Mengekstraksi teks dari file HTML menggunakan Python

243

Saya ingin mengekstrak teks dari file HTML menggunakan Python. Saya ingin pada dasarnya output yang sama saya akan dapatkan jika saya menyalin teks dari browser dan menempelkannya ke notepad.

Saya ingin sesuatu yang lebih kuat daripada menggunakan ekspresi reguler yang mungkin gagal pada HTML yang dibentuk dengan buruk. Saya telah melihat banyak orang merekomendasikan Beautiful Soup, tetapi saya punya beberapa masalah dalam menggunakannya. Untuk satu, ia mengambil teks yang tidak diinginkan, seperti sumber JavaScript. Juga, itu tidak menafsirkan entitas HTML. Misalnya, saya harapkan & # 39; dalam sumber HTML untuk dikonversi menjadi tanda kutip dalam teks, sama seperti jika saya menempelkan konten browser ke notepad.

Pembaruan html2text terlihat menjanjikan. Ini menangani entitas HTML dengan benar dan mengabaikan JavaScript. Namun, itu tidak persis menghasilkan teks biasa; itu menghasilkan penurunan harga yang kemudian harus diubah menjadi teks biasa. Muncul tanpa contoh atau dokumentasi, tetapi kode terlihat bersih.


Pertanyaan-pertanyaan Terkait:

John D. Cook
sumber
Untuk beberapa saat, orang-orang tampaknya menemukan jawaban NLTK saya (sangat baru) sangat berguna sehingga, Anda mungkin ingin mempertimbangkan untuk mengubah jawaban yang diterima. Terima kasih!
Shatu
1
Saya tidak pernah menyangka akan menemukan pertanyaan yang diajukan oleh penulis blog favorit saya! The Endeavour!
Ryan G
1
@ Shatu Sekarang karena solusi Anda sudah tidak berlaku lagi, Anda mungkin ingin menghapus komentar Anda. Terima kasih! ;)
Sнаđошƒаӽ

Jawaban:

136

html2text adalah program Python yang melakukan pekerjaan dengan cukup baik.

RexE
sumber
5
bit itu gpl 3.0 yang berarti mungkin tidak kompatibel
frog32
138
Luar biasa! penulisnya adalah RIP Aaron Swartz.
Atul Arvind
2
Adakah yang menemukan alternatif untuk html2text karena GPL 3.0?
jontsai
1
GPL tidak seburuk yang diinginkan orang. Aaron tahu yang terbaik.
Steve K
2
Saya mencoba html2text dan nltk tetapi mereka tidak bekerja untuk saya. Saya akhirnya pergi dengan Beautiful Soup 4, yang bekerja dengan indah (tidak ada permainan kata-kata).
Ryan
149

Sepotong kode terbaik yang saya temukan untuk mengekstraksi teks tanpa mendapatkan javascript atau tidak menginginkan hal-hal:

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)

Anda hanya perlu menginstal BeautifulSoup sebelum:

pip install beautifulsoup4
PeYoTlL
sumber
2
Bagaimana jika kita ingin memilih beberapa baris, katakan saja, baris # 3?
hepidad
3
Skrip pembunuhan sedikit, penyelamat !!
Nanda
2
Setelah melalui banyak jawaban stackoverflow, saya merasa ini adalah pilihan terbaik bagi saya. Satu masalah yang saya temui adalah bahwa beberapa baris ditambahkan bersamaan dalam beberapa kasus. Saya dapat mengatasinya dengan menambahkan pemisah dalam fungsi get_text:text = soup.get_text(separator=' ')
Joswin KJ
5
Alih-alih soup.get_text()saya gunakan soup.body.get_text(), sehingga saya tidak mendapatkan teks dari <headelemen>, seperti judul.
Sjoerd
10
Untuk Python 3,from urllib.request import urlopen
Jacob Kalakal Joseph
99

CATATAN: NTLK tidak lagi mendukung clean_htmlfungsi

Jawaban asli di bawah, dan alternatif di bagian komentar.


Gunakan NLTK

Saya menghabiskan 4-5 jam untuk memperbaiki masalah dengan html2text. Untungnya saya bisa menemukan NLTK.
Ini bekerja secara ajaib.

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)
Shatu
sumber
8
terkadang itu sudah cukup :)
Sharmila
8
Saya ingin memilih ini ribuan kali. Saya terjebak di neraka regex, tapi lihat, sekarang saya melihat kebijaksanaan NLTK.
BenDundee
26
Rupanya, clean_html tidak didukung lagi: github.com/nltk/nltk/commit/…
alexanderlukanin13
5
mengimpor perpustakaan berat seperti nltk untuk tugas sederhana seperti itu akan terlalu banyak
richie
54
@ alexanderlukanin13 Dari sumber:raise NotImplementedError ("To remove HTML markup, use BeautifulSoup's get_text() function")
Chris Arena
54

