Joh*_*ook 222 html python text html-content-extraction
我想使用Python从HTML文件中提取文本.如果我从浏览器复制文本并将其粘贴到记事本中,我想要的输出基本相同.
我想要比使用可能在格式不正确的HTML上失败的正则表达式更强大的东西.我见过很多人推荐Beautiful Soup,但是我使用它时遇到了一些问题.首先,它选择了不需要的文本,例如JavaScript源代码.此外,它没有解释HTML实体.例如,我希望' 在HTML源代码中转换为文本中的撇号,就像我将浏览器内容粘贴到记事本中一样.
更新 html2text看起来很有希 它正确处理HTML实体并忽略JavaScript.但是,它并不完全产生纯文本; 它会产生降价,然后必须将其转换为纯文本.它没有示例或文档,但代码看起来很干净.
相关问题:
PeY*_*TlL 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)
Run Code Online (Sandbox Code Playgroud)
你必须先安装BeautifulSoup:
pip install beautifulsoup4
Run Code Online (Sandbox Code Playgroud)
Rex*_*exE 124
html2text是一个Python程序,在这方面表现相当不错.
Sha*_*atu 98
注意: 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)
Run Code Online (Sandbox Code Playgroud)
xpe*_*oni 53
发现自己今天面临同样的问题.我编写了一个非常简单的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()
Run Code Online (Sandbox Code Playgroud)
小智 14
这是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 {'&':'&', "'":''', '"':'"', '<':'<', '>':'>'}.get(t)
return '<a href="%s">%s</a>' % (t, t)
return re.sub(r'https?://[^] ()"\';]+|[&\'"<>]', f, text)
Run Code Online (Sandbox Code Playgroud)
我知道已经有很多答案,但我发现的最优雅和pythonic解决方案部分地在这里描述.
from bs4 import BeautifulSoup
text = ''.join(BeautifulSoup(some_html_string, "html.parser").findAll(text=True))
Run Code Online (Sandbox Code Playgroud)
根据弗雷泽的评论,这里是更优雅的解决方案:
from bs4 import BeautifulSoup
clean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings)
Run Code Online (Sandbox Code Playgroud)
您也可以在条形图库中使用html2text方法.
from stripogram import html2text
text = html2text(your_html_string)
Run Code Online (Sandbox Code Playgroud)
要安装条带图运行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
Run Code Online (Sandbox Code Playgroud)
小智 7
我知道这里已经有很多答案了,但我认为news3k也值得一提。我最近需要完成一项从网络文章中提取文本的类似任务,到目前为止,这个库在我的测试中做得非常出色。它忽略菜单项和侧边栏中的文本以及作为 OP 请求出现在页面上的任何 JavaScript。
from newspaper import Article
article = Article(url)
article.download()
article.parse()
article.text
Run Code Online (Sandbox Code Playgroud)
如果您已经下载了 HTML 文件,您可以执行以下操作:
article = Article('')
article.set_html(html)
article.parse()
article.text
Run Code Online (Sandbox Code Playgroud)
它甚至还有一些 NLP 功能用于总结文章的主题:
article.nlp()
article.summary
Run Code Online (Sandbox Code Playgroud)
如果您需要更快的速度和更低的准确性,那么您可以使用原始 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()
Run Code Online (Sandbox Code Playgroud)
这不完全是一个 Python 解决方案,但它会将 Javascript 生成的文本转换为文本,我认为这很重要(EG google.com)。浏览器 Links(不是 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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
316306 次 |
| 最近记录: |