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

IMDb爬虫报AttributeError及数组长度不一致ValueError求助

IMDb列表页电影爬虫两类报错排查与修复

问题复现

  • 爬取目标:提取IMDb列表页250部电影的标题、上映年份、年龄分级(如PG)、IMDb评分、投票数、主演/卡司、剧情简介字段,存入pandas DataFrame
  • 依赖库:requests、BeautifulSoup4、pandas
  • 原有实现流程:发起目标URL请求→解析HTML响应→定位所有class为lister-item mode-advanced的电影条目容器→完成单条目字段提取测试→初始化各字段对应的空列表→循环遍历容器提取字段追加到对应列表→传入列表生成结构化数据表

报错表现

  1. 第一类报错:循环运行过程中抛出AttributeError: 'NoneType' object has no attribute 'text'

    触发位置:循环内提取年龄分级的代码行 age_rating = container.find('span', 'certificate').text

  2. 第二类报错:注释年龄分级相关代码后继续运行,构建DataFrame时抛出ValueError: All arrays must be of the same length

    长度校验结果:通过len()打印各字段存储列表的长度,输出为250 8 250 250 6 0 250,其中电影标题、电影类型、IMDb评分、剧情简介的列表长度为250,和单页250部电影的数量匹配;但上映年份列表长度仅8、投票数列表长度仅6、主演卡司列表长度为0,手动核查IMDb页面确认每部电影均存在这三类信息。

根因说明

  • AttributeError触发原因:BeautifulSoup.find()方法在当前节点下匹配不到目标标签时,会直接返回None,对None调用.text属性必然触发属性不存在的报错。IMDb列表页的certificate年龄分级标签不是所有条目都会渲染:未上映、未分级、对应展示地区无分级标识的条目下不存在该span节点,直接链式调用.text就会触发报错。
  • 列表长度不匹配触发原因:
    • 上映年份、投票数、卡司三个字段的提取逻辑没有基于单个电影容器做相对查找,大概率是直接在全局页面解析结果上做匹配,或者标签class、层级选择规则写错,只能抓到页面零散的几个对应元素,卡司字段的选择器完全不匹配所以返回空列表
    • 所有字段提取都没有做缺失值兜底逻辑,匹配不到元素时没有执行列表追加操作直接跳过,最终导致列表长度和实际电影条目数不一致

修复方案

  • 所有字段提取增加非空判断,统一做缺失值兜底
    任何find()返回结果先判断是否存在,再提取属性或文本,匹配不到时向对应列表追加None/空值,既避免AttributeError,也保证每个列表长度和条目数一致。年龄分级修复示例:
    cert_node = container.find('span', class_='certificate')
    age_rating = cert_node.text.strip() if cert_node else None
    age_rating_list.append(age_rating)
    
  • 修正三个异常字段的选择器,确保基于单个container做相对查找,不要全局搜索
    三个字段的正确提取逻辑参考:
    # 上映年份:匹配条目下的年份专属span
    year_node = container.find('span', class_='lister-item-year text-muted unbold')
    release_year = year_node.text.strip() if year_node else None
    year_list.append(release_year)
    
    # 投票数:匹配带name=nv属性的投票数据节点
    vote_node = container.find('span', attrs={'name': 'nv'})
    vote_count = vote_node.get('data-value') if vote_node else None
    vote_list.append(vote_count)
    
    # 主演卡司:匹配条目下无class的演职员文本段,提取Stars:后的链接文本
    cast_block = container.find('p', class_='')
    cast = []
    if cast_block:
        block_text = cast_block.text
        if 'Stars:' in block_text:
            star_links = cast_block.find_all('a')
            cast = [a.text.strip() for a in star_links]
    cast_list.append(cast)
    
  • 增加循环内长度校验
    每处理完一个电影容器,打印一次各列表的长度,确认每个列表每轮都成功追加1个值,避免漏写append语句导致的长度异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:54:19