Menemukan diri saya menghadapi masalah yang sama hari ini. Saya menulis parser HTML yang sangat sederhana untuk menghapus konten yang masuk dari semua markup, mengembalikan teks yang tersisa dengan hanya memformat minimum.

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()
xperroni
sumber
5
Ini tampaknya menjadi cara paling mudah untuk melakukan ini dengan Python (2.7) hanya menggunakan modul default. Yang benar-benar konyol, karena ini adalah hal yang biasa dibutuhkan dan tidak ada alasan mengapa tidak ada parser untuk ini dalam modul HTMLParser default.
Ingmar Hupp
2
Saya tidak berpikir akan mengubah karakter html menjadi unicode, kan? Misalnya, &amp;tidak akan dikonversi menjadi &, bukan?
speedplane
Untuk penggunaan Python 3from html.parser import HTMLParser
sebhaase
14

Ini adalah versi jawaban xperroni yang sedikit lebih lengkap. Ini melompati skrip dan bagian gaya dan menerjemahkan charrefs (misalnya, & # 39;) dan entitas HTML (misalnya, & amp;).

Ini juga termasuk konverter invers plain-text-to-html sepele.

"""
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)
bit4
sumber
Di get_text, '' .join harus '' .join. Seharusnya ada ruang kosong, jika tidak beberapa teks akan bergabung bersama.
Obinna Nnenanya
1
Selain itu, ini tidak akan menangkap SEMUA teks, kecuali Anda menyertakan tag wadah teks lain seperti H1, H2 ...., rentang, dll. Saya harus mengubahnya untuk mendapatkan cakupan yang lebih baik.
Obinna Nnenanya
11

Saya tahu sudah ada banyak jawaban, tetapi solusi paling elegan dan pythonic yang saya temukan dijelaskan, sebagian, di sini .

from bs4 import BeautifulSoup

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

Memperbarui

Berdasarkan komentar Fraser, berikut adalah solusi yang lebih elegan:

from bs4 import BeautifulSoup

clean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings)
Floyd
sumber
2
Untuk menghindari peringatan, tentukan pengurai untuk BeautifulSoup untuk menggunakan:text = ''.join(BeautifulSoup(some_html_string, "lxml").findAll(text=True))
Floyd
Anda dapat menggunakan generator stripped_strings untuk menghindari ruang putih yang berlebihan - yaituclean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings
Fraser
8

Anda dapat menggunakan metode html2text di perpustakaan stripogram juga.

from stripogram import html2text
text = html2text(your_html_string)

Untuk menginstal stripogram, jalankan sudo easy_install stripogram

GeekTantra
sumber
23
Modul ini, menurut halaman pypi-nya , sudah usang: "Kecuali Anda memiliki alasan historis untuk menggunakan paket ini, saya akan menyarankan untuk tidak melakukannya!"
intuited
7

Ada perpustakaan pola untuk penambangan data.

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

Anda bahkan dapat memutuskan tag mana yang akan disimpan:

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

PyParsing melakukan pekerjaan dengan baik. Wiki PyParsing terbunuh jadi di sini ada lokasi lain di mana ada contoh penggunaan PyParsing ( contoh tautan ). Salah satu alasan untuk menginvestasikan sedikit waktu dengan parsing adalah bahwa ia juga telah menulis sebuah panduan singkat O'Reilly Short Cut yang sangat terorganisir dengan baik yang juga murah.

Karena itu, saya banyak menggunakan BeautifulSoup dan tidak sulit untuk berurusan dengan masalah entitas, Anda dapat mengonversinya sebelum Anda menjalankan BeautifulSoup.

Semoga berhasil

PyNEwbie
sumber
1
Tautannya mati atau masam.
Yvette
4

Ini bukan solusi Python, tetapi itu akan mengkonversi teks yang akan dihasilkan Javascript menjadi teks, yang menurut saya penting (EG google.com). Tautan peramban (bukan Lynx) memiliki mesin Javascript, dan akan mengonversi sumber ke teks dengan opsi -dump.

Jadi Anda bisa melakukan sesuatu seperti:

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()
Andrew
sumber
4

Alih-alih modul HTMLParser, periksa htmllib. Ini memiliki antarmuka yang sama, tetapi lebih banyak bekerja untuk Anda. (Ini cukup kuno, jadi tidak banyak membantu dalam hal menyingkirkan javascript dan css. Anda bisa membuat kelas turunan, tetapi dan menambahkan metode dengan nama seperti start_script dan end_style (lihat dokumentasi python untuk perincian), tetapi sulit untuk melakukan ini secara andal untuk html cacat.) Bagaimanapun, ini adalah sesuatu yang sederhana yang mencetak teks biasa ke konsol

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)
Menandai
sumber
NB: HTMLError dan HTMLParserError harus membaca HTMLParseError. Ini berfungsi, tetapi melakukan pekerjaan yang buruk dalam mempertahankan jeda baris.
Dave Knight
4

Saya merekomendasikan Paket Python yang disebut Goose-extractor Goose akan mencoba mengekstrak informasi berikut:

Teks utama dari sebuah artikel Gambar utama dari artikel Setiap film Youtube / Vimeo yang disematkan dalam artikel Meta Deskripsi Meta tag

Lebih lanjut: https://pypi.python.org/pypi/goose-extractor/

Li Yingjun
sumber
4

jika Anda membutuhkan lebih banyak kecepatan dan kurang akurasi maka Anda bisa menggunakan lxml mentah.

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()
Anton Shelin
sumber
4

instal html2text menggunakan

pip instal html2text

kemudian,

>>> 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!
Pravitha V
sumber
4

Saya tahu sudah ada banyak jawaban di sini, tetapi saya pikir newspaper3k juga layak disebutkan. Baru-baru ini saya perlu menyelesaikan tugas serupa mengekstraksi teks dari artikel di web dan perpustakaan ini telah melakukan pekerjaan yang sangat baik untuk mencapai ini sejauh ini dalam pengujian saya. Ini mengabaikan teks yang ditemukan di item menu dan bilah samping serta semua JavaScript yang muncul pada halaman sesuai permintaan OP.

from newspaper import Article

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

Jika Anda sudah mengunduh file HTML, Anda dapat melakukan sesuatu seperti ini:

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

Bahkan memiliki beberapa fitur NLP untuk merangkum topik artikel:

article.nlp()
article.summary
spatel4140
sumber
3

Sup yang indah memang mengubah entitas html. Ini mungkin pilihan terbaik Anda mengingat HTML sering bermasalah dan diisi dengan masalah enkode unicode dan html. Ini adalah kode yang saya gunakan untuk mengonversi html ke teks mentah:

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 ""
speedplane
sumber
3

Pilihan lain adalah menjalankan html melalui browser web berbasis teks dan membuangnya. Misalnya (menggunakan Lynx):

lynx -dump html_to_convert.html > converted_html.txt

Ini dapat dilakukan dalam skrip python sebagai berikut:

import subprocess

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

Itu tidak akan memberi Anda persis hanya teks dari file HTML, tetapi tergantung pada kasus penggunaan Anda mungkin lebih disukai untuk output dari html2text.

John Lucas
sumber
3

Yang paling berhasil bagi saya adalah prasasti.

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)

Hasilnya sangat bagus

Vim
sumber
2

Solusi non-python lain: Libre Office:

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

Alasan saya lebih suka yang satu ini daripada alternatif lain adalah bahwa setiap paragraf HTML akan dikonversi menjadi satu baris teks (tidak ada jeda baris), yang adalah apa yang saya cari. Metode lain membutuhkan pasca pemrosesan. Lynx memang menghasilkan output yang bagus, tetapi tidak persis apa yang saya cari. Selain itu, Libre Office dapat digunakan untuk mengonversi dari semua jenis format ...

YakovK
sumber
2

Adakah yang sudah mencoba bleach.clean(html,tags=[],strip=True)dengan pemutih ? ini bekerja untuk saya.

rox
sumber
Tampaknya bekerja untuk saya juga, tetapi mereka tidak menyarankan menggunakannya untuk tujuan ini: "Fungsi ini adalah fungsi yang berfokus pada keamanan yang satu-satunya tujuan adalah untuk menghapus konten berbahaya dari string sehingga dapat ditampilkan sebagai konten di web halaman." -> bleach.readthedocs.io/en/latest/clean.html#bleach.clean
Loktopus
2

Saya mendapatkan hasil yang baik dengan Apache Tika . Tujuannya adalah ekstraksi metadata dan teks dari konten, karenanya parser yang mendasarinya disetel sesuai di luar kotak.

Tika dapat dijalankan sebagai server , mudah dijalankan / disebarkan dalam wadah Docker, dan dari sana dapat diakses melalui binding Python .

u-phoria
sumber
1

dengan cara yang sederhana

import re

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

kode ini menemukan semua bagian dari html_text dimulai dengan '<' dan diakhiri dengan '>' dan ganti semua yang ditemukan oleh string kosong

David Fraga
sumber
1

@ PeYoTIL's jawaban menggunakan BeautifulSoup dan menghilangkan gaya dan konten skrip tidak bekerja untuk saya. Saya mencoba menggunakan decomposebukan extracttetapi masih tidak berhasil. Jadi saya buat sendiri yang juga memformat teks menggunakan <p>tag dan mengganti <a>tag dengan tautan href. Juga mengatasi tautan di dalam teks. Tersedia di intisari ini dengan dokumen uji yang disematkan.

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
racitup
sumber
1
Terima kasih, jawaban ini diremehkan. Bagi kita yang ingin memiliki representasi teks yang bersih yang berperilaku lebih seperti browser (mengabaikan baris baru, dan hanya mempertimbangkan paragraf dan baris menjadi pertimbangan), BeautifulSoup get_texthanya tidak memotongnya.
jrial
@ jrial senang Anda menemukannya bermanfaat, juga terima kasih untuk kontribusinya. Untuk orang lain, intisari terkait telah ditingkatkan sedikit. Apa yang OP singgung adalah alat yang membuat html menjadi teks, seperti peramban berbasis teks seperti lynx. Itulah yang dicoba solusi ini. Yang dikontribusikan kebanyakan orang hanyalah ekstraktor teks.
racitup
1

Dalam Python 3.x Anda dapat melakukannya dengan cara yang sangat mudah dengan mengimpor paket 'imaplib' dan 'email'. Meskipun ini adalah posting yang lebih lama tetapi mungkin jawaban saya dapat membantu pendatang baru di posting ini.

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

Sekarang Anda dapat mencetak variabel tubuh dan itu akan berada dalam format plaintext :) Jika cukup baik untuk Anda maka akan lebih baik untuk memilihnya sebagai jawaban yang diterima.

Wahib Ul Haq
sumber
Ini tidak mengubah apa pun.
Antti Haapala
1
Ini menunjukkan kepada Anda cara mengekstrak text/plainbagian dari email jika orang lain meletakkannya di sana. Itu tidak melakukan apa pun untuk mengubah HTML menjadi plaintext, dan tidak melakukan apa pun yang berguna jika Anda mencoba untuk mengkonversi HTML dari, katakanlah, situs web.
tripleee
1

Anda hanya dapat mengekstrak teks dari HTML dengan 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)
Sai Gopi N
sumber
1

Sementara banyak orang yang disebutkan menggunakan regex untuk menghapus tag html, ada banyak kelemahan.

sebagai contoh:

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

Harus diuraikan ke:

Hello world
I love you

Berikut cuplikan yang saya buat, Anda dapat menyesuaikannya dengan kebutuhan spesifik Anda, dan itu berfungsi seperti pesona

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
Uri Goren
sumber
1

Contoh lain menggunakan BeautifulSoup4 di Python 2.7.9+

termasuk:

import urllib2
from bs4 import BeautifulSoup

Kode:

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'))

Dijelaskan:

Baca di data url sebagai html (menggunakan BeautifulSoup), hapus semua elemen skrip dan gaya, dan dapatkan juga teks menggunakan .get_text (). Pecah menjadi beberapa baris dan hapus spasi awal dan akhir pada masing-masing, kemudian pisahkan multi-headline menjadi satu baris setiap potongan = (phrase.strip () untuk baris dalam baris untuk frase dalam line.split ("")). Kemudian menggunakan text = '\ n'.join, drop baris kosong, akhirnya kembali sebagai utf-8 yang disetujui.

Catatan:

  • Beberapa sistem yang dijalankan ini akan gagal dengan https: // koneksi karena masalah SSL, Anda dapat mematikan verifikasi untuk memperbaiki masalah itu. Contoh perbaikan: http://blog.pengyifan.com/how-to-fix-python-ssl-certificate_verify_failed/

  • Python <2.7.9 mungkin memiliki masalah menjalankan ini

  • text.encode ('utf-8') dapat meninggalkan penyandian yang aneh, mungkin ingin mengembalikan str (teks) saja.

Mike Q
sumber
0

Berikut kode yang saya gunakan secara teratur.

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

Saya harap itu membantu.

troymyname00
sumber
0

Komentar penulis LibreOffice pantas karena aplikasi dapat menggunakan makro python. Tampaknya menawarkan banyak manfaat baik untuk menjawab pertanyaan ini dan melanjutkan basis makro LibreOffice. Jika resolusi ini adalah implementasi satu kali, alih-alih digunakan sebagai bagian dari program produksi yang lebih besar, membuka HTML dalam penulis dan menyimpan halaman sebagai teks akan menyelesaikan masalah yang dibahas di sini.

1of7
sumber
0

Perl way (maaf Bu, aku tidak akan pernah melakukannya dalam produksi).

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
brunql
sumber
Ini adalah praktik buruk karena berbagai alasan, misalnya&nbsp;
Uri Goren
Iya! Itu benar! Jangan lakukan di sana!
brunql