Я хочу извлечь текст из файла HTML с помощью Python. Мне нужен практически такой же результат, как если бы я скопировал текст из браузера и вставил его в блокнот.
Я бы хотел что-то более надежное, чем использование регулярных выражений, которые могут дать сбой в плохо сформированном HTML. Я видел, как многие рекомендуют Beautiful Soup, но у меня было несколько проблем с его использованием. Во-первых, он улавливал нежелательный текст, такой как исходный код JavaScript. Кроме того, он не интерпретировал объекты HTML. Например, я ожидал & # 39; в исходном HTML-коде для преобразования в апостроф в тексте, как если бы я вставил содержимое браузера в блокнот.
Обновлятьhtml2text выглядит многообещающе. Он правильно обрабатывает объекты HTML и игнорирует JavaScript. Однако это не совсем простой текст; он производит уценку, которая затем должна быть преобразована в обычный текст. В нем нет примеров или документации, но код выглядит чистым.
Связанные вопросы:
Никогда не думал, что наткнусь на вопрос, который задает автор моего любимого блога! The Endeavour!
@Shatu Теперь, когда ваше решение больше не действует, вы можете удалить свой комментарий. Спасибо! ;)






html2text - это программа на Python, которая с этим неплохо справляется.
бит это gpl 3.0, что означает, что он может быть несовместим
Удивительный! его автор - RIP Аарон Шварц.
Кто-нибудь нашел альтернативы html2text из-за GPL 3.0?
GPL не так плоха, как люди хотят ее видеть. Аарон знал лучше.
Я пробовал и html2text, и nltk, но у меня они не работали. В итоге я выбрал Beautiful Soup 4, который прекрасно работает (без каламбура).
Ищу модуль для этого. Это то, что такое html2text?
Кажется, это больше не работает, какие-либо обновления или предложения?
Я знаю, что это (ВООБЩЕ) не то место, но я перехожу по ссылке на блог Аарона, профиль и проекты на github, и меня очень беспокоит тот факт, что о его смерти не упоминается, и она, конечно, заморожена в 2012 году, как будто время остановилось или он взял очень долгий отпуск. Очень тревожно.
PyParsing отлично справляется. Вики-сайт PyParsing был убит, поэтому вот еще одно место, где есть примеры использования PyParsing (пример ссылки). Одна из причин потратить немного времени на pyparsing заключается в том, что он также написал очень краткое, очень хорошо организованное руководство O'Reilly Short Cut, которое также стоит недорого.
Сказав это, я часто использую BeautifulSoup, и решить проблемы с сущностями не так уж и сложно, вы можете преобразовать их перед запуском BeautifulSoup.
Удачи
Ссылка мертвая или испорченная.
Вы также можете использовать метод html2text в библиотеке стрипограмм.
from stripogram import html2text
text = html2text(your_html_string)
Чтобы установить стрипограмму, запустите sudo easy_install stripogram
Этот модуль, согласно его страница pypi, устарел: «Если у вас нет каких-либо исторических причин для использования этого пакета, я бы не советовал его использовать!»
Сегодня я столкнулся с той же проблемой. Я написал очень простой анализатор 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()
Это кажется наиболее простым способом сделать это в Python (2.7), используя только модули по умолчанию. Что действительно глупо, так как это такая часто используемая вещь, и нет веской причины, почему нет парсера для этого в модуле HTMLParser по умолчанию.
Я не думаю, что конвертирую html-символы в Unicode, верно? Например, & не будет преобразован в &, верно?
Для Python 3 используйте from html.parser import HTMLParser
ПРИМЕЧАНИЕ: NTLK больше не поддерживает функцию clean_html
Оригинальный ответ ниже и альтернатива в разделах комментариев.
Используйте НЛТК
Я потратил 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)
Он просто удаляет разметку HTML и не обрабатывает теги (например, <p> и <br/>) или объекты.
иногда этого достаточно :)
Я хочу проголосовать за это тысячу раз. Я застрял в аду регулярных выражений, но теперь я вижу мудрость NLTK.
Судя по всему, clean_html больше не поддерживается: github.com/nltk/nltk/commit/…
импортировать тяжелую библиотеку, такую как nltk, для такой простой задачи было бы слишком много
@ alexanderlukanin13 Из источника: raise NotImplementedError ("To remove HTML markup, use BeautifulSoup's get_text() function")
@ChrisArena Да, хороший звонок, из-за этого я перешел на BeautifulSoup.
clean_html () и clean_url () - симпатичная функция в NLTK, которая была удалена, так как BeautifulSoup лучше справляется с работой и анализирует язык разметки, см. github.com/nltk/nltk/commit/… Здесь документация BeautifulSoup: crummy.com/software/BeautifulSoup/bs4/doc
Вместо модуля 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)
NB: HTMLError и HTMLParserError должны читать HTMLParseError. Это работает, но плохо справляется с поддержанием разрывов строк.
Это не совсем решение 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()
Есть библиотека шаблонов для интеллектуального анализа данных.
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
Красивый суп действительно конвертирует html-сущности. Вероятно, это ваш лучший выбор, учитывая, что HTML часто содержит ошибки и проблемы с кодировкой Unicode и html. Это код, который я использую для преобразования HTML в необработанный текст:
import BeautifulSoup
def getsoup(data, to_unicode=False):
data = data.replace(" ", " ")
# 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 ""
Вот версия ответа xperroni, которая немного более полная. Он пропускает разделы скриптов и стилей и переводит charref (например, & # 39;) и объекты HTML (например, & amp;).
Он также включает тривиальный обратный преобразователь простого текста в 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 {'&':'&', "'":''', '"':'"', '<':'<', '>':'>'}.get(t)
return '<a href = "%s">%s</a>' % (t, t)
return re.sub(r'https?://[^] ()"\';]+|[&\'"<>]', f, text)
версия python 3: gist.github.com/Crazometer/af441bc7dc7353d41390a59f20f07b51
В get_text '.join должно быть' '.join. Там должно быть пустое место, иначе некоторые тексты сойдутся вместе.
Кроме того, это не будет перехватывать ВСЕ тексты, за исключением того, что вы включаете другие теги текстовых контейнеров, такие как H1, H2 ...., span и т. д. Мне пришлось настроить его для лучшего охвата.
В 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
Теперь вы можете распечатать переменную тела, и она будет в текстовом формате :) Если она вам подходит, было бы неплохо выбрать ее как принятый ответ.
Это ничего не перерабатывать.
Это показывает вам, как извлечь часть text/plain из электронного письма, если кто-то другой поместил ее туда. Он ничего не делает для преобразования HTML в открытый текст и не делает ничего отдаленно полезного, если вы пытаетесь преобразовать HTML, скажем, с веб-сайта.
Лучший фрагмент кода, который я нашел для извлечения текста без получения 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
Как, если мы хотим выбрать какую-то строку, только что сказано, строку №3?
Сценарий убийства, спаситель !!
Пройдя через множество ответов на stackoverflow, я чувствую, что это лучший вариант для меня. Одна из проблем, с которыми я столкнулся, заключается в том, что в некоторых случаях строки складывались вместе. Мне удалось преодолеть это, добавив разделитель в функции get_text: text = soup.get_text(separator=' ')
Вместо soup.get_text() я использовал soup.body.get_text(), так что я не получаю никакого текста из элемента <head>, такого как заголовок.
Мне нужен soup.getText ()
Как извлечь символы & nbsp;, & lt; в контенте
Для Python 3, from urllib.request import urlopen
Это прекрасно работает! Есть ли простой способ извлечь все ссылки из HTML и сохранить их в соответствии с соответствующим текстом?
Идеально, за исключением того, что не разрывает линии на <br>
На самом деле вы можете добиться того же чистого результата без этих ручных циклов, просто используя два дополнительных стандартных параметра: soup.get_text(separator='\n', strip=True)
это кажется мучительно медленным, есть ли способ сделать это быстрее?
Для более быстрой обработки я использовал selectolax lib. Он довольно ограничен и производит вывод с дополнительными пробелами, которые мне пришлось удалить вручную. Но вроде работает намного быстрее.
Другой вариант - запустить 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.
Я рекомендую пакет Python под названием goose-extractor. Гусь попытается извлечь следующую информацию:
Основной текст статьи Основное изображение статьи Любые фильмы Youtube / Vimeo, встроенные в статью Мета-описание Мета-теги
Другое решение, отличное от Python: Libre Office:
soffice --headless --invisible --convert-to txt input1.html
Причина, по которой я предпочитаю этот вариант другим альтернативам, заключается в том, что каждый абзац HTML преобразуется в одну текстовую строку (без разрывов строк), что я и искал. Другие методы требуют постобработки. Lynx действительно дает хороший результат, но не совсем то, что я искал. Кроме того, Libre Office можно использовать для конвертации из всевозможных форматов ...
простым способом
import re
html_text = open('html_file.html').read()
text_filtered = re.sub(r'<(.*?)>', '', html_text)
этот код находит все части html_text, начинающиеся с '<' и заканчивающиеся на '>', и заменяет все найденные пустой строкой
Я добиваюсь этого примерно так.
>>> import requests
>>> url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"
>>> res = requests.get(url)
>>> text = res.text
Я использую python 3.4, и этот код у меня работает нормально.
текст будет содержать теги html
если вам нужна большая скорость и меньшая точность, вы можете использовать необработанный 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()
Я знаю, что уже есть много ответов, но большинство решений элегантный и питонический, которые я нашел, частично описываются здесь.
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)
Чтобы избежать предупреждения, укажите парсер, который будет использовать BeautifulSoup: text = ''.join(BeautifulSoup(some_html_string, "lxml").findAll(text=True))
Вы можете использовать генератор stripped_strings, чтобы избежать чрезмерного пробела - например, clean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings
Я бы рекомендовал ' '.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings) по крайней мере с одним пробелом, в противном случае строка, такая как Please click <a href = "link">text</a> to continue, отображается как Please clicktextto continue
Готово, спасибо @ am70!
Ответ @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
Спасибо, этот ответ недооценен. Для тех из нас, кто хочет иметь чистое текстовое представление, которое больше похоже на браузер (игнорируя символы новой строки и принимая во внимание только абзацы и разрывы строк), BeautifulSoup's get_text просто не сокращает его.
@jrial рад, что вы нашли его полезным, также спасибо за вклад. Для всех остальных сущность ссылки была немного улучшена. OP, похоже, намекает на инструмент, который отображает html в текст, очень похоже на текстовый браузер, такой как lynx. Это то, что пытается сделать это решение. Большинство людей вносят свой вклад только в экстракторы текста.
Кто-нибудь пробовал bleach.clean(html,tags=[],strip=True) с отбеливать? это работает для меня.
Кажется, у меня тоже работает, но они не рекомендуют использовать ее для этой цели: «Эта функция ориентирована на безопасность, единственная цель которой - удалить вредоносный контент из строки, чтобы он мог отображаться как контент в Интернете. страница." -> bleach.readthedocs.io/en/latest/clean.html#bleach.clean
установить 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!
Вот код, который я использую регулярно.
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
Надеюсь, это поможет.
Я знаю, что здесь уже есть много ответов, но я думаю, что газета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
Лучше всего у меня сработали надписи.
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)
Результаты действительно хорошие
вы можете извлекать только текст из 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)
У меня были хорошие результаты с Апач Тика. Его цель - извлечение метаданных и текста из содержимого, поэтому базовый синтаксический анализатор настраивается соответствующим образом из коробки.
Tika может запускаться как сервер, тривиально запускать / развертывать в контейнере Docker, а оттуда можно получить доступ через Привязки Python.
Комментарий автора LibreOffice заслуживает внимания, поскольку приложение может использовать макросы Python. Кажется, он предлагает множество преимуществ как для ответа на этот вопрос, так и для развития макро-базы LibreOffice. Если это разрешение является одноразовой реализацией, а не использоваться как часть более крупной производственной программы, открытие HTML в модуле записи и сохранение страницы в виде текста, по-видимому, решит проблемы, обсуждаемые здесь.
Путь 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
Это плохая практика по многим причинам, например
Да! Это так! Не делай этого здесь!
Хотя многие люди упоминали об использовании регулярных выражений для удаления тегов html, есть много недостатков.
Например:
<p>hello 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
Другой пример использования 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).
У меня был аналогичный вопрос, и я фактически использовал один из ответов с 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
Некоторое время люди, кажется, находят мой ответ NLTK (совсем недавно) чрезвычайно полезным, поэтому вы можете подумать об изменении принятого ответа. Спасибо!