原因很简单:其中之一<a>
HTML 中的标签没有href
财产。
这是重现异常的最小示例:
html = '<html><body><a>bar</a></body></html>'
soup = BeautifulSoup(html, 'html.parser')
links = soup.find_all('a', href=lambda x: ".org" in x)
# result:
# TypeError: argument of type 'NoneType' is not iterable
现在如果我们添加一个href
属性,异常消失:
html = '<html><body><a href="foo.org">bar</a></body></html>'
soup = BeautifulSoup(html, 'html.parser')
links = soup.find_all('a', href=lambda x: ".org" in x)
# result:
# [<a href="foo.org">bar</a>]
发生的情况是 BeautifulSoup 正在尝试访问<a>
tag's href
财产,并返回None
当该属性不存在时:
html = '<html><body><a>bar</a></body></html>'
soup = BeautifulSoup(html, 'html.parser')
print(soup.a.get('href'))
# output: None
这就是为什么有必要允许None
lambda 中的值。自从None
是一个假值,代码x and ...
防止右侧and
语句从何时执行x
is None
,正如您在这里看到的:
>>> None and 1/0
>>> 'foo.org' and 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
这就是所谓的短路 https://docs.python.org/3/library/stdtypes.html#boolean-operations-and-or-not.
也就是说,x and ...
检查真实性x
, and None
并不是唯一被认为是虚假的值。所以比较一下会更正确x
to None
像这样:
lambda x: x is not None and ".org" in x