我今天正在玩BeautifulSoup和Requests API。所以我想我会写一个简单的刮刀,它会跟随深度为2的链接(如果这是有道理的)。我正在抓取的网页中的所有链接都是相对的。 (例如:<a href="/free-man-aman-sethi/books/9788184001341.htm" title="A Free Man">
)所以为了使它们绝对,我想我会使用urljoin
加入带有相对链接的页面URL。
要做到这一点,我必须首先从<a>
标签中提取href值,为此我认为我会使用split
:
#!/bin/python
#crawl.py
import requests
from bs4 import BeautifulSoup
from urlparse import urljoin
html_source=requests.get("http://www.flipkart.com/books")
soup=BeautifulSoup(html_source.content)
links=soup.find_all("a")
temp=links[0].split('"')
这会出现以下错误:
Traceback (most recent call last):
File "test.py", line 10, in <module>
temp=links[0].split('"')
TypeError: 'NoneType' object is not callable
在正确浏览文档之前潜入水中,我意识到这可能不是实现目标的最佳方法,但为什么会出现TypeError?
答案 0 :(得分:5)
links[0]
不是字符串,而是bs4.element.Tag
。当您尝试在其中查找split
时,它会发挥其魔力,并尝试查找名为split
的子元素,但没有。你称之为无。
In [10]: l = links[0]
In [11]: type(l)
Out[11]: bs4.element.Tag
In [17]: print l.split
None
In [18]: None() # :)
TypeError: 'NoneType' object is not callable
使用索引查找HTML属性:
In [21]: links[0]['href']
Out[21]: '/?ref=1591d2c3-5613-4592-a245-ca34cbd29008&_pop=brdcrumb'
或get
如果存在不存在属性的危险:
In [24]: links[0].get('href')
Out[24]: '/?ref=1591d2c3-5613-4592-a245-ca34cbd29008&_pop=brdcrumb'
In [26]: print links[0].get('wharrgarbl')
None
In [27]: print links[0]['wharrgarbl']
KeyError: 'wharrgarbl'
答案 1 :(得分:1)
因为Tag
类使用代理来访问属性(正如Pavel指出的那样 - 这用于在可能的情况下访问子元素),所以如果找不到它,则会返回None
默认值。
令人费解的例子:
>>> print soup.find_all('a')[0].bob
None
>>> print soup.find_all('a')[0].foobar
None
>>> print soup.find_all('a')[0].split
None
您需要使用:
soup.find_all('a')[0].get('href')
其中:
>>> print soup.find_all('a')[0].get
<bound method Tag.get of <a href="test"></a>>
答案 2 :(得分:0)
我刚刚遇到了同样的错误 - 所以四年之后的价值也是如此:如果你需要拆分汤元素,你也可以在拆分它之前使用str()。在你的情况下:
temp = str(links).split('"')