IMDb爬虫报AttributeError及数组长度不一致ValueError求助
IMDb列表页电影爬虫两类报错排查与修复
问题复现
- 爬取目标:提取IMDb列表页250部电影的标题、上映年份、年龄分级(如PG)、IMDb评分、投票数、主演/卡司、剧情简介字段,存入pandas DataFrame
- 依赖库:
requests、BeautifulSoup4、pandas - 原有实现流程:发起目标URL请求→解析HTML响应→定位所有class为
lister-item mode-advanced的电影条目容器→完成单条目字段提取测试→初始化各字段对应的空列表→循环遍历容器提取字段追加到对应列表→传入列表生成结构化数据表
报错表现
- 第一类报错:循环运行过程中抛出
AttributeError: 'NoneType' object has no attribute 'text'触发位置:循环内提取年龄分级的代码行
age_rating = container.find('span', 'certificate').text - 第二类报错:注释年龄分级相关代码后继续运行,构建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
相关产品推荐
相关产品推荐

