2012-11-12 24 views
26

Tôi đang cố chuyển đổi một đoạn văn bản HTML với BeautifulSoup. Dưới đây là một ví dụ:HTML được hiển thị thành văn bản thuần tuý sử dụng Python

<div> 
    <p> 
     Some text 
     <span>more text</span> 
     even more text 
    </p> 
    <ul> 
     <li>list item</li> 
     <li>yet another list item</li> 
    </ul> 
</div> 
<p>Some other text</p> 
<ul> 
    <li>list item</li> 
    <li>yet another list item</li> 
</ul> 

Tôi đã cố gắng làm điều gì đó như:

def parse_text(contents_string) 
    Newlines = re.compile(r'[\r\n]\s+') 
    bs = BeautifulSoup.BeautifulSoup(contents_string, convertEntities=BeautifulSoup.BeautifulSoup.HTML_ENTITIES) 
    txt = bs.getText('\n') 
    return Newlines.sub('\n', txt) 

... nhưng cách mà phần tử span của tôi luôn luôn là trên một dòng mới. Đây là một ví dụ đơn giản. Có cách nào để có được văn bản trong trang HTML như cách nó sẽ được hiển thị trong trình duyệt (không có quy tắc css cần thiết, chỉ cần các phần tử div, span, li, vv thông thường được hiển thị) bằng Python?

Trả lời

61

BeautifulSoup là một thư viện cào, vì vậy có thể đây không phải là lựa chọn tốt nhất để thực hiện hiển thị HTML. Nếu không cần thiết phải sử dụng BeautifulSoup, bạn nên xem html2text. Ví dụ:

import html2text 
html = open("foobar.html").read() 
print html2text.html2text(html) 

này kết quả đầu ra:

 
Some text more text even more text 

    * list item 
    * yet another list item 

Some other text 

    * list item 
    * yet another list item 
+1

Tôi có thể sử dụng html2text ở ngã ba với BeautifulSoup. Ví dụ tôi phân tích cú pháp đoạn html mà tôi quan tâm và sau đó nạp nó vào html2text bằng cách sử dụng pretify()? – btatarov

+1

Có, html2text có thể xử lý HTML theo khối bằng cách gọi 'HTML2Text.feed (chunk)' trên mỗi đoạn kế tiếp, và sau đó gọi 'HTML2Text.close()' để lấy kết quả văn bản (tương tự như ['HTMLParser.feed()' ] (http://docs.python.org/2/library/htmlparser.html#HTMLParser.HTMLParser.feed)). – del

+11

Câu trả lời này làm tôi vui và buồn cùng một lúc. RIP Aaron Swartz. –

2

tôi đã gặp phải cùng một vấn đề cố gắng để phân tích HTML rendered. Về cơ bản có vẻ như BS không phải là gói lý tưởng cho việc này. @Del cung cấp giải pháp html2text tuyệt vời.

Trên một câu hỏi SO khác nhau: BeautifulSoup get_text does not strip all tags and JavaScript @Helge được đề cập bằng cách sử dụng nltk. Thật không may nltk dường như ngừng phương pháp này.

Tôi đã thử cả hai html2text và nltk.clean_html và đã rất ngạc nhiên bởi kết quả tính thời gian, do đó họ nghĩ rằng họ đã đảm bảo một câu trả lời cho hậu thế. Tất nhiên, tốc độ rất phụ thuộc vào nội dung của dữ liệu ...

Trả lời từ @Helge (nltk).

import nltk 

%timeit nltk.clean_html(html) 
was returning 153 us per loop 

Nó hoạt động thực sự tốt để trả về chuỗi có html được hiển thị. Mô-đun nltk này nhanh hơn cả html2text, mặc dù có lẽ html2text mạnh mẽ hơn.

trả lời trên từ @del

betterHTML = html.decode(errors='ignore') 
%timeit html2text.html2text(betterHTML) 
%3.09 ms per loop 
+8

nltk.clean_html cung cấp 'NotImplementedError: Để xóa đánh dấu HTML, sử dụng hàm get_text() của BeautifulSoup' –

+2

Thậm chí nếu bạn có một phiên bản cũ của nltk, không sử dụng chức năng này. Nó nhanh vì nó xử lý html với regexes: https://github.com/nltk/nltk/blob/e86e83b1e2219fb099c4fbcff89a4ae07cd14868/nltk/util.py#L333-L353 – digenishjkl

+1

Tôi đã thêm một câu trả lời cho một câu hỏi liên quan cung cấp một cách để loại bỏ JavaScript qua BeautifulSoup: https://stackoverflow.com/a/47782943/2112722 –

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