Trích xuất văn bản từ tệp HTML bằng Python


243

Tôi muốn trích xuất văn bản từ tệp HTML bằng Python. Tôi muốn về cơ bản cùng một đầu ra tôi sẽ nhận được nếu tôi sao chép văn bản từ trình duyệt và dán nó vào notepad.

Tôi muốn một cái gì đó mạnh mẽ hơn là sử dụng các biểu thức thông thường có thể thất bại trên HTML được định dạng kém. Tôi đã thấy nhiều người giới thiệu Beautiful Soup, nhưng tôi đã gặp một vài vấn đề khi sử dụng nó. Đối với một, nó đã chọn văn bản không mong muốn, chẳng hạn như nguồn JavaScript. Ngoài ra, nó không giải thích các thực thể HTML. Ví dụ: tôi mong đợi & # 39; trong nguồn HTML sẽ được chuyển đổi thành dấu nháy đơn trong văn bản, giống như tôi đã dán nội dung trình duyệt vào notepad.

Cập nhật có html2text vẻ hứa hẹn. Nó xử lý các thực thể HTML chính xác và bỏ qua JavaScript. Tuy nhiên, nó không chính xác tạo ra văn bản đơn giản; nó tạo ra markdown mà sau đó sẽ phải được chuyển thành văn bản thuần túy. Nó không có ví dụ hoặc tài liệu, nhưng mã có vẻ sạch sẽ.


Câu hỏi liên quan:


Trong một thời gian dài, mọi người dường như tìm thấy câu trả lời NLTK của tôi (khá gần đây) là cực kỳ hữu ích vì vậy, bạn có thể muốn xem xét thay đổi câu trả lời được chấp nhận. Cảm ơn!
Shatu

1
Tôi chưa bao giờ nghĩ rằng tôi bắt gặp một câu hỏi của tác giả của blog yêu thích của tôi! Nỗ lực hết mình!
Ryan G

1
@Shatu Bây giờ giải pháp của bạn đã không còn hiệu lực, bạn có thể muốn xóa nhận xét của mình. Cảm ơn! ;)
Sнаđошƒаӽ

Câu trả lời:


136

html2text là một chương trình Python thực hiện công việc này khá tốt.


5
bit gpl 3.0 có nghĩa là nó có thể không tương thích
ếch32

138
Kinh ngạc! tác giả của nó là RIP Aaron Swartz.
Atul Arvind

2
Có ai tìm thấy bất kỳ sự thay thế nào cho html2text vì GPL 3.0 không?
jontsai

1
GPL không tệ như mọi người muốn. Aaron biết rõ nhất.
Steve K

2
Tôi đã thử cả html2text và nltk nhưng chúng không hoạt động với tôi. Tôi đã kết thúc với Beautiful Soup 4, hoạt động rất đẹp (không có ý định chơi chữ).
Ryan

149

Đoạn mã tốt nhất tôi tìm thấy để trích xuất văn bản mà không nhận javascript hoặc không muốn những thứ:

import urllib
from bs4 import BeautifulSoup

url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"
html = urllib.urlopen(url).read()
soup = BeautifulSoup(html)

# kill all script and style elements
for script in soup(["script", "style"]):
    script.extract()    # rip it out

# get text
text = soup.get_text()

# break into lines and remove leading and trailing space on each
lines = (line.strip() for line in text.splitlines())
# break multi-headlines into a line each
chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
# drop blank lines
text = '\n'.join(chunk for chunk in chunks if chunk)

print(text)

Bạn chỉ cần cài đặt BeautifulSoup trước:

pip install beautifulsoup4

2
Làm thế nào nếu chúng ta muốn chọn một số dòng, chỉ cần nói, dòng # 3?
hepidad

3
Các kịch bản giết chóc bit, vị cứu tinh !!
Nanda

2
Sau khi trải qua rất nhiều câu trả lời stackoverflow, tôi cảm thấy như đây là lựa chọn tốt nhất cho tôi. Một vấn đề tôi gặp phải là các dòng được thêm vào với nhau trong một số trường hợp. Tôi đã có thể khắc phục bằng cách thêm một dấu phân cách trong hàm get lòng:text = soup.get_text(separator=' ')
Joswin KJ

5
Thay vì soup.get_text()tôi đã sử dụng soup.body.get_text(), do đó tôi không nhận được bất kỳ văn bản nào từ <headphần tử>, chẳng hạn như tiêu đề.
Sjoerd

