如何解决HLTV爬虫中NoneType对象无find_all属性的问题?
嘿,我来帮你搞定这个问题!你的核心问题其实很清晰:当上午10点前没有直播赛事时,soup.find('div', class_='live-matches')会返回None,这时候你直接去调用.find_all('a'),自然会触发那个烦人的'NoneType' object has no attribute find_all('a')错误——你之前写的if links is None: pass完全没用到点子上,因为links是循环里的变量,错误早在循环开始前就发生了。
下面给你两个靠谱的解决方案:
方案1:先检查直播容器是否存在
最稳妥的方式是先把live-matches这个容器拿到手,确认它不是None之后再去查找链接,这样从根源上避免错误:
from bs4 import BeautifulSoup import requests, datetime matchlinks_lm = [] r = requests.get('https://hltv.org/matches') sauce = r.content soup = BeautifulSoup(sauce, 'lxml') # 先获取直播容器,判断是否存在 live_matches_div = soup.find('div', class_='live-matches') if live_matches_div is not None: for links in live_matches_div.find_all('a'): matchlinks_lm.append('https://hltv.org' + links.get('href')) else: # 没有直播时可以加个提示,或者做其他处理 print("当前没有正在进行的直播赛事哦")
方案2:正确使用try-except捕获异常
你之前用try-except陷入循环,大概率是因为把整个请求+解析逻辑都套在了try块里,而且没处理循环退出的条件。正确的做法是把可能出错的那行代码单独放在try块中,精准捕获AttributeError:
from bs4 import BeautifulSoup import requests, datetime matchlinks_lm = [] r = requests.get('https://hltv.org/matches') sauce = r.content soup = BeautifulSoup(sauce, 'lxml') try: # 这一行是可能抛出错误的地方,单独放在try里 live_matches_links = soup.find('div', class_='live-matches').find_all('a') for links in live_matches_links: matchlinks_lm.append('https://hltv.org' + links.get('href')) except AttributeError: print("当前没有正在进行的直播赛事哦") # 要是需要空列表,直接赋值就行 matchlinks_lm = []
为啥之前的if links is None: pass没用?
简单说,links是你循环里的变量,当soup.find('div', class_='live-matches')返回None时,代码根本到不了循环那一步——错误发生在调用.find_all('a')的瞬间,这时候links甚至都还没被定义呢。
另外,如果你之前的try-except导致重复循环,建议检查你的代码结构:是不是把整个抓取逻辑放在了无限循环里,异常触发后又没跳出循环的逻辑?如果是定时抓取的场景,不如用time.sleep()来控制抓取间隔,比靠异常触发循环靠谱多了。
内容的提问来源于stack exchange,提问作者user5743273

