BeautifulSoup无法解析网页?

JLT*_*hiu 5 python parsing beautifulsoup

我现在正在使用美丽的汤来解析网页,我听说它很有名,很好,但看起来效果不好.

这就是我做的

import urllib2
from bs4 import BeautifulSoup

page = urllib2.urlopen("http://www.cnn.com/2012/10/14/us/skydiver-record-attempt/index.html?hpt=hp_t1")
soup = BeautifulSoup(page)
print soup.prettify()
Run Code Online (Sandbox Code Playgroud)

我觉得这很简单.我打开网页并将其传递给beautifulsoup.但这就是我得到的:

Warning (from warnings module):

File "C:\Python27\lib\site-packages\bs4\builder\_htmlparser.py", line 149

"Python's built-in HTMLParser cannot parse the given document. This is not a bug in Beautiful Soup. The best solution is to install an external parser (lxml or html5lib), and use Beautiful Soup with that parser. See http://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser for help."))

...

HTMLParseError: bad end tag: u'</"+"script>', at line 634, column 94

我认为CNN网站应该设计得很好,所以我不太清楚会发生什么.有没有人对此有所了解?

jfs*_*jfs 10

来自文档:

如果可以的话,我建议你安装并使用lxml来提高速度.如果您使用的是早于2.7.3的Python 2版本,或者早于3.2.2的Python 3版本,则必须安装lxml或html5lib-Python的内置HTML解析器在旧版本中不是很好版本.

如果在Python 2.7上安装更强大的解析器(例如lxml或html5lib),您的代码将按原样(在Python 2.7,Python 3.3上)工作:

try:
    from urllib2 import urlopen
except ImportError:
    from urllib.request import urlopen # py3k

from bs4 import BeautifulSoup # $ pip install beautifulsoup4

url = "http://www.cnn.com/2012/10/14/us/skydiver-record-attempt/index.html?hpt=hp_t1"
soup = BeautifulSoup(urlopen(url))
print(soup.prettify())
Run Code Online (Sandbox Code Playgroud)

HTMLParser.py - 更强大的SCRIPT标记解析错误可能是相关的.


And*_*Ray 8

您不能使用BeautifulSoup或任何HTML解析器来阅读网页.您永远不能保证网页是一个格式良好的文档.让我解释一下这个案例中发生的事情.

在该页面上有这个INLINE javascript:

var str="<script src='http://widgets.outbrain.com/outbrainWidget.js'; type='text/javascript'></"+"script>";
Run Code Online (Sandbox Code Playgroud)

您可以看到它正在创建一个将脚本标记放到页面上的字符串.现在,如果你是一个HTML解析器,这是一个非常棘手的事情.当你突然碰到<script>标签时,你会继续读取你的标记.不幸的是,如果你这样做了:

<script>
alert('hello');
<script>
alert('goodby');
Run Code Online (Sandbox Code Playgroud)

大多数解析器会说:好的,我找到了一个开放的脚本标签.哦,我找到了另一个开放的脚本标签!他们一定忘了关闭第一个!并且解析器会认为两者都是有效的脚本.

因此,在这种情况下,BeautifulSoup会看到一个<script>标记,即使它在javascript字符串中,看起来它可能是一个有效的起始标记,而且BeautifulSoup也有它的癫痫发作.

如果再看一下这个字符串,你可以看到他们做了这个有趣的工作:

... "</" + "script>";
Run Code Online (Sandbox Code Playgroud)

这看起来很奇怪吗?str = " ... </script>"如果不做额外的字符串连接就不是更好吗?这实际上是一个常见的技巧(愚蠢的人将脚本标记写为字符串,这是一种不好的做法),使解析器不会中断.因为如果你这样做:

var a = '</script>';
Run Code Online (Sandbox Code Playgroud)

在内联脚本中,解析器将出现,并且只是看到</script>并认为整个脚本标记已经结束,并将该脚本标记的其余内容作为纯文本抛出到页面上.这是因为即使您的JS语法无效,您也可以在技术上将关闭脚本标记放在任何位置.从解析器的角度来看,最好早点退出脚本标记,而不是尝试将html代码渲染为javascript.

因此,您无法使用常规HTML解析器来解析网页.这是一场非常非常危险的比赛.无法保证您将获得格式良好的HTML.根据您要执行的操作,您可以使用正则表达式阅读页面内容,或尝试使用无头浏览器获取完全呈现的页面内容

  • *"你不能使用任何HTML解析器来阅读网页"* - 我认为这是一个错误的陈述.Web浏览器就是这样做的,他们使用一个发展良好的HTML解析器来解析网页的内容.当然,他们在它上面添加了更多的功能,评估脚本和所有的东西,但他们仍然首先解析基本HTML.在这种情况下,内置的解析器似乎不足以接受特定的HTML(虽然它对我和Vor也可以正常工作),因此需要一个更强大的解析器.它仍然是一个HTML解析器. (2认同)