Python kullanarak HTML dosyasından metin çıkarma


243

Python kullanarak bir HTML dosyasındaki metni ayıklamak istiyorum. Metni bir tarayıcıdan kopyalayıp not defterine yapıştırırsam alacağım aslında aynı çıktıyı istiyorum.

Kötü biçimlendirilmiş HTML'de başarısız olabilecek normal ifadeleri kullanmaktan daha sağlam bir şey istiyorum. Birçok kişinin Güzel Çorba tavsiye ettiğini gördüm, ancak kullanırken birkaç sorun yaşadım. Birincisi, JavaScript kaynağı gibi istenmeyen metinler aldı. Ayrıca, HTML varlıklarını yorumlamadı. Örneğin, & # 39; HTML kaynağında, tıpkı tarayıcı içeriğini not defterine yapıştırmışım gibi, metinde kesme işaretine dönüştürülecek.

Güncelleme html2text umut verici görünüyor. HTML varlıklarını doğru şekilde işler ve JavaScript'i yok sayar. Ancak, tam olarak düz metin üretmez; daha sonra düz metne dönüştürülmesi gereken işaretleme oluşturur. Hiçbir örnek veya belge ile birlikte gelir, ancak kod temiz görünüyor.


İlgili sorular:


Bir süredir insanlar NLTK cevabımı (oldukça yeni) son derece yararlı buluyor gibi görünüyor, bu nedenle kabul edilen cevabı değiştirmeyi düşünebilirsiniz. Teşekkürler!
Shatu

1
Favori blogumun yazarı tarafından sorulan bir soruya rastlayacağımı hiç düşünmemiştim! Çaba!
Ryan G

1
@Shatu Artık çözümünüz artık geçerli olmadığına göre, yorumunuzu silmek isteyebilirsiniz. Teşekkürler! ;)
Sнаđошƒаӽ

Yanıtlar:


136

html2text , bu konuda oldukça iyi bir iş çıkaran bir Python programıdır.


5
bit bu gpl 3.0 yani uyumsuz olabilir
frog32

138
İnanılmaz! yazarı RIP Aaron Swartz.
Atul Arvind

2
Herkes GPL 3.0 nedeniyle html2text alternatifi buldunuz mu?
jontsai

1
GPL insanların istediği kadar kötü değil. Aaron en iyisini biliyordu.
Steve K

2
Hem html2text hem de nltk denedim ama onlar benim için çalışmadı. Güzel çalışan güzel çorba 4 ile gidiş sona erdi (hiçbir cinas amaçlanan).
Ryan

150

Javascript almadan veya istemediğim şeyler almadan metin ayıklamak için bulduğum en iyi kod parçası:

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)

BeautifulSoup'u daha önce yüklemeniz yeterlidir:

pip install beautifulsoup4

2
Diyelim ki, # 3 numaralı satırı seçmek istersek?
hepidad

3
Öldürme komut dosyaları biraz, kurtarıcı !!
Nanda

2
Çok sayıda stackoverflow yanıtından geçtikten sonra, bunun benim için en iyi seçenek olduğunu hissediyorum. Karşılaştığım bir sorun, bazı durumlarda satırların birlikte eklenmiş olmasıdır. Get_text işlevinde bir ayırıcı ekleyerek üstesinden gelebildim:text = soup.get_text(separator=' ')
Joswin KJ

5
Yerine soup.get_text()kullandığım soup.body.get_text(), bu yüzden herhangi bir metni alamadım o <headbaşlık gibi> öğesi.
Sjoerd

10
Python 3 için,from urllib.request import urlopen
Jacob Kalakal Joseph

99

NOT: NTLK artık desteklemiyorclean_html işlevi

Aşağıdaki orijinal cevap ve yorumlar bölümlerinde bir alternatif.


NLTK kullanın

Html2text ile ilgili sorunları gidermek için 4-5 saatimi boşa harcadım. Neyse ki NLTK ile karşılaşabilirim.
Büyülü çalışıyor.

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
bazen bu yeterlidir :)
Sharmila

8
Bunu bin kere oy vermek istiyorum. Regex cehenneme sıkışmıştım, ama şimdi NLTK bilgeliğini görüyorum.
BenDundee

26
Görünüşe göre, clean_html artık desteklenmiyor: github.com/nltk/nltk/commit/…
alexanderlukanin13

5
Böyle basit bir görev için nltk gibi ağır bir kütüphaneyi içe aktarmak çok fazla olurdu
richie

54
@ alexanderlukanin13 Kaynak:raise NotImplementedError ("To remove HTML markup, use BeautifulSoup's get_text() function")
Chris Arena

