Pandas构造DataFrame报数组长度不一致ValueError的解决方法
报错原因
触发ValueError: All arrays must be of the same length的直接原因是传入DataFrame的两个列表长度不相等:
name列表仅追加了1次商品标题,长度固定为1specs列表遍历了MARKETING下所有规格项追加值,长度等于该页面营销规格的总条数,和name长度不匹配
另外代码里存在两处额外隐患:
- 规格遍历的
try-except写法有问题:如果某条规格不存在value键,get变量会沿用上一次循环的赋值,导致重复脏数据写入specs - 定义了
headers但没传入requests请求,极易被站点反爬拦截返回异常响应
修复方法
根据需要的存储结构二选一即可:
方案1:长表格式(每条规格对应一行,爬虫场景最常用)
每写入一条规格值,同步写入一次对应的商品标题,保证两个列表长度完全一致,同时修复异常捕获逻辑:
import requests from bs4 import BeautifulSoup import json import pandas as pd url="https://www.fleetpride.com/parts/otr-coiled-air-hose-otr6818" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.3" } # 补传headers,避免被反爬拦截 r = requests.get(url, headers=headers) soup = BeautifulSoup(r.content, "html5lib") raw_json = "" for table in soup.find_all("script"): table_str = str(table) if 'CCRZ.detailData.jsonProductData = {"' in table_str: x = table_str.split('CCRZ.detailData.jsonProductData = {"') raw_json = "{\""+str(x[-1]).split('};')[0]+"}" break # 加兜底判断,避免未匹配到脚本时解析空值 if not raw_json: raise ValueError("未提取到页面商品JSON数据") req_json = json.loads(raw_json) product_data = req_json title = product_data['product']['prodBean']['name'] marketing_specs = product_data['specifications']['MARKETING'] name_list = [] spec_list = [] for spec_item in marketing_specs: # 修复异常逻辑,缺字段直接跳过,不写入脏数据 try: spec_val = spec_item['value'] spec_list.append(spec_val) name_list.append(title) except KeyError: continue # 可加长度校验做兜底 assert len(name_list) == len(spec_list), f"数据长度不匹配,标题数:{len(name_list)},规格数:{len(spec_list)}" result_df = pd.DataFrame({'title':name_list,'Specification':spec_list}) print(result_df)
方案2:单商品单行格式
如果需要一个商品只存一行记录,把所有营销规格合并为单个字段即可,此时两个列表长度均为1,自然匹配:
# 前面的页面请求、JSON提取逻辑和方案1一致,仅替换数据组装部分 title = product_data['product']['prodBean']['name'] marketing_specs = product_data['specifications']['MARKETING'] spec_kv = {} for spec_item in marketing_specs: try: spec_kv[spec_item['name']] = spec_item['value'] except KeyError: continue # 可选择把规格字典转成换行分隔的字符串直接展示 spec_content = "\n".join([f"{k}: {v}" for k,v in spec_kv.items()]) result_df = pd.DataFrame({'title':[title],'Specification':[spec_content]}) print(result_df)
内容的提问来源于stack exchange,提问作者Amen Aziz
相关产品推荐
相关产品推荐

