2013-03-14 80 views
2

我今天在玩BeautifulSoup和Requests API。所以我想我会写一个简单的刮板,它会跟随深度为2的链接(如果有意义的话)。我所刮的网页中的所有链接都是相对的。 (例如:<a href="/free-man-aman-sethi/books/9788184001341.htm" title="A Free Man">)所以为了使它们绝对,我以为我会加入页面的网址与相关链接使用urljoinTypeError:在BeautifulSoup中使用Python进行分割时无法调用'NoneType'对象

要做到这一点,我不得不首先从<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?

回答

4

links[0]不是一个字符串,它是一个bs4.element.Tag。当你试图在其中查找split时,它会发挥它的魔力并试图找到一个名为split的子元素,但是没有。你正在调用None。

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

因为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>> 
+0

子元素,而不是属性。 – 2013-03-14 12:26:32

0

我正好遇到了同样的错误 - 所以这是非常值得四年后:如果你需要分割汤元素,你也可以在分割之前使用str()。在你的情况下,将是:

temp = str(links).split('"') 
相关问题