10
Đối với Python 3,from urllib.request import urlopen
Jacob Kalakal Joseph

99

LƯU Ý: NTLK không còn hỗ trợ clean_htmlchức năng

Câu trả lời gốc dưới đây, và một thay thế trong phần ý kiến.


Sử dụng NLTK

Tôi đã lãng phí 4-5 giờ để khắc phục các sự cố với html2text. May mắn thay tôi có thể gặp NLTK.
Nó hoạt động kỳ diệu.

import nltk   
from urllib import urlopen

url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"    
html = urlopen(url).read()    
raw = nltk.clean_html(html)  
print(raw)

8
đôi khi thế là đủ :)
Sharmila

8
Tôi muốn bỏ phiếu này một ngàn lần. Tôi bị mắc kẹt trong địa ngục regex, nhưng lo, bây giờ tôi thấy sự khôn ngoan của NLTK.
BenDundee

26
Rõ ràng, Clean_html không còn được hỗ trợ nữa: github.com/nltk/nltk/commit/ mẹo
alexanderlukanin13

5
nhập một thư viện nặng như nltk cho một nhiệm vụ đơn giản như vậy sẽ là quá nhiều
richie

54
@ alexanderlukanin13 Từ nguồn:raise NotImplementedError ("To remove HTML markup, use BeautifulSoup's get_text() function")
Chris Arena

54

Tìm thấy chính mình phải đối mặt với cùng một vấn đề ngày hôm nay. Tôi đã viết một trình phân tích cú pháp HTML rất đơn giản để loại bỏ nội dung đến của tất cả các đánh dấu, trả lại văn bản còn lại chỉ với định dạng tối thiểu.

from HTMLParser import HTMLParser
from re import sub
from sys import stderr
from traceback import print_exc

class _DeHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.__text = []

    def handle_data(self, data):
        text = data.strip()
        if len(text) > 0:
            text = sub('[ \t\r\n]+', ' ', text)
            self.__text.append(text + ' ')

    def handle_starttag(self, tag, attrs):
        if tag == 'p':
            self.__text.append('\n\n')
        elif tag == 'br':
            self.__text.append('\n')

    def handle_startendtag(self, tag, attrs):
        if tag == 'br':
            self.__text.append('\n\n')

    def text(self):
        return ''.join(self.__text).strip()


def dehtml(text):
    try:
        parser = _DeHTMLParser()
        parser.feed(text)
        parser.close()
        return parser.text()
    except:
        print_exc(file=stderr)
        return text


def main():
    text = r'''
        <html>
            <body>
                <b>Project:</b> DeHTML<br>
                <b>Description</b>:<br>
                This small script is intended to allow conversion from HTML markup to 
                plain text.
            </body>
        </html>
    '''
    print(dehtml(text))


if __name__ == '__main__':
    main()

5
Đây dường như là cách đơn giản nhất để thực hiện việc này trong Python (2.7) chỉ sử dụng các mô-đun mặc định. Điều này thực sự ngớ ngẩn, vì đây là một điều rất cần thiết và không có lý do chính đáng tại sao không có trình phân tích cú pháp cho điều này trong mô-đun HTMLParser mặc định.
Ingmar Hupp

2
Tôi không nghĩ sẽ chuyển đổi các ký tự html thành unicode, phải không? Ví dụ, &amp;sẽ không được chuyển đổi thành &, phải không?
siêu tốc

Đối với Python 3 sử dụngfrom html.parser import HTMLParser
sebhaase

14

