我正在使用Beautiful Soup编写一个脚本,从1999 - 2003年各个维基百科页面中删除每个温布尔登网球锦标赛的开始和结束日期。
我希望将日期范围作为可选对象的列表,我编写了一个实现此目的的脚本:
from bs4 import BeautifulSoup
import requests
import re
import os
year = 1999
url = "https://en.wikipedia.org/wiki/{tourneyYear}_Wimbledon_Championships"
range = [1, 2, 3, 4, 5,]
for number in range:
response = requests.get(url.format(tourneyYear=year))
text = response.text
soup = BeautifulSoup(text, "html.parser")
overviewTable = soup.find('table', attrs ={'class':"infobox vevent"})
date = overviewTable.find('th', attrs={"scope":"row"}).parent
specialResult = date.find('td')
for sentence in specialResult:
words = sentence.split()
print(words)
year += 1
循环遍历网页('年'每次增加1,插槽进入我已定义的网址结构 - 顺便说一下这部分工作正常)最后打印列表。
对于循环的前两次迭代(对于1999和2000 Wimbledon页面),列表打印就好了。但在第三次迭代时,它返回以下错误:
Traceback (most recent call last):
File
"XYZ", line 21, in <module>
words = sentence.split()
TypeError: 'NoneType' object is not callable
每个网页的相关部分的HTML结构是相同的(据我所知),并且循环仅在2001迭代中失败(我知道这是因为如果我将循环设置为迭代任何五年范围不包括2001,它的工作正常。)
我的代码中是否有错误,或者某些特定网页是否有所不同,我还没注意到?我在这个问题上已经绞尽脑汁待了好几天,但无济于事!
答案 0 :(得分:1)
TL; DR:您需要删除for
- 循环并使用get_text()
才能获取每个元素的文本,然后split()
:
date = overviewTable.find('th', attrs={"scope":"row"}).parent
words = date.find('th').get_text().split()
<强>解释强>
find()
不返回字符串列表,它返回单个Tag
对象。因此,specialResult
中的内容是Tag对象。
当您遍历Tag对象时,您可以获得两种类型的项:字符串(用于文本)和其他Tag对象(用于内部元素)。您的代码失败,因为specialResult
不仅包含文本,还包含子元素:
[u'25 June \u2013 9 July', <sup class="reference" id="cite_ref-info_1-0"><a href="#cite_note-info-1">[1]</a></sup>]
此处的sup
元素不是字符串,它是Tag对象,没有split()
方法,这就是您获得异常的原因。