54

Bugün kendimi aynı problemle karşı karşıya buldum. Tüm biçimlendirmelerin gelen içeriğini çıkarmak için çok basit bir HTML ayrıştırıcısı yazdım, kalan metni yalnızca minimum biçimlendirme ile döndürdüm.

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
Bu, yalnızca varsayılan modülleri kullanarak Python'da (2.7) bunu yapmanın en basit yolu gibi görünmektedir. Bu çok yaygın bir şey olduğundan ve varsayılan HTMLParser modülünde bunun için bir ayrıştırıcı olmamasının iyi bir nedeni yoktur.
Ingmar Hupp

2
Html karakterleri unicode dönüştürecek sanmıyorum, değil mi? Örneğin, &amp;dönüştürülmez &, değil mi?
Speedplane

Python 3 kullanımı içinfrom html.parser import HTMLParser
sebhaase

14

İşte xperroni'nin cevabının biraz daha eksiksiz bir versiyonu. Komut dosyası ve stil bölümlerini atlar ve charref'leri (örneğin, ') ve HTML varlıklarını (örn. & Amp;) çevirir.

Ayrıca önemsiz düz metin-html ters dönüştürücü içerir.

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


Get_text içinde, '' .join '' .join olmalıdır. Boş bir alan olmalı, aksi takdirde bazı metinler bir araya gelecektir.
Obinna Nnenanya

1
Ayrıca, H1, H2 ...., yayılma, vb gibi diğer metin kabı etiketleri dahil hariç, TÜM metinleri yakalamaz. Daha iyi bir kapsama alanı için ince ayar yapmak zorunda kaldım.
Obinna Nnenanya

11

Zaten birçok cevap olduğunu biliyorum, ama bulduğum en zarif ve pythonic çözüm kısmen burada açıklanıyor .

from bs4 import BeautifulSoup

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

Güncelleme

Fraser'ın yorumuna dayanarak, daha zarif bir çözüm var:

from bs4 import BeautifulSoup

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

2
Bir uyarıyı önlemek için BeautifulSoup'un kullanması için bir ayrıştırıcı belirtin:text = ''.join(BeautifulSoup(some_html_string, "lxml").findAll(text=True))
Floyd

Aşırı boşluktan kaçınmak için stripped_strings jeneratörünü kullanabilirsiniz - yaniclean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings
Fraser

8

Stripogram kütüphanesinde html2text yöntemini de kullanabilirsiniz.

from stripogram import html2text
text = html2text(your_html_string)

Stripogram kurmak için sudo easy_install stripogram'ı çalıştırın


23
Bu modül, pypi sayfasına göre kullanımdan kaldırılmıştır: "Bu paketi kullanmak için geçmişe ait bir nedeniniz olmadıkça, ona karşı tavsiye ederim!"
intuited

7

Veri madenciliği için Desen kütüphanesi vardır.

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

Hangi etiketlerin saklanacağına bile karar verebilirsiniz:

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

6

PyParsing harika bir iş çıkarıyor. PyParsing wiki'si öldürüldü, bu yüzden PyParsing kullanımına ilişkin örneklerin bulunduğu başka bir yer ( örnek bağlantı) ). Pyparsing ile biraz zaman harcamanın bir nedeni de çok kısa, çok iyi organize edilmiş bir O'Reilly Short Cut el kitabı yazmasıdır.

Bunu söyledikten sonra, BeautifulSoup'u çok kullanıyorum ve varlık sorunları ile başa çıkmak zor değil, BeautifulSoup'u çalıştırmadan önce bunları dönüştürebilirsiniz.

İyi şanslar


1
Bağlantı ölü veya ekşidir.
Yvette

4

Bu tam olarak bir Python çözümü değil, ancak metni Javascript'in önemli olduğunu düşündüğüm metne dönüştürecek (EG google.com). Tarayıcı Bağlantıları (Lynx değil) bir Javascript motoruna sahiptir ve -dump seçeneği ile kaynağı metne dönüştürür.

Böylece şöyle bir şey yapabilirsiniz:

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

HTMLParser modülü yerine htmllib'i inceleyin. Benzer bir arayüze sahip, ancak sizin için daha fazla iş yapıyor. (Oldukça eskidir, bu yüzden javascript ve css'den kurtulmak için çok yardımcı değildir. Türetilmiş bir sınıf oluşturabilirsiniz, ancak start_script ve end_style gibi adlarla yöntemler ekleyebilirsiniz (ayrıntılar için python belgelerine bakın), ancak zor bunu hatalı biçimlendirilmiş html için güvenilir bir şekilde yapmak.) Her neyse, düz metni konsola yazdırmak için basit bir şey var

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)