Đây là một phiên bản của câu trả lời của xperroni hoàn chỉnh hơn một chút. Nó bỏ qua các phần tập lệnh và kiểu và dịch các charrefs (ví dụ: & # 39;) và các thực thể HTML (ví dụ: & amp;).

Nó cũng bao gồm một trình chuyển đổi nghịch đảo văn bản thành văn bản đơn giản tầm thường.

"""
HTML <-> text conversions.
"""
from HTMLParser import HTMLParser, HTMLParseError
from htmlentitydefs import name2codepoint
import re

class _HTMLToText(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self._buf = []
        self.hide_output = False

    def handle_starttag(self, tag, attrs):
        if tag in ('p', 'br') and not self.hide_output:
            self._buf.append('\n')
        elif tag in ('script', 'style'):
            self.hide_output = True

    def handle_startendtag(self, tag, attrs):
        if tag == 'br':
            self._buf.append('\n')

    def handle_endtag(self, tag):
        if tag == 'p':
            self._buf.append('\n')
        elif tag in ('script', 'style'):
            self.hide_output = False

    def handle_data(self, text):
        if text and not self.hide_output:
            self._buf.append(re.sub(r'\s+', ' ', text))

    def handle_entityref(self, name):
        if name in name2codepoint and not self.hide_output:
            c = unichr(name2codepoint[name])
            self._buf.append(c)

    def handle_charref(self, name):
        if not self.hide_output:
            n = int(name[1:], 16) if name.startswith('x') else int(name)
            self._buf.append(unichr(n))

    def get_text(self):
        return re.sub(r' +', ' ', ''.join(self._buf))

def html_to_text(html):
    """
    Given a piece of HTML, return the plain text it contains.
    This handles entities and char refs, but not javascript and stylesheets.
    """
    parser = _HTMLToText()
    try:
        parser.feed(html)
        parser.close()
    except HTMLParseError:
        pass
    return parser.get_text()

def text_to_html(text):
    """
    Convert the given text to html, wrapping what looks like URLs with <a> tags,
    converting newlines to <br> tags and converting confusing chars into html
    entities.
    """
    def f(mo):
        t = mo.group()
        if len(t) == 1:
            return {'&':'&amp;', "'":'&#39;', '"':'&quot;', '<':'&lt;', '>':'&gt;'}.get(t)
        return '<a href="%s">%s</a>' % (t, t)
    return re.sub(r'https?://[^] ()"\';]+|[&\'"<>]', f, text)


Trong get lòng, '' .join nên là '' .join. Cần có một khoảng trống, nếu không một số văn bản sẽ kết hợp với nhau.
Obinna Nnenanya

1
Ngoài ra, điều này sẽ không bắt được TẤT CẢ các văn bản, ngoại trừ bạn bao gồm các thẻ chứa văn bản khác như H1, H2 ...., span, v.v. Tôi phải điều chỉnh nó để có độ bao phủ tốt hơn.
Obinna Nnenanya

11

Tôi biết đã có rất nhiều câu trả lời, nhưng giải pháp tao nhãpythonic nhất mà tôi đã tìm thấy được mô tả, một phần, ở đây .

from bs4 import BeautifulSoup

text = ''.join(BeautifulSoup(some_html_string, "html.parser").findAll(text=True))

Cập nhật

Dựa trên nhận xét của Fraser, đây là giải pháp thanh lịch hơn:

from bs4 import BeautifulSoup

clean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings)

2
Để tránh cảnh báo, chỉ định trình phân tích cú pháp cho BeautifulSoup để sử dụng:text = ''.join(BeautifulSoup(some_html_string, "lxml").findAll(text=True))
Floyd

Bạn có thể sử dụng trình tạo dải tước_strings để tránh khoảng trắng quá mức - tức làclean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings
Fraser

8

Bạn cũng có thể sử dụng phương thức html2text trong thư viện biểu đồ.

from stripogram import html2text
text = html2text(your_html_string)

Để cài đặt biểu đồ, hãy chạy sudo easy_install


23
Mô-đun này, theo trang pypi của nó , không được chấp nhận: "Trừ khi bạn có một số lý do lịch sử để sử dụng gói này, tôi khuyên bạn nên chống lại nó!"
trực giác

7

Có thư viện mẫu để khai thác dữ liệu.

http://www.clips.ua.ac.be/pages/potype-web

Bạn thậm chí có thể quyết định những thẻ cần giữ:

s = URL('http://www.clips.ua.ac.be').download()
s = plaintext(s, keep={'h1':[], 'h2':[], 'strong':[], 'a':['href']})
print s

6

PyParsing làm một công việc tuyệt vời. Wiki PyParsing đã bị giết, vì vậy đây là một địa điểm khác có các ví dụ về việc sử dụng PyParsing ( liên kết ví dụ ). Một lý do để đầu tư một chút thời gian với pyparsing là ông cũng đã viết một hướng dẫn sử dụng O'Reilly Short Cut được tổ chức rất ngắn gọn mà cũng không tốn kém.

Phải nói rằng, tôi sử dụng BeautifulSoup rất nhiều và không khó để xử lý các vấn đề về thực thể, bạn có thể chuyển đổi chúng trước khi chạy BeautifulSoup.

Chúc may mắn


1
Các liên kết là chết hoặc chua.
Yvette

4

Đây không chính xác là một giải pháp Python, nhưng nó sẽ chuyển đổi văn bản Javascript sẽ tạo thành văn bản, điều mà tôi nghĩ là quan trọng (EG google.com). Liên kết trình duyệt (không phải Lynx) có công cụ Javascript và sẽ chuyển đổi nguồn thành văn bản với tùy chọn -dump.

Vì vậy, bạn có thể làm một cái gì đó như:

fname = os.tmpnam()
fname.write(html_source)
proc = subprocess.Popen(['links', '-dump', fname], 
                        stdout=subprocess.PIPE,
                        stderr=open('/dev/null','w'))
text = proc.stdout.read()

4

Thay vì mô-đun HTMLParser, hãy kiểm tra htmllib. Nó có một giao diện tương tự, nhưng làm nhiều việc hơn cho bạn. (Nó khá cổ xưa, vì vậy nó không giúp ích nhiều trong việc loại bỏ javascript và css. Bạn có thể tạo một lớp dẫn xuất, nhưng thêm các phương thức với các tên như start_script và end_style (xem chi tiết tài liệu python), nhưng thật khó để làm điều này một cách đáng tin cậy cho html không đúng định dạng.) Dù sao, đây là một cái gì đó đơn giản mà in văn bản đơn giản lên bàn điều khiển

from htmllib import HTMLParser, HTMLParseError
from formatter import AbstractFormatter, DumbWriter
p = HTMLParser(AbstractFormatter(DumbWriter()))
try: p.feed('hello<br>there'); p.close() #calling close is not usually needed, but let's play it safe
except HTMLParseError: print ':(' #the html is badly malformed (or you found a bug)

NB: HTMLError và HTMLParserError đều nên đọc HTMLPudeError. Điều này hoạt động, nhưng làm một công việc tồi tệ của việc duy trì ngắt dòng.
Dave Knight

4

Tôi khuyên bạn nên sử dụng Gói Python có tên là ngỗng trích xuất Goose sẽ cố gắng trích xuất thông tin sau:

Văn bản chính của một bài viết Hình ảnh chính của bài viết Bất kỳ phim Youtube / Vimeo nào được nhúng trong bài viết Meta Mô tả Thẻ meta

Thêm: https://pypi.python.org/pypi/goose-extractor/


4

Nếu bạn cần tốc độ nhanh hơn và độ chính xác thấp hơn thì bạn có thể sử dụng lxml thô.

import lxml.html as lh
from lxml.html.clean import clean_html

def lxml_to_text(html):
    doc = lh.fromstring(html)
    doc = clean_html(doc)
    return doc.text_content()

4

cài đặt html2text bằng

Pip cài đặt html2text

sau đó,

>>> import html2text
>>>
>>> h = html2text.HTML2Text()
>>> # Ignore converting links from HTML
>>> h.ignore_links = True
>>> print h.handle("<p>Hello, <a href='http://earth.google.com/'>world</a>!")
Hello, world!

4

Tôi biết đã có rất nhiều câu trả lời ở đây rồi nhưng tôi nghĩ báo3k cũng xứng đáng được đề cập. Gần đây tôi cần hoàn thành một nhiệm vụ tương tự là trích xuất văn bản từ các bài viết trên web và thư viện này đã thực hiện một công việc tuyệt vời để đạt được điều này cho đến nay trong các thử nghiệm của tôi. Nó bỏ qua văn bản tìm thấy trong các mục menu và thanh bên cũng như bất kỳ JavaScript nào xuất hiện trên trang như các yêu cầu OP.

from newspaper import Article

article = Article(url)
article.download()
article.parse()
article.text

Nếu bạn đã tải xuống các tệp HTML, bạn có thể làm một cái gì đó như thế này:

article = Article('')
article.set_html(html)
article.parse()
article.text

Nó thậm chí còn có một vài tính năng NLP để tóm tắt các chủ đề của bài viết:

article.nlp()
article.summary

3

Súp đẹp không chuyển đổi các thực thể html. Có lẽ đặt cược tốt nhất của bạn khi xem xét HTML thường là lỗi và chứa đầy các vấn đề mã hóa unicode và html. Đây là mã tôi sử dụng để chuyển đổi html thành văn bản thô:

import BeautifulSoup
def getsoup(data, to_unicode=False):
    data = data.replace("&nbsp;", " ")
    # Fixes for bad markup I've seen in the wild.  Remove if not applicable.
    masssage_bad_comments = [
        (re.compile('<!-([^-])'), lambda match: '<!--' + match.group(1)),
        (re.compile('<!WWWAnswer T[=\w\d\s]*>'), lambda match: '<!--' + match.group(0) + '-->'),
    ]
    myNewMassage = copy.copy(BeautifulSoup.BeautifulSoup.MARKUP_MASSAGE)
    myNewMassage.extend(masssage_bad_comments)
    return BeautifulSoup.BeautifulSoup(data, markupMassage=myNewMassage,
        convertEntities=BeautifulSoup.BeautifulSoup.ALL_ENTITIES 
                    if to_unicode else None)

remove_html = lambda c: getsoup(c, to_unicode=True).getText(separator=u' ') if c else ""

3

Một tùy chọn khác là chạy html thông qua trình duyệt web dựa trên văn bản và kết xuất nó. Ví dụ: (sử dụng Lynx):

lynx -dump html_to_convert.html > converted_html.txt

Điều này có thể được thực hiện trong một kịch bản python như sau:

import subprocess

with open('converted_html.txt', 'w') as outputFile:
    subprocess.call(['lynx', '-dump', 'html_to_convert.html'], stdout=testFile)

Nó sẽ không cung cấp cho bạn chính xác văn bản từ tệp HTML, nhưng tùy thuộc vào trường hợp sử dụng của bạn, nó có thể thích hợp hơn với đầu ra của html2text.


3

Làm việc tốt nhất cho tôi là chữ khắc.

https://github.com/weblyzard/inscriptis

import urllib.request
from inscriptis import get_text

url = "http://www.informationscience.ch"
html = urllib.request.urlopen(url).read().decode('utf-8')

text = get_text(html)
print(text)

Kết quả rất tốt


2

Một giải pháp không phải trăn: Văn phòng Libre:

soffice --headless --invisible --convert-to txt input1.html

Lý do tôi thích cái này hơn các lựa chọn thay thế khác là vì mỗi đoạn HTML được chuyển đổi thành một dòng văn bản duy nhất (không ngắt dòng), đó là điều tôi đang tìm kiếm. Các phương pháp khác yêu cầu xử lý hậu kỳ. Lynx không tạo ra đầu ra tốt, nhưng không chính xác những gì tôi đang tìm kiếm. Ngoài ra, Libre Office có thể được sử dụng để chuyển đổi từ tất cả các định dạng ...


2

Bất cứ ai đã thử bleach.clean(html,tags=[],strip=True)với thuốc tẩy ? nó làm việc cho tôi


Có vẻ như tôi cũng làm việc với họ, nhưng họ không khuyên bạn nên sử dụng nó cho mục đích này: "Chức năng này là một chức năng tập trung vào bảo mật với mục đích duy nhất là xóa nội dung độc hại khỏi chuỗi để nó có thể được hiển thị dưới dạng nội dung trong web trang." -> Bleach.readthedocs.io/en/latest/clean.html#bleach.clean
Loktopus

2

Tôi đã có kết quả tốt với Apache Tika . Mục đích của nó là trích xuất siêu dữ liệu và văn bản từ nội dung, do đó trình phân tích cú pháp cơ bản được điều chỉnh tương ứng ra khỏi hộp.

Tika có thể được chạy như một máy chủ , không quan trọng để chạy / triển khai trong bộ chứa Docker và từ đó có thể được truy cập thông qua các ràng buộc Python .


1

một cách đơn giản

import re

html_text = open('html_file.html').read()
text_filtered = re.sub(r'<(.*?)>', '', html_text)

mã này tìm thấy tất cả các phần của htmlSphere bắt đầu bằng '<' và kết thúc bằng '>' và thay thế tất cả được tìm thấy bởi một chuỗi rỗng


1

Câu trả lời của @ PeYoTIL bằng cách sử dụng BeautifulSoup và loại bỏ phong cách và nội dung kịch bản không phù hợp với tôi. Tôi đã thử sử dụng nó decomposethay vì extractnhưng nó vẫn không hoạt động. Vì vậy, tôi đã tạo riêng cho mình định dạng văn bản bằng cách sử dụng các <p>thẻ và thay thế <a>các thẻ bằng liên kết href. Cũng đối phó với các liên kết bên trong văn bản. Có sẵn tại ý chính này với một tài liệu thử nghiệm được nhúng.

from bs4 import BeautifulSoup, NavigableString

def html_to_text(html):
    "Creates a formatted text email message as a string from a rendered html template (page)"
    soup = BeautifulSoup(html, 'html.parser')
    # Ignore anything in head
    body, text = soup.body, []
    for element in body.descendants:
        # We use type and not isinstance since comments, cdata, etc are subclasses that we don't want
        if type(element) == NavigableString:
            # We use the assumption that other tags can't be inside a script or style
            if element.parent.name in ('script', 'style'):
                continue

            # remove any multiple and leading/trailing whitespace
            string = ' '.join(element.string.split())
            if string:
                if element.parent.name == 'a':
                    a_tag = element.parent
                    # replace link text with the link
                    string = a_tag['href']
                    # concatenate with any non-empty immediately previous string
                    if (    type(a_tag.previous_sibling) == NavigableString and
                            a_tag.previous_sibling.string.strip() ):
                        text[-1] = text[-1] + ' ' + string
                        continue
                elif element.previous_sibling and element.previous_sibling.name == 'a':
                    text[-1] = text[-1] + ' ' + string
                    continue
                elif element.parent.name == 'p':
                    # Add extra paragraph formatting newline
                    string = '\n' + string
                text += [string]
    doc = '\n'.join(text)
    return doc

1
Cảm ơn, câu trả lời này được đánh giá thấp. Đối với những người trong chúng ta muốn có một bản trình bày văn bản rõ ràng hoạt động giống như một trình duyệt (bỏ qua các dòng mới và chỉ xem xét các đoạn văn và ngắt dòng), BeautifulSoup get_textđơn giản là không cắt nó.
18:03

@jrial rất vui vì bạn thấy nó hữu ích, cũng cảm ơn vì đã đóng góp. Đối với bất cứ ai khác, ý chính được liên kết đã được tăng cường khá nhiều. Những gì OP dường như ám chỉ là một công cụ kết xuất html thành văn bản, giống như một trình duyệt dựa trên văn bản như lynx. Đó là những gì giải pháp này cố gắng. Những gì hầu hết mọi người đang đóng góp chỉ là trích xuất văn bản.
racitup

1

Trong Python 3.x bạn có thể làm điều đó một cách rất dễ dàng bằng cách nhập các gói 'imaplib' và 'email'. Mặc dù đây là một bài viết cũ hơn nhưng có lẽ câu trả lời của tôi có thể giúp những người mới đến bài đăng này.

status, data = self.imap.fetch(num, '(RFC822)')
email_msg = email.message_from_bytes(data[0][1]) 
#email.message_from_string(data[0][1])

#If message is multi part we only want the text version of the body, this walks the message and gets the body.

if email_msg.is_multipart():
    for part in email_msg.walk():       
        if part.get_content_type() == "text/plain":
            body = part.get_payload(decode=True) #to control automatic email-style MIME decoding (e.g., Base64, uuencode, quoted-printable)
            body = body.decode()
        elif part.get_content_type() == "text/html":
            continue

Bây giờ bạn có thể in biến cơ thể và nó sẽ ở định dạng văn bản gốc :) Nếu nó đủ tốt cho bạn thì thật tuyệt khi chọn nó làm câu trả lời được chấp nhận.


