【问题标题】:Cannot convert HTML from a site to text properly无法将网站中的 HTML 正确转换为文本
【发布时间】:2014-02-28 10:03:11
【问题描述】:

编辑:我不敢相信 BeautifullSoup 实际上无法正确解析 HTML。实际上我可能做错了什么,但如果我不这样做,这是一个非常业余的模块。

我正在尝试从网络上获取文本,但我无法这样做,因为我总是在大多数句子中得到一些奇怪的字符。我从来没有得到一个包含诸如“不正确”之类的词的句子。

useragent = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11'}
request = urllib2.Request('SomeURL',None,useragent)
myreq = urllib2.urlopen(request, timeout = 5)
html = myreq.read()

#get paragraphs
soup = BeautifulSoup(html)
textList = soup.find_all('p')
mytext = ""
for par in textList:
    if len(str(par))<2000: 
    print par
    mytext +=" " +  str(par)

 print "the text is ", mytext

结果包含一些奇怪的字符:

The plural of “comedo� is comedomes�.</p>
Surprisingly, the visible black head isn’t caused by dirt

显然我想得到不是而不是不是。我该怎么办?

【问题讨论】:

  • 这不是重复的。我首先需要提取所有段落。我认为解码会删除所有

    标签。

  • 我现在需要告诉 beautifullsoup 来毁掉我的 html。我不敢相信这样一个有信誉的 python 模块不能正确解析 html。

标签: python python-2.7 text web-scraping beautifulsoup


【解决方案1】:

我认为问题在于您的系统输出编码,它无法正确输出编码字符,因为它超出了显示的字符范围。

BeautifulSoup4 旨在完全支持 HTML 实体。

注意这些命令的奇怪行为:

>python temp.py
...
ed a blackhead. The plural of ÔÇ£comedoÔÇØ is comedomesÔÇØ.</p>
...

>python temp.py > temp.txt

>cat temp.txt
....
ed a blackhead. The plural of "comedo" is comedomes".</p> <p> </p> <p>Blackheads is an open and wide
....

我建议将您的输出写入文本文件,或者使用不同的终端/更改终端设置以支持更广泛的字符。

【讨论】:

  • 我仍然得到 - “喜剧”?是喜剧演员吗? - 你用过 python 2.7 吗?
  • 我的 python 搞砸了,我不断得到不同的输出。你能告诉我你有哪些版本的python和beautifulsoup吗?
  • 是python 2.7.3和bs4
  • 我之前看到了这些字符,但是现在当我尝试运行您的代码时,我再也看不到它们了。仍在试图弄清楚发生了什么
  • 你从哪里运行 Python?经过测试,我认为是你的字符编码有问题。
【解决方案2】:

由于这是 Python 2,urllib.urlopen().read() 调用返回最有可能以 UTF-8 编码的字节字符串 - 如果特别包含,您可以查看 HTTP 标头以查看编码。我假设是 UTF-8。

您在开始处理内容之前未能解码此外部表示,这只会导致眼泪。一般规则:立即解码输入,仅在输出时编码。

这是您的工作形式的代码,只有两个修改;

import urllib2
from BeautifulSoup import BeautifulSoup

useragent = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11'}
request = urllib2.Request('SomeURL',None,useragent)
myreq = urllib2.urlopen(request, timeout = 5)
html = unicode(myreq.read(), "UTF-8")

#get paragraphs
soup = BeautifulSoup(html)
textList = soup.findAll('p')
mytext = ""
for par in textList:
    if len(str(par))<2000: 
      print par
      mytext +=" " +  str(par)

print "the text is ", mytext

我所做的只是添加了 html 的 unicode 解码并使用 soup.findAll() 而不是 soup.find_all()

【讨论】:

  • 我试过了,我也看到了。如何查看 http 标头?
  • 相当奇怪。当我运行上面的代码时,我看到的 HTML 包含 The plural of &amp;#8220;comedo&amp;#8221; is comedomes&amp;#8221;. - 也就是说,左右引号已被正确处理。使用myreq.headers.headers 访问标题。我没有看到太多价值,但确实确认您正在处理 UTF-8 流。内容似乎缺少一个左引号。
  • 是的,正如我所见,它是 charset=UTF-8。没关系,我添加了适合我的解决方案。我使用 bs4,它可能会做一些奇怪的事情。
【解决方案3】:

这是基于人们在这里的回答和我的研究得出的解决方案。

import html2text
import urllib2
import re
import nltk

useragent = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11'}
request = urllib2.Request('SomeURL',None,useragent)
myreq = urllib2.urlopen(request, timeout = 5)
html = myreq.read()
html = html.decode("utf-8")


textList = re.findall(r'(?<=<p>).*?(?=</p>)',html, re.MULTILINE|re.DOTALL)
mytext = ""
for par in textList:
   if len(str(par))<2000: 
    par = re.sub('<[^<]+?>', '', par)
    mytext +=" " +  html2text.html2text(par)

 print "the text is ", mytext

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 2020-10-08
    • 1970-01-01
    • 2015-03-01
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    相关资源
    最近更新 更多