Python新手求助:如何让BeautifulSoup未找到值时自动重试?
解决Python爬虫自动重试直到找到目标元素的问题
嘿,作为刚入门Python爬虫的新手,碰到这种“找不到元素就报错终止”的情况太正常了!咱们来把代码改成能自动重试的版本,再也不用眼睁睁看着AttributeError报错啦。
先搞懂错误原因
你遇到的'ResultSet' object has no attribute 'get'错误,大概率是用了find_all()方法(它返回的是元素列表,也就是ResultSet),然后直接对这个列表调用get()方法——这肯定不行呀!或者是用find()没找到元素,返回了None,然后你去调用get(),也会触发类似的错误。
解决方案:循环+异常捕获+重试机制
核心思路就是:一直尝试请求页面、查找元素,直到找到目标值,或者达到你设定的最大重试次数才停止。同时要处理请求失败、元素不存在等各种异常,还要加延迟避免频繁请求被网站封禁。
下面是修改后的完整代码示例:
import requests from bs4 import BeautifulSoup import time def get_target_value(url, target_selector, attribute='text', max_retries=10, retry_delay=5): retries = 0 while retries < max_retries: try: # 发送请求,记得加headers模拟浏览器,避免被反爬 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } response = requests.get(url, headers=headers) response.raise_for_status() # 如果请求失败(比如404、500),直接抛出异常 # 解析页面 soup = BeautifulSoup(response.text, 'html.parser') # 用select_one找单个元素,返回的是单个标签对象(找不到就返回None) target_element = soup.select_one(target_selector) if target_element: # 根据需求获取文本或属性 if attribute == 'text': return target_element.get_text(strip=True) else: return target_element.get(attribute) else: print(f"第{retries+1}次重试:没找到目标元素,{retry_delay}秒后再试~") retries += 1 time.sleep(retry_delay) # 捕获请求相关的异常(比如网络断了、服务器报错) except requests.exceptions.RequestException as e: print(f"请求出问题啦:{str(e)},{retry_delay}秒后重试...") retries += 1 time.sleep(retry_delay) # 捕获元素处理时的异常(比如None调用get()) except AttributeError as e: print(f"处理元素出错:{str(e)},{retry_delay}秒后重试...") retries += 1 time.sleep(retry_delay) # 超过最大重试次数,返回None print(f"已经重试了{max_retries}次,还是没找到目标值,先停啦!") return None # 调用示例,替换成你的目标网站和选择器 if __name__ == "__main__": target_url = "https://你的目标网站.com" # 比如找class为"price"的span标签的文本,或者a标签的href属性 result = get_target_value(target_url, '.price', attribute='text') if result: print(f"终于找到啦!目标值是:{result}")
几个关键细节要注意:
- 用
select_one()代替find_all():select_one()返回单个元素(找不到就返回None),不会出现ResultSet的问题;如果需要找多个元素,可以用select()然后判断列表长度是否大于0。 - 加
headers:很多网站会拦截没有User-Agent的请求,模拟浏览器的请求头能降低被封的概率。 - 设置
max_retries:别搞无限循环,不然网站崩了或者元素永久不存在,程序会一直跑下去。 retry_delay:给服务器留缓冲时间,别一秒钟请求几十次,容易被判定为爬虫封禁IP。- 如果是动态加载的内容:如果目标元素是JavaScript渲染出来的,
requests拿不到,这时候得用selenium或者playwright这类工具来模拟浏览器加载页面。
内容的提问来源于stack exchange,提问作者Sid
相关产品推荐
相关产品推荐