Điều này không chuyển đổi bất cứ điều gì.
Antti Haapala

1
Điều này chỉ cho bạn cách trích xuất một text/plainphần từ email nếu có người khác đặt nó ở đó. Nó không làm bất cứ điều gì để chuyển đổi HTML thành văn bản gốc và không có gì hữu ích từ xa nếu bạn đang cố gắng chuyển đổi HTML từ một trang web.
tripleee

1

bạn chỉ có thể trích xuất văn bản từ HTML bằng BeautifulSoup

url = "https://www.geeksforgeeks.org/extracting-email-addresses-using-regular-expressions-python/"
con = urlopen(url).read()
soup = BeautifulSoup(con,'html.parser')
texts = soup.get_text()
print(texts)

1

Trong khi rất nhiều người được đề cập bằng cách sử dụng regex để tước thẻ html, có rất nhiều nhược điểm.

ví dụ:

<p>hello&nbsp;world</p>I love you

Nên được phân tích cú pháp để:

Hello world
I love you

Đây là một đoạn tôi đã nghĩ ra, bạn có thể đưa nó vào nhu cầu cụ thể của bạn và nó hoạt động như một bùa mê

import re
import html
def html2text(htm):
    ret = html.unescape(htm)
    ret = ret.translate({
        8209: ord('-'),
        8220: ord('"'),
        8221: ord('"'),
        160: ord(' '),
    })
    ret = re.sub(r"\s", " ", ret, flags = re.MULTILINE)
    ret = re.sub("<br>|<br />|</p>|</div>|</h\d>", "\n", ret, flags = re.IGNORECASE)
    ret = re.sub('<.*?>', ' ', ret, flags=re.DOTALL)
    ret = re.sub(r"  +", " ", ret)
    return ret

