【问题标题】:Python: AttributeError: 'NoneType' object has no attribute 'findNext'Python:AttributeError:“NoneType”对象没有属性“findNext”
【发布时间】:2014-01-29 03:24:35
【问题描述】:

我正在尝试使用 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 的问题还是我太天真了?

【问题讨论】:

  • 你确定不想要body = soup.find('body')

标签: python web-scraping beautifulsoup


【解决方案1】:

findfind_all 方法不会搜索文档中的任意文本,它们会搜索 HTML 标记。 文档说明了这一点(我的斜体):


为 name 传递一个值,你会告诉 Beautiful Soup 只考虑具有特定名称的 标签。文本字符串将被忽略,名称不匹配的标签也会被忽略。这是最简单的用法:

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

这就是为什么你的soup.find("Born") 会返回None 以及为什么它抱怨NoneTypeNone 的类型)没有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 />
</td>

【讨论】:

  • 如果您确实想在 html 文件中找到一些任意文本怎么办?
  • @user391339,虽然最初的问题没有要求,但您可以在字符串化的汤上使用常规的 Python 字符串搜索功能(例如,字符串 find 或正则表达式 search) doc,漂亮或不漂亮:crummy.com/software/BeautifulSoup/bs4/doc/#pretty-printing
【解决方案2】:

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 接受类似文件的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    • 2016-06-26
    • 2016-11-08
    • 2014-04-26
    • 2021-01-15
    • 2020-03-09
    相关资源
    最近更新 更多