Извлечение текста из файла HTML с помощью Python

Я хотел бы извлечь текст из файла HTML с помощью Python. Мне нужен практически такой же результат, как если бы я скопировал текст из браузера и вставил его в блокнот.

Я бы хотел что-то более надежное, чем использование регулярных выражений, которые могут дать сбой в плохо сформированном HTML. Я видел, как многие рекомендуют Beautiful Soup, но у меня было несколько проблем с его использованием. Во-первых, он улавливал нежелательный текст, такой как исходный код JavaScript. Кроме того, он не интерпретировал объекты HTML. Например, я ожидал, что 'в исходном HTML-коде будет преобразован в апостроф в тексте, как если бы я вставил содержимое браузера в блокнот.

Обновление html2text выглядит многообещающим. Он правильно обрабатывает объекты HTML и игнорирует JavaScript. Однако это не совсем простой текст; он производит уценку, которая затем должна быть преобразована в обычный текст. В нем нет примеров или документации, но код выглядит чистым.


Связанные вопросы:


person John D. Cook    schedule 30.11.2008    source источник
comment
Некоторое время люди, кажется, находят мой ответ NLTK (совсем недавно) чрезвычайно полезным, поэтому вы можете подумать об изменении принятого ответа. Спасибо!   -  person Shatu    schedule 21.10.2013
comment
Никогда не думал, что наткнусь на вопрос автора моего любимого блога! The Endeavour!   -  person Ryan G    schedule 30.04.2014
comment
@Shatu Теперь, когда ваше решение больше не действует, вы можете удалить свой комментарий. Спасибо! ;)   -  person Sнаđошƒаӽ    schedule 05.04.2016


Ответы (32)


html2text - это программа Python, которая неплохо справляется с этой задачей.

person RexE    schedule 30.11.2008
comment
бит это gpl 3.0, что означает, что он может быть несовместим - person frog32; 07.11.2012
comment
Удивительный! его автор - RIP Аарон Шварц. - person Atul Arvind; 10.08.2013
comment
Кто-нибудь нашел альтернативы html2text из-за GPL 3.0? - person jontsai; 05.09.2014
comment
GPL не так плоха, как люди хотят ее видеть. Аарон знал лучше всех. - person Steve K; 13.10.2014
comment
Я пробовал и html2text, и nltk, но у меня они не работали. В итоге я выбрал Beautiful Soup 4, который прекрасно работает (без каламбура). - person Ryan Shea; 30.04.2015
comment
Ищу модуль для этого. Это то, что такое html2text? - person Ecko; 01.02.2016
comment
Кажется, это больше не работает, какие-либо обновления или предложения? - person David Andrei Ned; 15.12.2016
comment
Я знаю, что это (ВООБЩЕ) не то место, но я перехожу по ссылке на блог Аарона, профиль и проекты на github, и меня очень беспокоит тот факт, что о его смерти не упоминается, и она, конечно, заморожена в 2012 году, как будто время остановилось или он взял очень долгий отпуск. Очень тревожно. - person JulienFr; 09.09.2017

Лучший фрагмент кода, который я нашел для извлечения текста без получения javascript или нежелательных вещей:

from urllib.request import urlopen
from bs4 import BeautifulSoup

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

# 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, прежде чем:

