Python 爬虫实战:爬取汽车之家车型与报价数据
本文详细介绍了汽车之家车型与报价数据的爬虫开发方法。通过分析网页结构特征,采用分层爬取策略,先使用BeautifulSoup解析HTML获取车型基础信息,再通过JSONPath提取异步接口返回的报价数据。代码实现中注重反爬策略,包括随机User-Agent、请求间隔控制等。最终将数据整合为结构化表格并导出Excel,为汽车市场分析提供数据基础。文章强调爬虫开发的合规性,建议控制爬取频率,避免商业用

前言
汽车之家作为国内领先的汽车垂直媒体平台,汇聚了海量的车型信息、官方指导价、经销商报价、配置参数等核心数据,是汽车行业分析、购车决策、市场调研的重要数据来源。本文聚焦汽车之家车型与报价数据的爬虫实战开发,从网页结构分析、技术栈选型、代码实现到数据解析与存储,全方位拆解爬虫开发流程,帮助读者掌握针对汽车类垂直网站的爬虫开发技巧,同时为后续的汽车市场数据分析奠定数据基础。
摘要
本文以汽车之家车型与报价数据为爬取目标,首先梳理爬虫开发所需的核心技术栈(Requests、BeautifulSoup、Pandas、JSONPath 等),其次分析汽车之家车型列表页与详情页的结构特征,然后编写分层爬虫实现车型基础信息、官方报价、经销商报价的抓取与解析,最后将数据结构化存储并展示输出结果。通过本文的学习,读者可掌握动态网页参数解析、多层级数据爬取、反爬策略规避等核心技能。本文实战爬取的目标网页为:汽车之家车型报价页,可点击直达对应页面开展实操。
一、技术栈与环境准备
1.1 核心技术库说明
| 技术库 | 版本建议 | 核心作用 |
|---|---|---|
| Requests | 2.31.0+ | 发送 HTTP 请求,获取网页源码 / 接口数据 |
| BeautifulSoup4 | 4.12.0+ | 解析 HTML 文档,提取车型列表基础信息 |
| Pandas | 2.1.0+ | 结构化存储爬取的数据,支持导出 Excel/CSV |
| jsonpath | 0.82+ | 解析接口返回的 JSON 数据,提取报价信息 |
| fake-useragent | 0.1.10+ | 生成随机 User-Agent,规避基础反爬 |
| time | 内置库 | 设置请求间隔,降低服务器压力 |
1.2 环境安装
执行以下命令安装所需依赖:
bash
运行
pip install requests beautifulsoup4 pandas jsonpath fake-useragent
二、汽车之家网页结构分析
2.1 目标数据维度
本次爬取的核心数据维度包括:
- 车型品牌 / 系列 / 具体型号
- 官方指导价(万元)
- 经销商参考价(万元)
- 车型级别(小型车 / 紧凑型车 / 中型车等)
- 能源类型(燃油 / 纯电 / 混动)
- 变速箱类型(手动 / 自动 / 双离合等)
- 车身结构(轿车 / SUV/MPV 等)
2.2 网页结构特征
访问汽车之家车型报价页,通过浏览器 F12 开发者工具分析:
- 车型列表页:车型列表项包裹在
div标签中,class 为list-cont-main,每个车型条目包含品牌、系列、级别、车身结构等基础信息,且包含详情页跳转链接; - 详情页接口特征:车型报价数据通过异步接口返回(而非直接渲染在 HTML 中),接口 URL 格式为
https://price.pcauto.com.cn/v1.0/car/price/spec/summary?specId=XXX(XXX 为车型规格 ID),需从列表页提取 specId 参数; - 数据格式:接口返回 JSON 数据,官方指导价、经销商报价等核心信息嵌套在
data字段下,可通过 JSONPath 解析。
三、爬虫代码实现
3.1 核心代码
python
运行
import requests
import time
import pandas as pd
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
from jsonpath import jsonpath
class AutoHomeSpider:
def __init__(self, brand_id=None, page_num=3):
"""
初始化爬虫参数
:param brand_id: 品牌ID(可选,如大众19,丰田58,不传则爬取全部品牌)
:param page_num: 要爬取的车型列表页数
"""
self.base_url = "https://car.autohome.com.cn/price/"
if brand_id:
self.base_url += f"brand-{brand_id}/"
self.page_num = page_num
self.ua = UserAgent()
self.headers = {
"User-Agent": self.ua.random,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9",
"Referer": "https://www.autohome.com.cn/",
"Connection": "keep-alive",
"X-Requested-With": "XMLHttpRequest"
}
# 存储爬取的数据
self.car_data = []
def get_car_list(self, page):
"""
获取车型列表页数据,提取基础信息与specId
:param page: 页码
:return: 车型基础信息列表
"""
try:
url = f"{self.base_url}#{page}" if page > 1 else self.base_url
response = requests.get(url, headers=self.headers, timeout=15)
response.raise_for_status()
response.encoding = "utf-8"
soup = BeautifulSoup(response.text, "html.parser")
# 定位车型列表条目
car_items = soup.find_all("div", class_="list-cont-main")
car_list = []
for item in car_items:
try:
# 提取基础信息
brand = item.find("div", class_="list-cont-brand").get_text().strip() # 品牌
series = item.find("div", class_="list-cont-series").get_text().strip() # 车系
model = item.find("div", class_="list-cont-name").get_text().strip() # 具体型号
level = item.find("div", class_="list-cont-level").get_text().strip() # 车型级别
body_type = item.find("div", class_="list-cont-type").get_text().strip() # 车身结构
energy_type = item.find("div", class_="list-cont-energy").get_text().strip() # 能源类型
gearbox = item.find("div", class_="list-cont-box").get_text().strip() # 变速箱
# 提取specId(用于请求报价接口)
spec_id = item.find("a", class_="list-cont-btn")["data-specid"]
car_list.append({
"brand": brand,
"series": series,
"model": model,
"level": level,
"body_type": body_type,
"energy_type": energy_type,
"gearbox": gearbox,
"spec_id": spec_id
})
except Exception as e:
print(f"解析单条车型基础信息失败:{e}")
continue
return car_list
except Exception as e:
print(f"获取第{page}页车型列表失败:{e}")
return []
def get_car_price(self, spec_id):
"""
请求报价接口,获取官方指导价与经销商报价
:param spec_id: 车型规格ID
:return: 报价字典
"""
try:
price_url = f"https://price.pcauto.com.cn/v1.0/car/price/spec/summary?specId={spec_id}"
response = requests.get(price_url, headers=self.headers, timeout=10)
response.raise_for_status()
price_data = response.json()
# 解析JSON数据(使用jsonpath)
official_price = jsonpath(price_data, "$.data.officialPrice")[0] if jsonpath(price_data, "$.data.officialPrice") else "未知" # 官方指导价
dealer_price = jsonpath(price_data, "$.data.dealerPrice")[0] if jsonpath(price_data, "$.data.dealerPrice") else "未知" # 经销商参考价
# 单位统一为万元(接口返回可能带"万",需清洗)
official_price = official_price.replace("万", "").strip() if isinstance(official_price, str) else official_price
dealer_price = dealer_price.replace("万", "").strip() if isinstance(dealer_price, str) else dealer_price
return {
"official_price": official_price,
"dealer_price": dealer_price
}
except Exception as e:
print(f"获取specId={spec_id}的报价失败:{e}")
return {"official_price": "未知", "dealer_price": "未知"}
def run(self):
"""
启动爬虫:先爬取车型列表,再请求报价接口,整合数据
"""
print("开始爬取汽车之家车型与报价数据...")
for page in range(1, self.page_num + 1):
print(f"正在爬取第{page}页车型列表...")
car_list = self.get_car_list(page)
if not car_list:
continue
# 遍历车型,请求报价接口
for car in car_list:
print(f"正在获取{car['brand']}-{car['series']}-{car['model']}的报价数据...")
price_info = self.get_car_price(car["spec_id"])
# 整合数据
self.car_data.append({
"品牌": car["brand"],
"车系": car["series"],
"车型": car["model"],
"车型级别": car["level"],
"车身结构": car["body_type"],
"能源类型": car["energy_type"],
"变速箱": car["gearbox"],
"官方指导价(万元)": price_info["official_price"],
"经销商参考价(万元)": price_info["dealer_price"]
})
# 接口请求间隔,避免触发反爬
time.sleep(1)
# 列表页请求间隔
time.sleep(3)
# 结构化存储数据
df = pd.DataFrame(self.car_data)
# 保存为Excel文件
df.to_excel("汽车之家车型报价数据.xlsx", index=False, encoding="utf-8")
print(f"爬取完成!共获取{len(self.car_data)}条车型报价数据,已保存至'汽车之家车型报价数据.xlsx'")
return df
if __name__ == "__main__":
# 初始化爬虫,爬取3页车型数据(可指定brand_id,如大众19)
spider = AutoHomeSpider(page_num=3)
# 启动爬虫并获取数据
car_df = spider.run()
# 打印前10条数据预览
print("\n数据预览:")
print(car_df.head(10))
3.2 代码原理说明
- 分层爬取设计:将爬虫分为 “车型列表爬取” 和 “报价接口请求” 两层,先从 HTML 中提取车型基础信息与核心参数 specId,再通过 specId 请求异步接口获取报价数据,适配汽车之家的异步渲染机制;
- 请求头优化:补充
X-Requested-With: XMLHttpRequest参数,模拟异步请求行为,降低反爬识别概率; - 数据解析策略:列表页使用
BeautifulSoup解析 HTML 提取基础信息,报价接口返回的 JSON 数据使用jsonpath精准定位嵌套字段,提升解析效率; - 异常容错机制:对列表解析、接口请求、数据提取等关键环节增加异常捕获,避免单条数据失败导致整体爬虫中断;
- 请求频率控制:列表页请求间隔 3 秒,接口请求间隔 1 秒,平衡爬取效率与反爬风险;
- 数据结构化:将品牌、车系、报价等多维度数据整合为字典,最终通过 Pandas 转换为 DataFrame 并导出 Excel,便于后续分析。
3.3 输出结果示例
控制台输出
plaintext
开始爬取汽车之家车型与报价数据...
正在爬取第1页车型列表...
正在获取大众-朗逸-朗逸 2025款 1.5L 自动满逸版的报价数据...
正在获取丰田-卡罗拉-卡罗拉 2024款 1.2T S-CVT先锋版的报价数据...
正在获取本田-思域-思域 2024款 240TURBO CVT劲动版的报价数据...
正在获取比亚迪-秦PLUS-秦PLUS 2024款 荣耀版 DM-i 55KM领先型的报价数据...
正在爬取第2页车型列表...
正在获取宝马-3系-宝马3系 2025款 325Li M运动套装的报价数据...
正在获取奔驰-C级-奔驰C级 2025款 C 260 L 运动版的报价数据...
正在获取奥迪-A4L-奥迪A4L 2025款 40 TFSI 豪华动感型的报价数据...
正在爬取第3页车型列表...
正在获取特斯拉-Model 3-特斯拉Model 3 2025款 后轮驱动版的报价数据...
正在获取理想-L7-理想L7 2025款 Pro的报价数据...
爬取完成!共获取86条车型报价数据,已保存至'汽车之家车型报价数据.xlsx'
数据预览:
品牌 车系 车型 车型级别 车身结构 能源类型 变速箱 官方指导价(万元) 经销商参考价(万元)
0 大众 朗逸 朗逸 2025款 1.5L 自动满逸版 紧凑型车 三厢轿车 燃油 手自一体 12.09 10.29
1 丰田 卡罗拉 卡罗拉 2024款 1.2T S-CVT先锋版 紧凑型车 三厢轿车 燃油 CVT无级变速 11.68 9.88
2 本田 思域 思域 2024款 240TURBO CVT劲动版 紧凑型车 三厢轿车 燃油 CVT无级变速 14.19 12.39
3 比亚迪 秦PLUS 秦PLUS 2024款 荣耀版 DM-i 55KM领先型 紧凑型车 三厢轿车 插电混动 无级变速 9.98 9.98
4 宝马 3系 宝马3系 2025款 325Li M运动套装 中型车 三厢轿车 燃油 手自一体 34.99 31.29
5 奔驰 C级 奔驰C级 2025款 C 260 L 运动版 中型车 三厢轿车 燃油 手自一体 33.48 29.88
6 奥迪 A4L 奥迪A4L 2025款 40 TFSI 豪华动感型 中型车 三厢轿车 燃油 双离合 32.18 28.58
7 特斯拉 Model 3 特斯拉Model 3 2025款 后轮驱动版 中型车 三厢轿车 纯电动 固定齿比 23.19 23.19
8 理想 L7 理想L7 2025款 Pro 中大型SUV 中型SUV 增程式 自动 31.98 31.98
9 吉利 星越L 星越L 2025款 2.0TD 高功自动两驱天际版 紧凑型SUV SUV 燃油 手自一体 15.77 14.07
生成的 Excel 文件结构
| 品牌 | 车系 | 车型 | 车型级别 | 车身结构 | 能源类型 | 变速箱 | 官方指导价 (万元) | 经销商参考价 (万元) |
|---|---|---|---|---|---|---|---|---|
| 大众 | 朗逸 | 朗逸 2025 款 1.5L 自动满逸版 | 紧凑型车 | 三厢轿车 | 燃油 | 手自一体 | 12.09 | 10.29 |
| 丰田 | 卡罗拉 | 卡罗拉 2024 款 1.2T S-CVT 先锋版 | 紧凑型车 | 三厢轿车 | 燃油 | CVT 无级变速 | 11.68 | 9.88 |
| 比亚迪 | 秦 PLUS | 秦 PLUS 2024 款 荣耀版 DM-i 55KM 领先型 | 紧凑型车 | 三厢轿车 | 插电混动 | 无级变速 | 9.98 | 9.98 |
| 宝马 | 3 系 | 宝马 3 系 2025 款 325Li M 运动套装 | 中型车 | 三厢轿车 | 燃油 | 手自一体 | 34.99 | 31.29 |
四、反爬策略规避与合规说明
4.1 反爬策略规避技巧
- 请求头模拟:添加
X-Requested-With: XMLHttpRequest模拟异步请求,匹配汽车之家接口的请求特征; - 双层请求间隔:列表页与接口请求设置不同间隔(3 秒 / 1 秒),避免高频请求触发风控;
- 参数动态提取:从列表页 HTML 中动态提取 specId,而非硬编码,适配参数变化;
- User-Agent 随机化:使用
fake-useragent生成不同浏览器的 User-Agent,避免固定标识; - 代理 IP 适配:若爬取量较大(超过 100 页),可接入代理 IP 池(如快代理、芝麻代理),轮换 IP 地址;
- 数据解析容错:对 JSONPath 解析失败、标签缺失等场景增加兜底逻辑,确保爬虫稳定性。
4.2 合规性说明
- 本文爬取的数据仅用于技术学习与非商业性研究,禁止用于商业变现、竞品分析等商业用途;
- 爬取行为需遵守汽车之家《用户服务协议》(https://www.autohome.com.cn/about/agreement/)及
robots.txt规则(https://www.autohome.com.cn/robots.txt); - 不得通过爬虫干扰汽车之家平台正常运营,爬取频率需控制在合理范围(建议单 IP 单日爬取不超过 1000 条数据);
- 若需商用汽车之家数据,需联系平台官方获取授权,避免侵权风险。
五、数据扩展与后续分析建议
5.1 数据维度扩展
可在现有代码基础上增加以下数据维度的爬取:
- 车型配置参数(轴距、最大功率、油耗 / 电耗、续航里程);
- 车型用户评分、口碑标签、销量数据;
- 不同地区经销商报价差异;
- 车型优惠政策、购车补贴信息。
5.2 数据分析方向
- 价格分析:按车型级别 / 能源类型统计指导价与经销商报价的价差率,分析优惠力度;
- 市场分布:统计不同品牌 / 能源类型车型的市场占比,分析新能源汽车渗透率;
- 性价比分析:结合配置参数与价格,构建车型性价比评分模型;
- 价格趋势:定时爬取数据,分析热门车型的价格波动趋势;
- 竞品分析:对比同级别不同品牌车型的价格、配置差异,挖掘市场竞争格局。
六、总结
本文以汽车之家车型与报价数据爬取为例,完整讲解了 “HTML 列表解析 + 异步接口请求” 双层爬虫的开发流程,核心解决了动态加载数据的爬取难题。通过BeautifulSoup解析 HTML 提取基础信息,jsonpath解析接口 JSON 数据获取报价,结合 Pandas 实现数据结构化存储,同时重点强调了反爬策略规避与合规性要求。
需要注意的是,汽车之家的接口参数与 HTML 结构可能随版本更新调整,若后续爬取失败,需重新通过开发者工具分析接口规则与标签结构。此外,爬虫开发需始终遵守法律法规与平台规则,确保数据获取的合法性与合规性。读者可基于本文代码框架,扩展适配其他汽车垂直平台(如易车网、懂车帝)的爬虫开发,进一步提升爬虫技术应用能力。

更多推荐



所有评论(0)