use*_*140 3 python beautifulsoup web-scraping
我试图用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)
Run Code Online (Sandbox Code Playgroud)
如果我尝试运行我得到的程序,
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'
Run Code Online (Sandbox Code Playgroud)
这是python 3的问题还是我太天真了?
该find和find_all方法不搜索文档中的任意文本,他们搜索的HTML标签.文档清楚地表明了(我的斜体):
传递一个名称的值,你会告诉Beautiful Soup只考虑具有某些名称的标签.将忽略文本字符串,名称不匹配的标记也将被忽略.这是最简单的用法:
soup.find_all("title")
# [<title>The Dormouse's story</title>]
Run Code Online (Sandbox Code Playgroud)
这就是为什么你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 />
Run Code Online (Sandbox Code Playgroud)
该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)
Run Code Online (Sandbox Code Playgroud)
输出:
Steven Paul Jobs
1955-02-24
San Francisco, California, US
Run Code Online (Sandbox Code Playgroud)
PS:你不必叫read上urlopen,BS接受类文件对象.