pip install beautifulsoup4
person PeYoTlL    schedule 07.07.2014
comment
Как, если мы хотим выбрать какую-то строку, только что сказано, строку №3? - person hepidad; 26.08.2014
comment
Сценарий убийства, спаситель !! - person Nanda; 17.11.2014
comment
Пройдя через множество ответов на stackoverflow, я чувствую, что это лучший вариант для меня. Одна из проблем, с которыми я столкнулся, заключается в том, что в некоторых случаях строки складывались вместе. Мне удалось преодолеть это, добавив разделитель в функцию get_text: text = soup.get_text(separator=' ') - person Joswin K J; 02.09.2015
comment
Вместо soup.get_text() я использовал soup.body.get_text(), так что я не получаю никакого текста из элемента <head ›, такого как заголовок. - person Sjoerd; 15.01.2016
comment
Мне нужен soup.getText () - person gogasca; 16.06.2016
comment
Как извлечь символы , в содержимом - person Ashok kumar Ganesan; 09.12.2016
comment
Для Python 3 from urllib.request import urlopen - person Jacob Kalakal Joseph; 19.05.2017
comment
Это прекрасно работает! Есть ли простой способ извлечь все ссылки из HTML и точно согласовать их с соответствующим текстом? - person Arya; 23.11.2019
comment
Идеально, за исключением того, что не разрывает линии на <br> - person VBobCat; 09.01.2020
comment
На самом деле вы можете добиться того же чистого результата без этих ручных циклов, просто используя два дополнительных стандартных параметра: soup.get_text(separator='\n', strip=True) - person DemX86; 16.06.2020
comment
это кажется мучительно медленным, есть ли способ сделать это быстрее? - person kodlan; 30.06.2020
comment
Для более быстрой обработки я использовал selectolax lib. Он довольно ограничен и производит вывод с дополнительными пробелами, которые мне пришлось удалить вручную. Но вроде работает намного быстрее. - person kodlan; 30.06.2020

ПРИМЕЧАНИЕ. NTLK больше не поддерживает функцию clean_html.

Оригинальный ответ ниже и альтернатива в разделах комментариев.


Используйте NLTK.

Я потратил 4-5 часов на устранение проблем с html2text. К счастью, я мог встретить NLTK.
Он работает волшебным образом.

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)
person Shatu    schedule 20.11.2011
comment
Он просто удаляет разметку HTML и не обрабатывает теги (например, <p> и <br/>) или объекты. - person utapyngo; 11.12.2011
comment
иногда этого достаточно :) - person Sharmila; 12.01.2012
comment
Я хочу проголосовать за это тысячу раз. Я застрял в аду регулярных выражений, но теперь я вижу мудрость NLTK. - person BenDundee; 22.02.2013
comment
По-видимому, clean_html больше не поддерживается: github.com/nltk/commit/nltk/ - person alexanderlukanin13; 22.08.2013
comment
импортировать тяжелую библиотеку, такую ​​как nltk, для такой простой задачи было бы слишком много - person richie; 22.10.2013
comment
@ alexanderlukanin13 Из источника: raise NotImplementedError ("To remove HTML markup, use BeautifulSoup's get_text() function") - person Chris Arena; 06.04.2014
comment
@ChrisArena Да, хороший звонок, из-за этого я перешел на BeautifulSoup. - person Ryan Shea; 21.04.2015

Сегодня я столкнулся с той же проблемой. Я написал очень простой анализатор HTML, чтобы удалить из входящего содержимого все разметки, возвращая оставшийся текст с минимальным форматированием.

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()
person xperroni    schedule 21.10.2010
comment
Это кажется наиболее простым способом сделать это в Python (2.7), используя только модули по умолчанию. Что действительно глупо, так как это такая часто используемая вещь, и нет веской причины, почему нет парсера для этого в модуле HTMLParser по умолчанию. - person Ingmar Hupp; 18.08.2011
comment
Я не думаю, что конвертирую html-символы в юникод, верно? Например, &amp; не будет преобразован в &, верно? - person speedplane; 30.11.2012
comment
Для Python 3 используйте from html.parser import HTMLParser - person sebhaase; 30.05.2017

Я знаю, что уже есть много ответов, но наиболее элегантное и питоническое решение, которое я нашел, частично описывается здесь.

from bs4 import BeautifulSoup

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

Обновлять

Основываясь на комментарии Фрейзера, вот более элегантное решение:

from bs4 import BeautifulSoup

clean_text = ' '.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings)
person Floyd    schedule 06.10.2016
comment
Чтобы избежать предупреждения, укажите парсер, который будет использовать BeautifulSoup: text = ''.join(BeautifulSoup(some_html_string, "lxml").findAll(text=True)) - person Floyd; 06.10.2016
comment
Вы можете использовать генератор stripped_strings, чтобы избежать чрезмерного пробела, т.е. clean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings - person Fraser; 08.04.2018
comment
Я бы порекомендовал ' '.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings) хотя бы с одним пробелом, иначе строка, такая как Please click <a href="link">text</a> to continue, будет отображаться как Please clicktextto continue - person am70; 01.03.2021
comment
Готово, спасибо @ am70! - person Floyd; 01.03.2021

