Python爬虫爬取Cars.com时重复抓取车辆问题求助
解决Cars.com爬虫重复抓取数据的问题
问题定位
1. 反爬机制触发(核心原因)
Cars.com有反爬策略,你的代码直接用requests.get发起请求,未设置请求头(User-Agent),也没有添加请求间隔,频繁请求会被判定为机器人,网站返回重复页面内容,导致抓取到重复数据。爬取大量页面时,这种限制会更明显。
2. 代码逻辑错误
zip_longest调用时机错误:你在初始化空列表后立即执行exoprted = zip_longest(*all_lists),此时所有列表为空,生成的迭代器也为空。后续填充列表后,写入的还是这个空迭代器,等于无效写入,反而可能因文件追加模式导致重复内容。- 拼写错误:
exoprted应为exported,虽不影响运行,但属于潜在问题。 - 外层循环冗余:用
for c in range(0,18000)完全没必要,应直接用while循环精准控制爬取页数,避免无效循环。
3. 缺少异常处理
车辆详情页可能存在字段缺失(比如部分二手车未标注变速箱信息),此时代码会直接报错中断,导致page_num无法递增,下次循环继续爬取同一页,造成重复数据。
解决方案
1. 添加反爬规避措施
- 设置请求头模拟浏览器请求
- 添加随机请求间隔,避免频繁请求
- 可选:限制爬取速度或使用代理IP(若限制严重)
2. 修正代码逻辑
- 调整
zip_longest调用位置,确保填充完所有车辆数据后再生成迭代器 - 替换外层循环为
while循环,精准控制爬取页数 - 修正拼写错误
3. 添加异常处理
对车辆详情页的字段查找添加try-except块,避免程序中断,同时记录异常车辆URL以便排查
优化后的完整代码
import csv import time import random import requests as r from bs4 import BeautifulSoup as b from itertools import zip_longest # 配置参数 car_count = 0 page_num = 1 max_page = 100 # 模拟浏览器请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } # 爬取循环,直到达到最大页数 while page_num <= max_page: urls = [] urls_list = [] stocks_list = [] names_list = [] miles_list = [] prices_list = [] fueltype_list = [] tran_list = [] engine_list = [] print(f"开始爬取第 {page_num} 页...") # 构造列表页URL list_url = f"https://www.cars.com/shopping/results/?dealer_id=&keyword=&list_price_max=&list_price_min=&makes[]=&maximum_distance=all&mileage_max=&no_accidents=true&page={page_num}&page_size=100&sort=best_match_desc&stock_type=used&year_max=&year_min=&zip=" try: # 请求列表页,添加随机延迟 time.sleep(random.uniform(1, 3)) list_response = r.get(list_url, headers=headers) list_response.raise_for_status() # 检查请求是否成功 list_soup = b(list_response.content, "lxml") cards = list_soup.find_all("div", class_="vehicle-card") if not cards: print(f"第 {page_num} 页未找到车辆卡片,可能被反爬限制") page_num += 1 continue # 提取所有车辆详情页URL for card in cards: url = card.find("a").get("href") full_url = "https://www.cars.com" + url urls.append(full_url) # 爬取每个车辆详情页 for idx, car_url in enumerate(urls): try: time.sleep(random.uniform(0.5, 2)) car_response = r.get(car_url, headers=headers) car_response.raise_for_status() car_soup = b(car_response.content, "lxml") # 提取字段,添加异常处理 stock = car_soup.find("p", {"class": "new-used"}).text if car_soup.find("p", {"class": "new-used"}) else "未知" name = car_soup.find("h1", {"class": "listing-title"}).text if car_soup.find("h1", {"class": "listing-title"}) else "未知" miless = car_soup.find("dt", string="Mileage") milesss = miless.find_next_sibling("dd").get_text().strip(" mi.") if miless else "未知" gear = car_soup.find("dt", string="Transmission") tran = gear.find_next_sibling("dd").get_text() if gear else "未知" oneengine = car_soup.find("dt", string="Engine") twoengine = oneengine.find_next_sibling("dd").get_text() if oneengine else "未知" onefuel = car_soup.find("dt", string="Fuel type") twofuel = onefuel.find_next_sibling("dd").get_text() if onefuel else "未知" price = car_soup.find("span", {"class": "primary-price"}).text.strip("$") if car_soup.find("span", {"class": "primary-price"}) else "未知" # 添加到列表 urls_list.append(car_url) stocks_list.append(stock) names_list.append(name) miles_list.append(milesss) prices_list.append(price) fueltype_list.append(twofuel) tran_list.append(tran) engine_list.append(twoengine) car_count += 1 print(f"已抓取 {car_count} 辆车(第{page_num}页第{idx+1}辆)") except Exception as e: print(f"爬取车辆 {car_url} 出错: {str(e)}") continue # 生成要写入的数据(必须在填充完列表后调用) exported = zip_longest(stocks_list, names_list, miles_list, prices_list, fueltype_list, tran_list, engine_list, urls_list) # 写入CSV,追加模式 with open(r"C:\Users\khale\OneDrive\سطح المكتب\car\cars33.csv", "a", newline="", encoding="utf-8") as myfile: writer = csv.writer(myfile) # 如果是第一页,写入表头 if page_num == 1: writer.writerow(["车辆类型", "车辆名称", "里程", "价格", "燃料类型", "变速箱", "发动机", "详情URL"]) writer.writerows(exported) print(f"第 {page_num} 页数据写入完成") page_num += 1 except Exception as e: print(f"爬取列表页 {page_num} 出错: {str(e)}") # 遇到错误时等待更久,避免被封 time.sleep(random.uniform(5, 10)) continue print("所有页面爬取完成")
额外注意事项
- 如果仍出现重复数据,可尝试增加请求间隔,或使用代理IP轮换
- 不要设置过大的
max_page,Cars.com可能限制总爬取页数 - 定期检查CSV文件,避免重复写入表头
内容的提问来源于stack exchange,提问作者KONICHUA
相关产品推荐
相关产品推荐

