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

使用BeautifulSoup爬取IMDB用户会员年限出现IndexError怎么解决?

问题根源

  • 核心触发原因是IMDB的反爬机制:批量高频请求时,平台会直接返回拦截页面(验证码/403拒绝访问页),这类页面不存在你要匹配的div.value元素,导致find_all返回空列表,取[-1]时直接触发索引越界。单次请求因为频率低未触发反爬,所以偶尔能正常返回结果。
  • 次要潜在问题:部分用户页面可能无对应徽章、html.parser解析容错性不足、请求头配置过于简单也可能导致匹配失败。

修复方案

  1. 先做基础合法性校验:先判断请求状态码是否为200,再判断匹配到的元素列表是否非空,异常情况统一返回占位标记(比如None/'未知')避免程序直接崩溃。
  2. 批量请求时增加随机延迟:每次请求间隔1-3秒,降低触发反爬的概率。
  3. 完善请求头配置,使用requests.Session维持会话上下文,模拟真实浏览器访问行为。
  4. 可替换为容错性更高的lxml解析器(需提前安装lxml库)。

修复后代码示例

单个抓取函数修改

import requests
import time
import random
from bs4 import BeautifulSoup

# 初始化会话复用,减少被识别概率
session = requests.Session()
session.headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Referer': 'https://www.imdb.com/'
})

def getYear(review_url):
    try:
        # 随机延迟,也可以放到批量调用逻辑中调整
        time.sleep(random.uniform(1, 3))
        response = session.get(review_url, timeout=10)
        # 先校验请求是否成功
        if response.status_code != 200:
            return '请求失败'
        # 用lxml解析,容错性更高
        soup = BeautifulSoup(response.text, 'lxml')
        year_list = soup.find_all('div', attrs={'class': 'value'})
        #  列表非空再取值
        if year_list:
            return year_list[-1].get_text().strip()
        else:
            return '无匹配数据'
    except Exception as e:
        # 捕获所有异常避免批量调用中断
        return f'异常:{str(e)}'

批量调用逻辑

可以保留原有写法,返回的列表里会自动标记失败的条目,后续可以单独对异常条目重试:

years = [getYear(url) for url in user_links]

如果后续反爬严格到返回验证码,可以额外配置代理池或者使用无头浏览器抓取。

内容的提问来源于stack exchange,提问作者Malvi Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 19:45:03