Вот версия ответа xperroni, которая немного более полная. Он пропускает разделы скриптов и стилей и переводит charref (например, ') и объекты HTML (например,).

Он также включает тривиальный обратный преобразователь простого текста в HTML.

"""
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)
person bit4    schedule 07.05.2013
comment
версия python 3: gist.github.com/Crazometer/af441bc7dc7353df41307b51 - person Crazometer; 15.09.2016
comment
В get_text '.join должно быть' '.join. Там должно быть пустое место, иначе некоторые тексты сойдутся вместе. - person Obinna Nnenanya; 21.01.2019
comment
Кроме того, это не будет перехватывать ВСЕ тексты, за исключением того, что вы включаете другие теги текстовых контейнеров, такие как H1, H2 ...., span и т. Д. Мне пришлось настроить его для лучшего охвата. - person Obinna Nnenanya; 21.01.2019

Вы также можете использовать метод html2text в библиотеке стрипограмм.

from stripogram import html2text
text = html2text(your_html_string)

Чтобы установить стрипограмму, запустите sudo easy_install stripogram

person GeekTantra    schedule 23.09.2009
comment
Этот модуль, согласно его странице pypi, устарел: если у вас нет исторических причин для использования этот пакет, я бы не советовал! - person intuited; 24.07.2010

Есть библиотека шаблонов для интеллектуального анализа данных.

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

Вы даже можете решить, какие теги оставить:

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

Я знаю, что здесь уже есть множество ответов, но я думаю, что газета3k также заслуживает упоминания . Недавно мне нужно было выполнить аналогичную задачу по извлечению текста из статей в Интернете, и эта библиотека до сих пор отлично справлялась с этой задачей в моих тестах. Он игнорирует текст, найденный в пунктах меню и боковых панелях, а также любой код JavaScript, который появляется на странице как запросы OP.

from newspaper import Article

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

Если у вас уже есть загруженные файлы HTML, вы можете сделать что-то вроде этого:

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

В нем даже есть несколько функций НЛП для обобщения тем статей:

article.nlp()
article.summary
person spatel4140    schedule 18.02.2018

PyParsing отлично справляется. Вики-сайт PyParsing был убит, поэтому вот еще одно место, где есть примеры использования PyParsing (пример ссылки). Одна из причин потратить немного времени на pyparsing заключается в том, что он также написал очень краткое, очень хорошо организованное руководство O'Reilly Short Cut, которое также стоит недорого.

Сказав это, я часто использую BeautifulSoup, и решить проблемы с сущностями не так уж и сложно, вы можете преобразовать их перед запуском BeautifulSoup.

Удачи

person PyNEwbie    schedule 30.11.2008
comment
Ссылка мертвая или испорченная. - person ; 11.08.2018

Это не совсем решение Python, но оно преобразует текст, который генерирует Javascript, в текст, что, на мой взгляд, важно (например, google.com). Ссылки браузера (не Lynx) имеют механизм Javascript и преобразуют исходный текст в текст с параметром -dump.

Итак, вы можете сделать что-то вроде:

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()
person Andrew    schedule 18.05.2012

Вместо модуля HTMLParser проверьте htmllib. Он имеет аналогичный интерфейс, но выполняет большую часть работы за вас. (Он довольно древний, поэтому он не очень помогает с точки зрения избавления от javascript и css. Вы можете создать производный класс, но и добавить методы с такими именами, как start_script и end_style (подробности см. В документации python), но это сложно чтобы сделать это надежно для искаженного html.) В любом случае, вот что-то простое, которое выводит простой текст на консоль

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)
person Mark    schedule 20.02.2012
comment
NB: HTMLError и HTMLParserError должны читать HTMLParseError. Это работает, но плохо справляется с поддержанием разрывов строк. - person Dave Knight; 08.04.2014

Я рекомендую пакет Python под названием goose-extractor Goose попытается извлечь следующую информацию:

Основной текст статьи Основное изображение статьи Любые фильмы Youtube / Vimeo, встроенные в статью Мета Описание Мета-теги

Подробнее: https://pypi.python.org/pypi/goose-extractor/

person Li Yingjun    schedule 25.11.2015

если вам нужна большая скорость и меньшая точность, вы можете использовать необработанный lxml.

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()
person Hodza    schedule 30.08.2016

установить html2text с помощью

pip install html2text

тогда,

>>> 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!
person Pravitha V    schedule 05.04.2017

Красивый суп действительно конвертирует html-сущности. Это, вероятно, ваш лучший выбор, учитывая, что HTML часто содержит ошибки и проблемы с кодировкой Unicode и html. Это код, который я использую для преобразования HTML в необработанный текст:

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 ""
person speedplane    schedule 30.11.2012

Другое решение, отличное от Python: Libre Office:

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

Причина, по которой я предпочитаю этот вариант другим альтернативам, заключается в том, что каждый абзац HTML преобразуется в одну текстовую строку (без разрывов строк), что я и искал. Другие методы требуют постобработки. Lynx действительно дает хороший результат, но не совсем то, что я искал. Кроме того, Libre Office можно использовать для конвертации из всевозможных форматов ...

person YakovK    schedule 11.12.2015

Кто-нибудь пробовал bleach.clean(html,tags=[],strip=True) использовать отбеливатель? это работает для меня.

person rox    schedule 16.01.2017
comment
Кажется, у меня тоже работает, но они не рекомендуют использовать ее для этой цели: эта функция ориентирована на безопасность, единственная цель которой - удалить вредоносный контент из строки, чтобы он мог отображаться как контент на веб-странице . - ›bleach.readthedocs.io/en/latest/clean.html# bleach.clean - person Loktopus; 25.07.2018

Лучше всего у меня сработали надписи.

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)

Результаты действительно хорошие

person Vim    schedule 06.04.2018

У меня был аналогичный вопрос, и я использовал один из ответов с BeautifulSoup. Проблема была в том, что это было очень медленно. В итоге я использовал библиотеку под названием selectolax. Он довольно ограничен, но подходит для этой задачи. Единственная проблема заключалась в том, что мне приходилось вручную удалять ненужные пробелы. Но, похоже, это решение BeautifulSoup работает намного быстрее.

from selectolax.parser import HTMLParser

def get_text_selectolax(html):
    tree = HTMLParser(html)

    if tree.body is None:
        return None

    for tag in tree.css('script'):
        tag.decompose()
    for tag in tree.css('style'):
        tag.decompose()

    text = tree.body.text(separator='')
    text = " ".join(text.split()) # this will remove all the whitespaces
    return text
person kodlan    schedule 30.06.2020

Другой вариант - запустить html через текстовый веб-браузер и выгрузить его. Например (с использованием Lynx):

lynx -dump html_to_convert.html > converted_html.txt

Это можно сделать в скрипте Python следующим образом:

import subprocess

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

Он не даст вам точно только текст из файла HTML, но в зависимости от вашего варианта использования это может быть предпочтительнее вывода html2text.

person John Lucas    schedule 08.08.2014

У меня хорошие результаты с Apache Tika. Его цель - извлечение метаданных и текста из содержимого, поэтому базовый синтаксический анализатор настраивается соответствующим образом из коробки.

Tika можно запускать как сервер, запускать / развертывать в контейнере Docker тривиально. оттуда можно получить доступ через привязки Python.

person u-phoria    schedule 07.05.2018

простым способом

import re

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

этот код находит все части html_text, начинающиеся с '‹' и заканчивающиеся на '>', и заменяет все найденные пустой строкой

person David Fraga    schedule 02.06.2016

Ответ @PeYoTIL с использованием BeautifulSoup и удалением стиля и содержимого скрипта для меня не сработал. Я попробовал использовать decompose вместо extract, но это все равно не сработало. Поэтому я создал свой собственный, который также форматирует текст с помощью тегов <p> и заменяет теги <a> ссылкой href. Также отлично справляется со ссылками внутри текста. Доступно на этой сути со встроенным тестовым документом.

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
person racitup    schedule 06.12.2016
comment
Спасибо, этот ответ недооценен. Для тех из нас, кто хочет иметь чистое текстовое представление, которое больше похоже на браузер (игнорируя символы новой строки и принимая во внимание только абзацы и разрывы строк), get_text от BeautifulSoup просто не сокращает его. - person jrial; 17.04.2018
comment
@jrial рад, что вы нашли его полезным, также спасибо за вклад. Для всех остальных сущность ссылки была немного улучшена. OP, похоже, намекает на инструмент, который преобразует html в текст, очень похоже на текстовый браузер, такой как lynx. Это то, что пытается сделать это решение. Большинство людей вносят свой вклад только в экстракторы текста. - person racitup; 19.04.2018

В Python 3.x это можно сделать очень легко, импортировав пакеты imaplib и email. Хотя это более старый пост, но, возможно, мой ответ может помочь новичкам в этом посте.

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

Теперь вы можете распечатать переменную тела, и она будет в текстовом формате :) Если она вам подходит, было бы неплохо выбрать ее как принятый ответ.

person Wahib Ul Haq    schedule 02.02.2014
comment
Это ничего не конвертирует. - person Antti Haapala; 03.10.2017
comment
Это показывает вам, как извлечь text/plain часть из электронного письма, если кто-то другой поместил ее туда. Он ничего не делает для преобразования HTML в открытый текст и не делает ничего отдаленно полезного, если вы пытаетесь преобразовать HTML, скажем, с веб-сайта. - person tripleee; 27.11.2017

вы можете извлекать только текст из HTML с 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)
person Sai Gopi Me    schedule 13.04.2018

Путь Perl (извини, мама, я никогда не буду делать это в продакшене).

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
person brunql    schedule 06.07.2018
comment
Это плохая практика по многим причинам, например &nbsp; - person Uri Goren; 21.01.2019
comment
Да! Это правда! Не делай этого здесь! - person brunql; 22.01.2019

Хотя многие люди упоминали об использовании регулярных выражений для удаления тегов html, есть много недостатков.

Например:

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

Следует разбирать на:

Hello world
I love you

Вот фрагмент, который я придумал, вы можете настроить его под свои нужды, и он отлично работает.

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
person Uri Goren    schedule 21.01.2019

Другой пример использования BeautifulSoup4 в Python 2.7.9+

включает:

import urllib2
from bs4 import BeautifulSoup

Код:

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

Объяснение:

Прочтите данные URL как html (используя BeautifulSoup), удалите все элементы скрипта и стиля, а также получите только текст с помощью .get_text (). Разбейте на строки и удалите начальные и конечные пробелы на каждой, затем разбейте несколько заголовков на строку каждый chunks = (фраза.strip () для строки в строках для фразы в line.split ("")). Затем, используя text = '\ n'.join, отбросьте пустые строки и, наконец, вернитесь как санкционированный utf-8.

Примечания:

  • Некоторые системы, на которых это работает, не будут работать с подключениями https: // из-за проблемы с SSL, вы можете отключить проверку, чтобы исправить эту проблему. Пример исправления: http://blog.pengyifan.com/how-to-fix-python-ssl-certificate_verify_failed/

  • Python ‹2.7.9 может иметь некоторые проблемы с запуском этого

  • text.encode ('utf-8') может оставлять странную кодировку, возможно, вместо этого может потребоваться просто вернуть str (text).

person Mike Q    schedule 27.08.2019

Вот код, который я использую регулярно.

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

Надеюсь, это поможет.

person troymyname00    schedule 25.10.2017

Комментарий автора LibreOffice заслуживает внимания, поскольку приложение может использовать макросы Python. Кажется, он предлагает множество преимуществ как для ответа на этот вопрос, так и для развития макро-базы LibreOffice. Если это разрешение является одноразовой реализацией, а не использоваться как часть более крупной производственной программы, открытие HTML в модуле записи и сохранение страницы в виде текста, по-видимому, решит проблемы, обсуждаемые здесь.

person 1of7    schedule 15.05.2018

Я добиваюсь этого примерно так.

>>> import requests
>>> url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"
>>> res = requests.get(url)
>>> text = res.text
person Waqar Detho    schedule 07.08.2016
comment
Я использую python 3.4, и этот код у меня работает нормально. - person Waqar Detho; 18.10.2016
comment
текст будет содержать теги html - person Ivelin; 29.11.2016