我正在使用BeautifulSoup
来解析一堆可能非常脏的HTML
文档。我偶然发现了一件非常奇怪的事情。
HTML来自此页面:http://www.wvdnr.gov/
它包含多个错误,例如<html></html>
之外的多个<title>
,<head>
等等。
然而,即使在这些情况下,html5lib通常也能正常工作。事实上,当我这样做时:
soup = BeautifulSoup(document, "html5lib")
我预先打印soup
,我看到以下输出:http://pastebin.com/8BKapx88
包含大量<a>
标记。
然而,当我soup.find_all("a")
时,我得到一个空列表。使用lxml
我会得到同样的结果。
所以:以前有人偶然发现了这个问题吗?到底是怎么回事?如何获取html5lib
找到但未使用find_all
返回的链接?
答案 0 :(得分:4)
即使正确的答案是“使用另一个解析器”(感谢@alecxe),我还有另一种解决方法。出于某种原因,这也有效:
soup = BeautifulSoup(document, "html5lib")
soup = BeautifulSoup(soup.prettify(), "html5lib")
print soup.find_all('a')
返回相同的链接列表:
soup = BeautifulSoup(document, "html.parser")
答案 1 :(得分:3)
在解析格式不健全的HTML时,the parser choice非常重要:
HTML解析器之间也存在差异。如果你给美丽 汤是一个完美形成的HTML文档,这些差异无关紧要。 一个解析器会比另一个解析器更快,但他们都会给你一个 数据结构看起来与原始HTML文档完全相同。
但是如果文档没有完美形成,不同的解析器会 给出不同的结果。
html.parser
为我工作:
from bs4 import BeautifulSoup
import requests
document = requests.get('http://www.wvdnr.gov/').content
soup = BeautifulSoup(document, "html.parser")
print soup.find_all('a')
演示:
>>> from bs4 import BeautifulSoup
>>> import requests
>>> document = requests.get('http://www.wvdnr.gov/').content
>>>
>>> soup = BeautifulSoup(document, "html5lib")
>>> len(soup.find_all('a'))
0
>>> soup = BeautifulSoup(document, "lxml")
>>> len(soup.find_all('a'))
0
>>> soup = BeautifulSoup(document, "html.parser")
>>> len(soup.find_all('a'))
147
另见: