You need to enable JavaScript to run this app. Python爬取TrueCar数据存MySQL时出现list索引越界及写入异常
优惠活动
大模型
产品
解决方案
定价
更多

Python爬取TrueCar数据存MySQL时出现list索引越界及写入异常

问题根因与修复方案

一、list index out of range 报错触发原因

  • 你在遍历提取车型、价格、里程元素时,硬编码了循环20次的逻辑,但实际通过选择器匹配到的页面元素数量不足20个。触发该问题的常见场景:
    • 请求未携带正常浏览器请求头,被truecar反爬策略拦截,返回的页面为验证拦截页,没有实际车辆内容,匹配到的元素列表为空
    • 页面的元素类名、测试属性值发生调整,原有选择器无法完整匹配所有车辆卡片,抓到的元素数量达不到20个
  • 一旦循环索引超过实际抓取到的列表长度,就会直接触发索引越界错误。

二、数据库写入失败的核心原因

原有实现完全不符合mysql.connector的参数传参规则,自然无法正常写入:

  • SQL拼接逻辑错误:原本只需要3个字段的占位符,却把三个独立列表生成的占位符组强行拼接到单条VALUES子句中,最终生成的SQL语法完全错误
  • 传参逻辑错误:cursor.execute() 仅支持传入对应单条记录的参数元组,根本不支持拆分三个列表分别传入参数的写法
  • 你要将每辆车作为独立行存入表,完全不需要复杂的占位符拼接,直接使用批量插入方法即可实现需求。

三、修正后的可运行实现

import mysql.connector
from bs4 import BeautifulSoup
import requests

# 携带正常浏览器请求头,避免被反爬拦截
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

# 接收输入并拼接请求链接
requested_car_name = input()
my_request = requests.get(
    'https://www.truecar.com/used-cars-for-sale/listings/' + requested_car_name + '/location-holtsville-ny/?sort[]=best_match',
    headers=headers
)
my_soup = BeautifulSoup(my_request.text, 'html.parser')

# 提取全量匹配元素后直接截取前20条,取消硬编码循环逻辑
car_model_elems = my_soup.find_all('span', attrs={'class': 'vehicle-header-make-model text-truncate'})[:20]
price_elems = my_soup.find_all('div', attrs={'data-test': 'vehicleCardPricingBlockPrice'})[:20]
distance_elems = my_soup.find_all('div', attrs={'data-test': 'vehicleMileage'})[:20]

# 增加基础异常判断,避免空列表操作
if not all([car_model_elems, price_elems, distance_elems]):
    print("页面元素匹配失败,请检查选择器有效性或反爬拦截情况")
    exit()

# 按行组装数据:每一个元组对应一辆车的三个字段值
insert_data = []
for model, price, dist in zip(car_model_elems, price_elems, distance_elems):
    insert_data.append(
        (model.text.strip(), price.text.strip(), dist.text.strip())
    )

# 原有数据库连接配置保持不变
mydb = mysql.connector.connect(
    host="xxxxx",
    user="xxxxxx",
    password="xxxxxx",
    port='xxxxxx',
    database='xxxxxx'
)
my_cursor = mydb.cursor(buffered=True)

# 使用批量插入方法写入多行,SQL保持单条3字段的标准结构
insert_sql = "INSERT INTO car_name (car_model, price, distance) VALUES (%s, %s, %s)"
my_cursor.executemany(insert_sql, insert_data)
mydb.commit()

print(f"成功插入 {my_cursor.rowcount} 条记录")
mydb.close()

注意:不同类别的页面元素抓取数量可能存在细微差异,直接用zip()按最短列表长度对齐匹配,就不会再出现索引越界问题,也能保证三个字段的取值和对应车辆一一匹配,不会错位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 19:36:10