Python亚马逊爬虫代码返回None及ValueError数组形状错误如何解决?
问题触发原因
1. ValueError: could not broadcast input array from shape (0,) into shape (1,) 报错
- 直接将BeautifulSoup的
Tag对象(代码里的each.i)存入字典,构建DataFrame时,Tag对象会被解析为数组结构,若Tag为空就会出现形状不匹配的广播错误 each.find(class_="a-link-normal a-text-normal")可能返回None,直接调用.get('href')会返回空值或抛出异常,写入DataFrame时也会触发形状错误- 双重循环逻辑错误:外层遍历
results判断非广告商品,内层又重复遍历全量results,导致同一条数据被重复插入多次,字段对齐异常
2. 局部变量未定义报错
df未在循环外初始化:如果results为空、或所有商品都是广告(sponsor != []),则df = df.append()永远不会执行,后续调用df时就会报未定义- 若
findpercentage函数未在当前作用域定义/导入,调用时也会触发局部变量未定义错误
3. 调试阶段返回None值
- 函数最终返回的是
soup而非处理完成的DataFrame,若页面解析异常导致soup为空,或你实际需要返回的是爬取结果df,就会拿到None值 - 页面反爬导致
results为空,整个循环逻辑未执行,处理逻辑无输出
优化修复后的代码
import pandas as pd from bs4 import BeautifulSoup # 折扣计算函数,缺失的话请自行补充逻辑 def findpercentage(og, dis): return round((og - dis)/og * 100, 2) def scrape_amazon(results): # 提前初始化数据存储列表,避免多次append DataFrame降低性能 data_list = [] # 固定列名避免字段缺失导致的数组形状错误 columns = ['Item Name', 'Item Price', 'Discounted Price', 'Percentage of discount', 'Item rating', 'Url'] for x in results: sponsor = x.findAll(class_="s-sponsored-label-info-icon") # 跳过广告商品 if sponsor: continue # 所有字段统一加判空逻辑,避免属性调用报错 item_name = x.h2.a.text.strip() if (x.h2 and x.h2.a) else "Not Available" item_rating = x.i.text.strip() if x.i else "No rating" url_ele = x.find(class_="a-link-normal a-text-normal") item_url = url_ele.get('href') if url_ele else "Not Available" price_data = { 'Item Name': item_name, 'Item Price': "Not Available", 'Discounted Price': "Not Available", 'Percentage of discount': 0.0, 'Item rating': item_rating, 'Url': item_url } # 价格字段处理加层级判空 hasdisprice = x.find(class_="a-price") hasrealprice = x.find(class_="a-price a-text-price") if hasrealprice and hasrealprice.find(class_="a-offscreen"): price_data["Item Price"] = hasrealprice.find(class_="a-offscreen").text.strip() if hasdisprice and hasdisprice.find(class_="a-offscreen"): price_data["Discounted Price"] = hasdisprice.find(class_="a-offscreen").text.strip() # 折扣计算加异常捕获,避免特殊价格格式转float失败报错 if price_data["Item Price"] != "Not Available" and price_data["Discounted Price"] != "Not Available": try: ogpriceclean = float(price_data["Item Price"].replace("s$", "").replace(",", "")) discountpriceclean = float(price_data["Discounted Price"].replace("s$", "").replace(",", "")) price_data["Percentage of discount"] = findpercentage(ogpriceclean, discountpriceclean) except (ValueError, ZeroDivisionError): pass data_list.append(price_data) # 一次性转换为DataFrame,效率更高且避免数组形状不匹配问题 df = pd.DataFrame(data_list, columns=columns) # 按需返回结果,若需要soup可自行调整返回值 return df
额外注意事项
- 亚马逊页面类名会定期更新,若爬取不到数据优先检查页面元素的class是否匹配
- 建议增加请求头、随机延迟、代理IP池配置,避免反爬导致
results为空 - 可根据需求自行扩展价格字符串的清洗规则,适配更多区域的货币格式
内容的提问来源于stack exchange,提问作者NZH
相关产品推荐
相关产品推荐