1

Một ví dụ khác sử dụng BeautifulSoup4 trong Python 2.7.9+

bao gồm:

import urllib2
from bs4 import BeautifulSoup

Mã số:

def read_website_to_text(url):
    page = urllib2.urlopen(url)
    soup = BeautifulSoup(page, 'html.parser')
    for script in soup(["script", "style"]):
        script.extract() 
    text = soup.get_text()
    lines = (line.strip() for line in text.splitlines())
    chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
    text = '\n'.join(chunk for chunk in chunks if chunk)
    return str(text.encode('utf-8'))

Giải thích:

Đọc trong dữ liệu url dưới dạng html (sử dụng BeautifulSoup), xóa tất cả các thành phần tập lệnh và kiểu và cũng chỉ nhận văn bản bằng cách sử dụng .get lòng (). Chia thành các dòng và xóa không gian hàng đầu và dấu trên mỗi dòng, sau đó chia nhiều dòng tiêu đề thành một dòng mỗi đoạn = (cụm từ.strip () cho dòng trong dòng cho cụm từ trong dòng.split ("")). Sau đó, sử dụng text = '\ n'.join, bỏ các dòng trống, cuối cùng trở lại dưới dạng utf-8 bị xử phạt.

Ghi chú:

  • Một số hệ thống được chạy trên sẽ thất bại với các kết nối https: // do sự cố SSL, bạn có thể tắt xác minh để khắc phục sự cố đó. Sửa ví dụ: http://blog.pengyifan.com/how-to-fix-python-ssl-cert ve_verify_fails /

  • Python <2.7.9 có thể có một số vấn đề khi chạy này

  • text.encode ('utf-8') có thể để lại mã hóa lạ, có thể chỉ muốn trả về str (văn bản) thay thế.