Not: HTMLError ve HTMLParserError HTMLParseError değerlerini okumalıdır. Bu işe yarar, ancak satır sonlarını korumak kötü bir iş çıkarır.
Dave Knight

4

Kaz çıkarıcı adı verilen bir Python Paketi öneririm Kaz aşağıdaki bilgileri çıkarmaya çalışacaktır:

Makalenin ana metni Makalenin ana görüntüsü Makaleye gömülü Youtube / Vimeo filmleri Meta Açıklama Meta etiketler

Daha fazla: https://pypi.python.org/pypi/goose-extractor/


4

daha fazla hıza ve daha az doğruluğa ihtiyacınız varsa, ham lxml kullanabilirsiniz.

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

kullanarak html2text yükleyin

pip install html2text

sonra,

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

Burada zaten çok sayıda cevap olduğunu biliyorum ama bence gazete3k de bir sözü hak ediyor. Kısa bir süre önce web'deki makalelerden metin çıkarma benzer bir görevi tamamlamak gerekiyordu ve bu kütüphane şimdiye kadar testlerimde bunu başarmak için mükemmel bir iş yaptı. Menü öğelerinde ve kenar çubuklarında bulunan metni ve sayfada OP'nin istediği şekilde görünen tüm JavaScript'leri yok sayar.

from newspaper import Article

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

HTML dosyalarını zaten indirdiyseniz, aşağıdakine benzer bir şey yapabilirsiniz:

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

Hatta makalelerin konularını özetlemek için birkaç NLP özelliği var:

article.nlp()
article.summary

3

Güzel çorba html varlıklarını dönüştürür. HTML en sık buggy ve unicode ve html kodlama sorunları ile dolu olduğunu düşünüyor muhtemelen en iyi bahis. Ben html ham metne dönüştürmek için kullandığım kod:

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

Başka bir seçenek, html'yi metin tabanlı bir web tarayıcısıyla çalıştırmak ve dökmektir. Örneğin (Lynx kullanarak):

lynx -dump html_to_convert.html > converted_html.txt

Bu, bir python betiği içinde şu şekilde yapılabilir:

import subprocess

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

Size tam olarak HTML dosyasındaki metni vermez, ancak kullanım durumunuza bağlı olarak html2text çıktısına tercih edilebilir.


3

Benim için en iyi çalışılan yazıtlardır.

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)

Sonuçlar gerçekten iyi


2

Başka bir python olmayan çözüm: Libre Office:

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

Bunu diğer alternatiflere tercih etmemin nedeni, her HTML paragrafının tek bir metin satırına (satır sonları) dönüştürülmesidir, aradığım şey budur. Diğer yöntemler sonradan işleme gerektirir. Lynx güzel çıktılar üretiyor, ama tam olarak aradığım şey değil. Ayrıca, Libre Office her türlü formattan dönüştürmek için kullanılabilir ...


2

Kim çamaşır suyubleach.clean(html,tags=[],strip=True) ile denedi ? benim için çalışıyor.


Benim için de çalışıyor gibi görünüyor, ancak bu amaçla kullanılmasını önermiyorlar: "Bu işlev, tek amacı bir dizede kötü amaçlı içeriği bir web'de içerik olarak görüntülenebilecek şekilde kaldırmak olan güvenlik odaklı bir işlevdir sayfa." -> bleach.readthedocs.io/en/latest/clean.html#bleach.clean
Loktopus

2

Apache Tika ile iyi sonuçlar elde ettim . Amacı, içerikten meta verilerin ve metnin çıkarılmasıdır, bu nedenle temeldeki ayrıştırıcı kutudan uygun şekilde ayarlanır.

Tika bir sunucu olarak çalıştırılabilir, bir Docker kapsayıcısında çalıştırmak / dağıtmak için önemsizdir ve buradan Python bağlamaları ile erişilebilir .


1

basit bir şekilde

import re

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

bu kod, html_text öğesinin '<' ile başlayan ve '>' ile biten tüm bölümlerini bulur ve boş bir dizeyle bulunanların tümünü değiştirir


1

