Tôi hoàn toàn tôn trọng sử dụng Súp đẹp để lấy nội dung trả lại nhưng có thể không phải là gói lý tưởng để có được nội dung được hiển thị trên trang.
Tôi gặp sự cố tương tự để hiển thị nội dung hoặc nội dung hiển thị trong trình duyệt thông thường. Đặc biệt, tôi có nhiều trường hợp điển hình có thể làm việc với một ví dụ đơn giản dưới đây. Trong trường hợp này, thẻ không thể hiển thị được lồng trong thẻ kiểu và không hiển thị trong nhiều trình duyệt mà tôi đã chọn. Các biến thể khác tồn tại như xác định cài đặt thẻ lớp hiển thị thành không. Sau đó, sử dụng lớp này cho div.
<html>
<title> Title here</title>
<body>
lots of text here <p> <br>
<h1> even headings </h1>
<style type="text/css">
<div > this will not be visible </div>
</style>
</body>
</html>
Một giải pháp được đăng trên đây là:
html = Utilities.ReadFile('simple.html')
soup = BeautifulSoup.BeautifulSoup(html)
texts = soup.findAll(text=True)
visible_texts = filter(visible, texts)
print(visible_texts)
[u'\n', u'\n', u'\n\n lots of text here ', u' ', u'\n', u' even headings ', u'\n', u' this will not be visible ', u'\n', u'\n']
Giải pháp này chắc chắn có ứng dụng trong nhiều trường hợp và không được công việc khá tốt thường nhưng trong html được đăng trên đây nó vẫn giữ được văn bản mà không được trả lại. Sau khi tìm kiếm SO một vài giải pháp đã đưa ra tại đây BeautifulSoup get_text does not strip all tags and JavaScript và tại đây Rendered HTML to plain text using Python
Tôi đã thử cả hai giải pháp sau: html2text và nltk.clean_html và ngạc nhiên bởi kết quả tính thời gian nên họ đã đảm bảo câu trả lời cho hậu thế. Tất nhiên, tốc độ cao phụ thuộc vào nội dung của dữ liệu ...
Một câu trả lời ở đây từ @Helge là về việc sử dụng nltk của tất cả mọi thứ.
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.
betterHTML = html.decode(errors='ignore')
%timeit html2text.html2text(betterHTML)
%3.09 ms per loop
@jbochi Tôi đã thay thế dòng 3 của hiển thị() bằng re.match ('. * . *', string, re.DOTALL). Của bạn dường như chỉ hoạt động nếu toàn bộ nội dung * của văn bản là nhận xét, nhưng nếu có một không gian ban đầu hoặc dòng mới thì html 'ẩn' sẽ được trả về. Giải pháp của tôi là quá tích cực ở chỗ nó sẽ đánh dấu toàn bộ phần tử là vô hình, nhưng với mục đích của tôi thì tốt. – Trindaz
+1 cho 'soup.findAll (text = True)' không bao giờ biết về tính năng đó –
Đối với BS4 gần đây (ít nhất) bạn có thể nhận dạng các chú thích với 'isinstance (element, Comment)' thay vì kết hợp với regex. – tripleee