我有Python 2.7.3和bs。版本是4.4.1
由于某种原因,此代码
from bs4 import BeautifulSoup # parsing
html = """
<html>
<head id="Head1"><title>Title</title></head>
<body>
<form id="form" action="login.php" method="post">
<input type="text" name="fname">
<input type="text" name="email" >
<input type="button" name="Submit" value="submit">
</form>
</body>
</html>
"""
html_proc = BeautifulSoup(html, 'html.parser')
for form in html_proc.find_all('form'):
for input in form.find_all('input'):
print "input:" + str(input)
返回错误的输入列表:
input:<input name="fname" type="text">
<input name="email" type="text">
<input name="Submit" type="button" value="submit">
</input></input></input>
input:<input name="email" type="text">
<input name="Submit" type="button" value="submit">
</input></input>
input:<input name="Submit" type="button" value="submit">
</input>
它应该返回
input: <input name="fname" type="text">
input: <input type="text" name="email">
input: <input type="button" name="Submit" value="submit">
发生什么事了?
答案 0 :(得分:2)
对我而言,这看起来像是html解析器的工件。将'lxml'
用于解析器而不是'html.parser'
似乎可以使其正常工作。这样做的缺点是您(或您的用户)需要安装lxml
- 好处是lxml
是更好/更快的解析器; - )。
至于为什么 'html.parser'
在这种情况下似乎无法正常工作,我认为它与input
标签是自我的事实有关-closing。如果明确关闭输入,则可以正常工作:
<input type="text" name="fname" ></input>
<input type="text" name="email" ></input>
<input type="button" name="Submit" value="submit" ></input>
我很想知道我们是否可以修改源代码来处理这种情况......对猴子补丁bs4
做一点实验表明我们可以这样做:
from bs4 import BeautifulSoup
from bs4.builder import _htmlparser
# Monkey-patch the Beautiful soup HTML parser to close input tags automatically.
BeautifulSoupHTMLParser = _htmlparser.BeautifulSoupHTMLParser
class FixedParser(BeautifulSoupHTMLParser):
def handle_starttag(self, name, attrs):
# Old-style class... No super :-(
result = BeautifulSoupHTMLParser.handle_starttag(self, name, attrs)
if name.lower() == 'input':
self.handle_endtag(name)
return result
_htmlparser.BeautifulSoupHTMLParser = FixedParser
html = """
<html>
<head id="Head1"><title>Title</title></head>
<body>
<form id="form" action="login.php" method="post">
<input type="text" name="fname" >
<input type="text" name="email" >
<input type="button" name="Submit" value="submit" >
</form>
</body>
</html>
"""
html_proc = BeautifulSoup(html, 'html.parser')
for form in html_proc.find_all('form'):
for input in form.find_all('input'):
print "input:" + str(input)
显然,这不是真正的修复(我不会将其作为补丁提交给BS4人员),但它确实证明了这个问题。由于没有结束标记,因此永远不会调用handle_endtag
方法。如果我们自己调用它,事情往往会解决(只要html不 也有关闭输入标记......)。
我不确定这个bug的责任应该是什么,但我想你可以先将它提交给bs4 - 然后他们可能会转发你报告python跟踪器上的错误,我&#39 ;我不确定......
答案 1 :(得分:0)
不要使用嵌套循环并使用lxml
,将代码更改为:
inp = []
html_proc = BeautifulSoup(html, 'lxml')
for form in html_proc.find_all('form'):
inp.extend(form.find_all('input'))
for item in inp:
print "input:" + str(item)