@ PeYoTIL'in BeautifulSoup'u kullanması ve stil ve script içeriğini ortadan kaldırması benim için işe yaramadı. Bunun decomposeyerine kullanarak denedim extractama hala işe yaramadı. Böylece <p>etiketleri kullanarak metni biçimlendiren ve <a>etiketleri href bağlantısıyla değiştiren kendim oluşturdum . Ayrıca metnin içindeki bağlantılarla da baş eder. Boş Bu özünden gömülü bir test doc ile.

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
Teşekkürler, bu cevabın hafife alınması. Daha çok bir tarayıcı gibi davranan (yeni satırları göz ardı etmek ve yalnızca paragrafları ve satır sonlarını göz önünde bulundurarak) temiz bir metin temsiline sahip olmak isteyenler için, BeautifulSoup's get_textbasitçe kesmez.
jrial

@jrial yararlı bulduğunuza sevindim, ayrıca katkıda bulunduğunuz için teşekkürler. Diğer herkes için, bağlantılı gist biraz geliştirildi. OP'nin anlatmak istediği şey, lynx gibi metin tabanlı bir tarayıcıya benzer şekilde, html'yi metne dönüştüren bir araçtır. Bu çözüm böyle deniyor. Çoğu insanın katkıda bulunduğu şey sadece metin çıkarıcılar.
racitup

1

Python 3.x'te 'imaplib' ve 'e-posta' paketlerini içe aktararak bunu çok kolay bir şekilde yapabilirsiniz. Bu eski bir yazı olmasına rağmen, belki de cevabım bu yazıya yeni gelenlere yardımcı olabilir.

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

Şimdi gövde değişkenini yazdırabilirsiniz ve düz metin biçiminde olacaktır :) Sizin için yeterince iyi ise, kabul edilen cevap olarak seçmek güzel olurdu.


Bu hiçbir şeyi dönüştürmez .
Antti Haapala

1
Bu, text/plainbir başkası oraya koyarsa, bir parçayı e-postadan nasıl çıkaracağınızı gösterir . HTML'yi düz metne dönüştürmek için hiçbir şey yapmaz ve HTML'yi bir web sitesinden dönüştürmeye çalışıyorsanız uzaktan yararlı bir şey yapmaz.
tripleee

1

BeautifulSoup ile HTML'den yalnızca metin çıkarabilirsiniz

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

Bir çok insan html etiketlerini şeritlemek için regex kullanarak bahsetmiş olsa da, bir çok olumsuz tarafı var.

Örneğin:

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

Ayrıştırılmalıdır:

Hello world
I love you

İşte bulduğum bir pasaj, özel ihtiyaçlarınıza göre özelleştirebilirsiniz ve bir cazibe gibi çalışır

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

Python 2.7.9+ sürümünde BeautifulSoup4 kullanan başka bir örnek

içerir:

import urllib2
from bs4 import BeautifulSoup

Kod:

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

Açıklaması:

URL verilerini html (BeautifulSoup kullanarak) olarak okuyun, tüm komut dosyası ve stil öğelerini kaldırın ve .get_text () kullanarak yalnızca metni alın. Satırlara ayırın ve her birinde önde gelen ve sondaki boşluğu kaldırın, ardından her satırdaki çok satırlı satırları bir satır içine bölün. Sonra text = '\ n''e katılın, boş satırlar bırakın, nihayet onaylı utf-8 olarak geri dönün.

Notlar:

  • Bu çalıştığı bazı sistemler SSL sorunu nedeniyle https: // bağlantılarında başarısız olur, bu sorunu gidermek için doğrulamayı kapatabilirsiniz. Örnek düzeltme: http://blog.pengyifan.com/how-to-fix-python-ssl-certificate_verify_failed/

  • Python <2.7.9 bunu çalıştırırken bazı sorunlar yaşayabilir

  • text.encode ('utf-8') garip kodlama bırakabilir, bunun yerine str (metin) döndürmek isteyebilir.


0

İşte düzenli olarak kullandığım kod.

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

Umarım bu yardımcı olur.


0

Uygulama python makroları kullanabileceğinden LibreOffice yazar yorumu haklıdır. Hem bu soruyu cevaplamak hem de LibreOffice'in makro tabanını ilerletmek için birçok fayda sağlıyor gibi görünüyor. Bu çözüm, daha büyük bir üretim programının parçası olarak kullanılmak yerine tek seferlik bir uygulama ise, HTML'yi yazarda açmak ve sayfayı metin olarak kaydetmek burada tartışılan sorunları çözer gibi görünmektedir.


0

Perl yolu (üzgünüm anne, üretimde asla yapmayacağım).

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

Bu pek çok nedenden dolayı kötü bir uygulama, örneğin&nbsp;
Uri Goren

Evet! Bu doğru! Bunu bir daha yapma!
brunql
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.