2011-01-05 24 views
5

Câu hỏi của tôi hơi liên quan đến: Strip HTML from strings in PythonPython: dải html từ dữ liệu văn bản

Tôi đang tìm cách đơn giản để tách mã HTML khỏi văn bản. Ví dụ:

string = 'foo <SOME_VALID_HTML_TAG> something </SOME_VALID_HTML_TAG> bar' 
stripIt(string) 

Sau đó, sản lượng foo bar.

Có công cụ đơn giản nào để đạt được điều này trong Python không? Mã HTML có thể được lồng vào nhau.

+0

là "SOME_VALID_HTML_TAG" được đặt thành một thẻ cụ thể? Bạn có muốn xóa thẻ ngoài cùng không? – milkypostman

+0

Tôi nghĩ bạn có thể muốn sử dụng câu trả lời được chấp nhận về câu hỏi bạn đã liên kết - bạn đang làm gì khác nhau? – girasquid

+0

Trong câu hỏi liên quan, người dùng muốn stripIt (' foo') để mang lại foo, trong khi trong trường hợp của tôi, tôi muốn nó trả về ''. – Jernej

Trả lời

5
from BeautifulSoup import BeautifulSoup 

def removeTags(html, *tags): 
    soup = BeautifulSoup(html) 
    for tag in tags: 
     for tag in soup.findAll(tag): 
      tag.replaceWith("") 

    return soup 


testhtml = ''' 
<html> 
    <head> 
     <title>Page title</title> 
    </head> 
    <body>text here<p id="firstpara" align="center">This is paragraph <b>one</b>.</p> 
     <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p> 
    </body> 
</html>''' 

print removeTags(testhtml, 'b', 'p') 
2

Hãy thử giải pháp này:

from BeautifulSoup import BeautifulSoup 

def stripIt(string, tag): 
    soup = BeautifulSoup(string) 

    rmtags = soup.findAll(tag) 
    for t in rmtags: 
     string = string.replace(str(t), '') 
    return string 

string = 'foo <p> something </p> bar' 
print stripIt(string, 'p') 
>>> foo bar 

string = 'foo <a>bar</a> baz <a>quux</a>' 
print stripIt(string, 'a') 
>>> foo baz 

Chỉnh sửa: Điều này chỉ hoạt động trên hợp lệ lồng thẻ, vì vậy ví dụ:

string = 'blaz <div>baz <div>quux</div></div>' 
print stripIt(string, 'div') 
>>> blaz 

string = 'blaz <a>baz <a>quux</a></a>' 
print stripIt(string, 'a') 
>>> blaz <a>baz </a> 
0

Bạn có thể tận dụng lợi thế của HTMLParser bằng cách ghi đè các phương pháp phù hợp:

from HTMLParser import HTMLParser 

class HTMLStripper(HTMLParser): 

    text_parts = [] 
    depth = 0 

    def handle_data(self, data): 
     if self.depth == 0: 
      self.text_parts.append(data.strip()) 

    def handle_charref(self, ref): 
     data = unichr(int(ref)) 
     self.handle_data(data) 

    def handle_starttag(self, tag, attrs): 
     self.depth += 1 

    def handle_endtag(self, tag): 
     if self.depth > 0: 
      self.depth -= 1 

    def handle_entityref(self, ref): 
     try: 
      data = unichr(name2codepoint[ref]) 
      self.handle_data(data) 
     except KeyError: 
      pass 

    def get_stripped_text(self): 
     return ' '.join(self.text_parts) 

def strip_html_from_text(html): 
    parser = HTMLStripper() 
    parser.feed(html) 
    return parser.get_stripped_text() 

def main(): 
    import sys 
    html = sys.stdin.read() 
    text = strip_html_from_text(html) 
    print text 

if __name__ == '__main__': 
    main() 
6
import lxml.html 
import re 

def stripIt(s): 
    doc = lxml.html.fromstring(s) # parse html string 
    txt = doc.xpath('text()')  # ['foo ', ' bar'] 
    txt = ' '.join(txt)    # 'foo bar' 
    return re.sub('\s+', ' ', txt) # 'foo bar' 

s = 'foo <SOME_VALID_HTML_TAG> something </SOME_VALID_HTML_TAG> bar' 
stripIt(s) 

lợi nhuận

foo bar 
+0

tôi nghĩ rằng, lxml tốt hơn các mô-đun khác, điều này hoạt động như sự quyến rũ. –

+0

Điều này là tốt vì chỉ có một khoảng trống giữa kết quả 'foo' và 'bar', như OP được yêu cầu. Một số giải pháp khác để lại hai khoảng trắng. – mmmdreg

2

Nếu ai có vấn đề này và đã được làm việc với ngôn ngữ jinja khuôn mẫu: Bạn có thể sử dụng bộ lọc striptags trong các mẫu và các chức năng jinja2.filters.do_striptags() trong mã của bạn.

3

Bạn có thể sử dụng regex:

def stripIt(s): 
    txt = re.sub('<[^<]+?>.*?</[^<]+?>', '', s) # Remove html tags 
    return re.sub('\s+', ' ', txt)    # Normalize whitespace 

Tuy nhiên, tôi muốn giải pháp Hugh Bothwell như nó sẽ là mạnh hơn so với regex tinh khiết.

Các vấn đề liên quan