You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:25:44