我正在尝试使用BeautifulSoup抓取一个网站,但我遇到了问题。 我正在按照python 2.7中的教程进行操作,它中的代码完全相同,没有任何问题。
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 :(得分:8)
find
和find_all
方法不会在文档中搜索任意文本,而是搜索 HTML标记。文档清楚地表明了这一点(我的斜体):< / p>
传递一个名称值,你会告诉Beautiful Soup只考虑具有某些名称的标签。将忽略文本字符串,名称不匹配的标记也将被忽略。这是最简单的用法:
soup.find_all("title")
# [<title>The Dormouse's story</title>]
这就是您的soup.find("Born")
返回None
的原因,以及为什么它抱怨NoneType
(None
的类型)没有findNext()
方法。
您引用的页面包含(在撰写本答案时)“生日”一词的八个副本,其中没有一个是标签。
查看该页面的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 />
答案 1 :(得分:6)
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:您不必在read
上拨打urlopen
,BS接受类似文件的对象。