我想使用Python从HTML文件中提取文本.如果我从浏览器复制文本并将其粘贴到记事本中,我想要的输出基本相同.
我想要比使用可能在格式不正确的HTML上失败的正则表达式更强大的东西.我见过很多人推荐Beautiful Soup,但是我使用它时遇到了一些问题.首先,它选择了不需要的文本,例如JavaScript源代码.此外,它没有解释HTML实体.例如,我希望' 在HTML源代码中转换为文本中的撇号,就像我将浏览器内容粘贴到记事本中一样.
更新 html2text
看起来很有希 它正确处理HTML实体并忽略JavaScript.但是,它并不完全产生纯文本; 它会产生降价,然后必须将其转换为纯文本.它没有示例或文档,但代码看起来很干净.
相关问题:
过滤掉HTML标签并解析python中的实体
在Python中将XML/HTML实体转换为Unicode字符串
PeYoTlL.. 129
我找到的最好的代码,用于提取文本而不需要获取javascript或不需要的东西:
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:
pip install beautifulsoup4
而不是`soup.get_text()`我使用了`soup.body.get_text()`,因此我没有从`
元素中获取任何文本,例如标题. (5认同)对于Python 3,`来自urllib.request import urlopen` (5认同)
杀戮脚本有点,救世主!! (3认同)
如果我们想要选择一些线路,只是说,第3行? (2认同)
在经历了很多stackoverflow答案之后,我觉得这对我来说是最好的选择。我遇到的一个问题是在某些情况下将行添加在一起。我可以通过在get_text函数中添加分隔符来克服它:`text = soup.get_text(separator ='')` (2认同)
RexE.. 124
html2text是一个Python程序,在这方面表现相当不错.
我找到的最好的代码,用于提取文本而不需要获取javascript或不需要的东西:
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:
pip install beautifulsoup4
html2text是一个Python程序,在这方面表现相当不错.
注意: 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)
发现自己今天面临同样的问题.我编写了一个非常简单的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''' Project: DeHTML
Description:
This small script is intended to allow conversion from HTML markup to plain text. ''' print(dehtml(text)) if __name__ == '__main__': main()
这是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 tags, converting newlines to
tags and converting confusing chars into html entities. """ def f(mo): t = mo.group() if len(t) == 1: return {'&':'&', "'":''', '"':'"', '<':'<', '>':'>'}.get(t) return '%s' % (t, t) return re.sub(r'https?://[^] ()"\';]+|[&\'"<>]', f, text)
我知道已经有很多答案,但我发现的最优雅和pythonic解决方案部分地在这里描述.
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)
您也可以在条形图库中使用html2text方法.
from stripogram import html2text text = html2text(your_html_string)
要安装条带图运行sudo easy_install条形图
有用于数据挖掘的Pattern库.
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
PyParsing做得很好.PyParsing wiki被杀了所以这里是另一个有PyParsing使用示例的位置(示例链接).投入一点时间进行pyparsing的一个原因是他还写了一篇非常简洁,非常有条理的O'Reilly Short Cut手册,价格便宜.
话虽如此,我使用BeautifulSoup并不是很难处理实体问题,你可以在运行BeautifulSoup之前转换它们.
祝好运