前言

汽车之家作为国内领先的汽车垂直媒体平台,汇聚了海量的车型信息、官方指导价、经销商报价、配置参数等核心数据,是汽车行业分析、购车决策、市场调研的重要数据来源。本文聚焦汽车之家车型与报价数据的爬虫实战开发,从网页结构分析、技术栈选型、代码实现到数据解析与存储,全方位拆解爬虫开发流程,帮助读者掌握针对汽车类垂直网站的爬虫开发技巧,同时为后续的汽车市场数据分析奠定数据基础。

摘要

本文以汽车之家车型与报价数据为爬取目标,首先梳理爬虫开发所需的核心技术栈(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 开发者工具分析:

  1. 车型列表页:车型列表项包裹在div标签中,class 为list-cont-main,每个车型条目包含品牌、系列、级别、车身结构等基础信息,且包含详情页跳转链接;
  2. 详情页接口特征:车型报价数据通过异步接口返回(而非直接渲染在 HTML 中),接口 URL 格式为https://price.pcauto.com.cn/v1.0/car/price/spec/summary?specId=XXX(XXX 为车型规格 ID),需从列表页提取 specId 参数;
  3. 数据格式:接口返回 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 代码原理说明

  1. 分层爬取设计:将爬虫分为 “车型列表爬取” 和 “报价接口请求” 两层,先从 HTML 中提取车型基础信息与核心参数 specId,再通过 specId 请求异步接口获取报价数据,适配汽车之家的异步渲染机制;
  2. 请求头优化:补充X-Requested-With: XMLHttpRequest参数,模拟异步请求行为,降低反爬识别概率;
  3. 数据解析策略:列表页使用BeautifulSoup解析 HTML 提取基础信息,报价接口返回的 JSON 数据使用jsonpath精准定位嵌套字段,提升解析效率;
  4. 异常容错机制:对列表解析、接口请求、数据提取等关键环节增加异常捕获,避免单条数据失败导致整体爬虫中断;
  5. 请求频率控制:列表页请求间隔 3 秒,接口请求间隔 1 秒,平衡爬取效率与反爬风险;
  6. 数据结构化:将品牌、车系、报价等多维度数据整合为字典,最终通过 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 反爬策略规避技巧

  1. 请求头模拟:添加X-Requested-With: XMLHttpRequest模拟异步请求,匹配汽车之家接口的请求特征;
  2. 双层请求间隔:列表页与接口请求设置不同间隔(3 秒 / 1 秒),避免高频请求触发风控;
  3. 参数动态提取:从列表页 HTML 中动态提取 specId,而非硬编码,适配参数变化;
  4. User-Agent 随机化:使用fake-useragent生成不同浏览器的 User-Agent,避免固定标识;
  5. 代理 IP 适配:若爬取量较大(超过 100 页),可接入代理 IP 池(如快代理、芝麻代理),轮换 IP 地址;
  6. 数据解析容错:对 JSONPath 解析失败、标签缺失等场景增加兜底逻辑,确保爬虫稳定性。

4.2 合规性说明

  1. 本文爬取的数据仅用于技术学习与非商业性研究,禁止用于商业变现、竞品分析等商业用途;
  2. 爬取行为需遵守汽车之家《用户服务协议》(https://www.autohome.com.cn/about/agreement/)及robots.txt规则(https://www.autohome.com.cn/robots.txt);
  3. 不得通过爬虫干扰汽车之家平台正常运营,爬取频率需控制在合理范围(建议单 IP 单日爬取不超过 1000 条数据);
  4. 若需商用汽车之家数据,需联系平台官方获取授权,避免侵权风险。

五、数据扩展与后续分析建议

5.1 数据维度扩展

可在现有代码基础上增加以下数据维度的爬取:

  • 车型配置参数(轴距、最大功率、油耗 / 电耗、续航里程);
  • 车型用户评分、口碑标签、销量数据;
  • 不同地区经销商报价差异;
  • 车型优惠政策、购车补贴信息。

5.2 数据分析方向

  1. 价格分析:按车型级别 / 能源类型统计指导价与经销商报价的价差率,分析优惠力度;
  2. 市场分布:统计不同品牌 / 能源类型车型的市场占比,分析新能源汽车渗透率;
  3. 性价比分析:结合配置参数与价格,构建车型性价比评分模型;
  4. 价格趋势:定时爬取数据,分析热门车型的价格波动趋势;
  5. 竞品分析:对比同级别不同品牌车型的价格、配置差异,挖掘市场竞争格局。

六、总结

本文以汽车之家车型与报价数据爬取为例,完整讲解了 “HTML 列表解析 + 异步接口请求” 双层爬虫的开发流程,核心解决了动态加载数据的爬取难题。通过BeautifulSoup解析 HTML 提取基础信息,jsonpath解析接口 JSON 数据获取报价,结合 Pandas 实现数据结构化存储,同时重点强调了反爬策略规避与合规性要求。

需要注意的是,汽车之家的接口参数与 HTML 结构可能随版本更新调整,若后续爬取失败,需重新通过开发者工具分析接口规则与标签结构。此外,爬虫开发需始终遵守法律法规与平台规则,确保数据获取的合法性与合规性。读者可基于本文代码框架,扩展适配其他汽车垂直平台(如易车网、懂车帝)的爬虫开发,进一步提升爬虫技术应用能力。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