我对Python很陌生,但是到底是什么......这是一个奇怪的问题所以我会尽我所能尽力解释它:
我正忙着用Python编写一个脚本来检查网页上的特定更改(基本上从0翻到1的数字)。当发生更改时,脚本将继续执行其他操作。不幸的是,我还没有达到这一点,因为我甚至在解析HTML时遇到了麻烦,因为当BeautifulSoup
获得它时,很多HTML都会丢失! (至少,这是我声称的。)
让我们一步一步:我正在使用BeautifulSoup
和Mechanize
。首先,我在网页上找到一个表单并选择它,根据需要更改表单中的控件。 (我已经验证所有控件都按照我的预期更改。)在此之后,我提交表单,然后调用我编写的名为process_results()
的辅助函数:
...
form = list(client.forms())[1]
client.select_form('ttform');
...
# Modify controls
...
client.submit()
process_results(client)
process_results()
只检查客户回来的内容。首先,根据放入表单的内容,您可以获得无效的搜索结果,因此我想搜索网页上显示的错误消息,看看它是否存在。我使用BeautifulSoup
来执行此操作:
# Processes search results.
def process_serach_results(cli):
html = cli.response().read()
soup = BeautifulSoup(html)
...
评估有问题的代码是否出现在页面上的语句如下所示:
...
if (soup.find('td', attr = {'class' : 'msgarea'}) != None):
# Do something...
...
这永远不会被评估为真,因为它找不到我正在描述的标签。我决定直接从Mechanize
和BeautifulSoup
打印出答案,这就是我得到的(缩短):
Mechanize
打印出我要找的代码,这意味着响应正确回复:
...
<TD class=msgarea>
<B class=important_msg>There was a problem with your request:</B>
<BR>
<BR>
<li class=red_msg>...</li>
...
</TD></TR></TABLE><P></DIV>
...
这是从BeautifulSoup
显示的最后一段HTML:
...
<span class="pageheaderlinks">
<a ... > MENU </a>
|
<a ... > SITE MAP </a>
|
</span></td></tr></table></div></body></html>
事实上,这是来自Mechanize
的相同HTML:
...
<SPAN class="pageheaderlinks">
<A ... >MENU</A>
|
<A ... >SITE MAP</A>
|
<--! Notice how this continues -->
<A ... >HELP</A>
|
<A ... >EXIT</A>
</span>
...
问题是BeautifulSoup
似乎忽略了Mechanize
浏览器报告的大部分HTML。这可能是我如何处理事情的问题,但在这一点上,我非常迷失。
有谁知道可能导致这种情况发生的原因?谢谢! :)
答案 0 :(得分:6)
BeautifulSoup支持a bunch of different HTML parsers。 Python的内置解析器不是非常快或宽松(意味着它很难理解无效的HTML),所以它会在你的HTML上窒息。
尝试安装lxml
,这更宽松,更快。如果这不起作用,html5lib
是你最好的选择,因为它是最宽松但也是最慢的。
答案 1 :(得分:0)
Blender的答案是正确的,但是这段代码显示了旧解析器破坏标记的严重程度,并且在寻找类似问题时可能非常有用。
# fails with bs3, works with bs4
bs3 = True
if bs3:
from BeautifulSoup import BeautifulSoup
else:
from bs4 import BeautifulSoup
mechanize = """
<TD class=msgarea>
<B class=important_msg>There was a problem with your request:</B>
<BR>
<BR>
<li class=red_msg>...</li>
</TD></TR></TABLE><P></DIV>"""
soup = BeautifulSoup(mechanize)
# the default parser worked just fine, see?
print soup.prettify()
print 'is important_msg?', soup.find('b').attrs
print 'is msgarea?', soup.find('td').attrs
print 'is td?', soup.find(class_='msgarea').name
print 'is contents?', soup.find('td', class_='msgarea').contents[:5], '...'
我花了一段时间来调试,因为bs4没有失败,所以我想我可能会拯救下一个来到这里的人。这是使用bs3的真正奇怪的输出,可以通过class
查找标记,但不能通过name
查找标记:
<td class="msgarea">
<b class="important_msg">
There was a problem with your request:
</b>
<br />
<br />
<li class="red_msg">
...
</li>
</td>
<p>
</p>
is important_msg? [(u'class', u'important_msg')]
is msgarea? [(u'class', u'msgarea')]
is td?
Traceback (most recent call last):
File "bs-fail.py", line 24, in <module>
print 'is td?', soup.find(class_='msgarea').name
AttributeError: 'NoneType' object has no attribute 'name'