0

Đây là mã tôi sử dụng thường xuyên.

from bs4 import BeautifulSoup
import urllib.request


def processText(webpage):

    # EMPTY LIST TO STORE PROCESSED TEXT
    proc_text = []

    try:
        news_open = urllib.request.urlopen(webpage.group())
        news_soup = BeautifulSoup(news_open, "lxml")
        news_para = news_soup.find_all("p", text = True)

        for item in news_para:
            # SPLIT WORDS, JOIN WORDS TO REMOVE EXTRA SPACES
            para_text = (' ').join((item.text).split())

            # COMBINE LINES/PARAGRAPHS INTO A LIST
            proc_text.append(para_text)

    except urllib.error.HTTPError:
        pass

    return proc_text

Tôi hy vọng điều đó sẽ giúp.


0

Nhận xét của người viết LibreScript có giá trị vì ứng dụng có thể sử dụng macro python. Nó dường như cung cấp nhiều lợi ích cho cả việc trả lời câu hỏi này và tiếp tục cơ sở vĩ mô của LibreOffice. Nếu độ phân giải này là triển khai một lần, thay vì được sử dụng như một phần của chương trình sản xuất lớn hơn, việc mở HTML bằng văn bản và lưu trang dưới dạng văn bản dường như sẽ giải quyết các vấn đề được thảo luận ở đây.


0

Perl way (xin lỗi mẹ, tôi sẽ không bao giờ làm điều đó trong sản xuất).

import re

def html2text(html):
    res = re.sub('<.*?>', ' ', html, flags=re.DOTALL | re.MULTILINE)
    res = re.sub('\n+', '\n', res)
    res = re.sub('\r+', '', res)
    res = re.sub('[\t ]+', ' ', res)
    res = re.sub('\t+', '\t', res)
    res = re.sub('(\n )+', '\n ', res)
    return res

Đây là thực tế tồi vì rất nhiều lý do, ví dụ&nbsp;
Uri Goren

Đúng! Đúng rồi! Đừng làm điều đó nữa!
brunql
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.