【问题标题】:beautifulsoup and invalid html documentBeautifulsoup 和无效的 html 文档
【发布时间】:2014-04-30 17:45:36
【问题描述】:

我正在尝试解析文档http://www.consilium.europa.eu/uedocs/cms_data/docs/pressdata/en/ecofin/acf8e.htm。 我想在文档的开头获取国家和名称。

这是我的代码

import urllib
import re
from bs4 import BeautifulSoup
url="http://www.consilium.europa.eu/uedocs/cms_data/docs/pressdata/en/ecofin/acf8e.htm"
soup=BeautifulSoup(urllib.urlopen(url))
attendances_table=soup.find("table", {"width":850})
print attendances_table #this works, I see the whole table
print attendances_table.find_all("tr")

我收到以下错误:

AttributeError: 'NoneType' object has no attribute 'next_element'

然后我尝试使用与这篇文章中相同的解决方案(我再次知道,我:p): beautifulsoup with an invalid html document

我换了行:

soup=BeautifulSoup(urllib.urlopen(url))

与:

return BeautifulSoup(html, 'html.parser')

现在如果我这样做:

print attendances_table

我只得到:

<table border="0" cellpadding="10" cellspacing="0" width="850">
<tr><td valign="TOP" width="42%">
<p><b><u>Belgium</u></b></p></td></tr></table>

我应该改变什么?

【问题讨论】:

  • 不同的解析器解析不同。 lxml 对我来说很好,html5lib 也是如此。
  • html5lib 不起作用,但 lxml 似乎起作用。再次感谢 ;)。解决了
  • 是的,html5lib 树构建器创建树的方式似乎存在错误,其中有一个悬空链接(None 而不是下一个元素)。跨度>

标签: python html parsing html-parsing beautifulsoup


【解决方案1】:

使用html5lib作为解析器,非常宽松:

soup = BeautifulSoup(urllib.urlopen(url), 'html5lib')

您还需要先安装html5lib 模块。

演示:

>>> from bs4 import BeautifulSoup
>>> import urllib
>>> url = "http://www.consilium.europa.eu/uedocs/cms_data/docs/pressdata/en/ecofin/acf8e.htm"
>>> soup = BeautifulSoup(urllib.urlopen(url), 'html5lib')
>>> attendances_table = soup.find("table", {"width": 850})
>>> print attendances_table
<table border="0" cellpadding="10" cellspacing="0" width="850">
<tbody><tr><td valign="TOP" width="42%">
<p><b><u>Belgium</u></b>:</p>
<p>Mr Philippe MAYSTADT</p></td>
<td valign="TOP" width="58%">
<p>Deputy Prime Minister, Minister for Finance and Foreign Trade</p></td>
</tr>
...
<tr><td valign="TOP" width="42%">
<b><u></u></b><u></u><p><u><b>Portugal</b></u>:</p>
<p>Mr António de SOUSA FRANCO</p>
<p>Mr Fernando TEIXEIRA dos SANTOS</p></td>
<td valign="TOP" width="58%">
<p>Minister for Finance</p>
<p>State Secretary for the Treasury and Finance</p></td>
</tr>
</tbody></table>

使find_all('tr') 工作的解决方法:

>>> attendances_table = BeautifulSoup(str(attendances_table), 'html5lib')
>>> print attendances_table.find_all("tr")
[<tr><td valign="TOP" width="42%">
<p><b><u>Belgium</u></b>:</p>
<p>Mr Philippe MAYSTADT</p></td>
...
<tr><td valign="TOP" width="42%">
<b><u></u></b><u></u><p><u><b>Portugal</b></u>:</p>
<p>Mr António de SOUSA FRANCO</p>
<p>Mr Fernando TEIXEIRA dos SANTOS</p></td>
<td valign="TOP" width="58%">
<p>Minister for Finance</p>
<p>State Secretary for the Treasury and Finance</p></td>
</tr>]

【讨论】:

  • 我刚试过html5lib。 print attendances_table 有效,但 print attendances_table.find_all("tr") 无效。它对你有用吗?
  • @rom:有趣,我确实可以重现你的问题!
  • @rom 是的,这里也是,让我看看。
  • @rom 我已经发布了一个解决方法,让BeautifulSoup 再次解析它会有所帮助。看起来并不整洁漂亮,但很有效。试试看。
  • 有趣的解决方案,但实际上 Martijn 给了我一个更好的主意:使用 lxml 库。到目前为止它有效:)。无论如何,谢谢;)。
【解决方案2】:

解决了!

我刚刚使用了另一个解析器库lxml。 感谢 Martijn Pieters!

soup = BeautifulSoup(urllib.urlopen(url), 'lxml')

lxml 是唯一对我有用的库!

【讨论】:

    猜你喜欢
    • 2014-06-14
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    相关资源
    最近更新 更多