2014-01-29 157 views
2

我试图用BeautifulSoup刮一个网站,但我有一个问题。 我在Python 2.7中完成了一个教程,它有完全相同的代码,并没有问题。Python:AttributeError:'NoneType'对象没有属性'findNext'

import urllib.request 
from bs4 import * 


htmlfile = urllib.request.urlopen("http://en.wikipedia.org/wiki/Steve_Jobs") 

htmltext = htmlfile.read() 

soup = BeautifulSoup(htmltext) 
title = (soup.title.text) 

body = soup.find("Born").findNext('td') 
print (body.text) 

如果我尝试运行该程序,我得到,

Traceback (most recent call last): 
    File "C:\Users\USER\Documents\Python Programs\World Population.py", line 13, in <module> 
    body = soup.find("Born").findNext('p') 
AttributeError: 'NoneType' object has no attribute 'findNext' 

这是与Python 3有问题还是我太天真?

+0

你确定你不想'body = soup.find('body')'? –

回答

7

findfind_all方法不搜索文档中的任意文本,它们搜索HTML标签。文档使得清楚了(我的斜体字):


通行证在name的值,你会告诉美丽的汤只考虑标签某些名称。文本字符串将被忽略,标签的名称不匹配。这是最简单的用法:没有findNext()方法

soup.find_all("title") 
# [<title>The Dormouse's story</title>] 

这就是为什么你soup.find("Born")将返回None,因此它为什么抱怨NoneType(的None类型)。

您引用的那个页面包含(在写这个答案的时候)单词“born”的八个副本,其中没有一个是标签。

查看HTML源为网页,你会找到最好的选择可能是寻找正确的跨度:

<th scope="row" style="text-align:left;">Born</th> 
    <td><span class="nickname">Steven Paul Jobs</span><br /> 
    <span style="display:none">(<span class="bday">1955-02-24</span>)</span>February 24, 1955<br /> 
+0

如果你想在html文件中找到一些任意文本,该怎么办? – user391339

+0

@ user391339,虽然原来的问题没有要求,但您可以在字符串化的汤doc上使用常规的Python字符串搜索功能(例如,字符串“find”或正则表达式搜索)漂亮:https://www.crummy.com/software/BeautifulSoup/bs4/doc/#pretty-printing – paxdiablo

5

find方法寻找标记,而不是文字。要查找姓名,生日和出生地,你将不得不抬头看span元素与相应的类名,并访问text属性,该属性物品:

import urllib.request 
from bs4 import * 


soup = BeautifulSoup(urllib.request.urlopen("http://en.wikipedia.org/wiki/Steve_Jobs")) 
title = soup.title.text 
name = soup.find('span', {'class': 'nickname'}).text 
bday = soup.find('span', {'class': 'bday'}).text 
birthplace = soup.find('span', {'class': 'birthplace'}).text 

print(name) 
print(bday) 
print(birthplace) 

输出:

Steven Paul Jobs 
1955-02-24 
San Francisco, California, US 

PS :您不必在urlopen上拨打read,BS接受类似文件的对象。

+1

为了多走一英里,实际给出了代码,这让我不能打扰:-) – paxdiablo