1. 懂车帝API接口初探第一次接触懂车帝的新能源汽车销量API时我像发现宝藏一样兴奋。这个接口设计得非常友好不需要复杂的鉴权流程直接用GET请求就能获取结构化数据。接口地址是https://www.dongchedi.com/motor/pc/car/rank_data参数设计也很直观new_energy_type1代表纯电动2代表插电混动month1000表示近一年500表示近半年202108表示2021年8月count返回数据条数city城市名称如成都rank_data_type固定传11表示销量榜实测发现即使官方更新了网页端这个接口依然可用。比如想获取成都地区近一年纯电动车销量前100名请求URL是这样的url https://www.dongchedi.com/motor/pc/car/rank_data?new_energy_type1month1000count100city成都rank_data_type112. 构建Python请求环境2.1 安装必要库建议使用conda或virtualenv创建独立环境pip install requests pandas2.2 基础请求代码我封装了一个带异常处理的请求函数这是踩过几次坑后的经验总结import requests from requests.exceptions import RequestException def fetch_data(url, retry3): headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } for i in range(retry): try: resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() # 自动处理HTTP错误 return resp.json() except RequestException as e: print(f第{i1}次请求失败: {str(e)}) if i retry - 1: raise3. 解析JSON响应数据3.1 数据结构分析返回的JSON包含三个关键部分{ data: { list: [ # 核心数据数组 { series_id: 4499, series_name: 五菱宏光MINIEV, rank: 1, count: 380278 # 销量数字 } ], sells_rank_month: [ # 可选时间范围 {text: 2021年11月, month: 202111} ] } }3.2 数据清洗技巧我习惯用pandas做二次处理import pandas as pd def parse_data(json_data): df pd.DataFrame(json_data[data][list]) # 处理价格字段 df[price_range] df.apply(lambda x: f{x[min_price]}-{x[max_price]}万, axis1) # 转换时间戳 df[update_time] pd.to_datetime(df[update_time], unitms) return df[[rank, series_name, count, price_range]]4. 构建完整爬虫脚本4.1 参数化请求通过函数封装实现灵活查询def get_car_rank(energy_type1, time_range1000, limit50, city全国): params { new_energy_type: energy_type, month: time_range, count: limit, city: city, rank_data_type: 11 } base_url https://www.dongchedi.com/motor/pc/car/rank_data return fetch_data(f{base_url}?{.join(f{k}{v} for k,v in params.items())})4.2 数据持久化建议同时保存原始JSON和清洗后的CSVimport json from datetime import datetime def save_data(data, prefixcar_rank): timestamp datetime.now().strftime(%Y%m%d_%H%M) # 保存原始数据 with open(f{prefix}_{timestamp}.json, w) as f: json.dump(data, f, ensure_asciiFalse) # 保存清洗数据 parse_data(data).to_csv(f{prefix}_{timestamp}.csv, indexFalse)5. 实战注意事项5.1 反爬策略应对随机User-Agent建议使用fake_useragent库请求频率控制添加time.sleep(random.uniform(1,3))代理IP池当出现403错误时需要轮换IP5.2 数据更新机制我发现销量数据通常在每月10号左右更新建议设置定时任务import schedule import time def monthly_job(): data get_car_rank() save_data(data) schedule.every().month.at(10:00).do(monthly_job) while True: schedule.run_pending() time.sleep(3600) # 每小时检查一次6. 数据可视化延伸用Matplotlib生成销量TOP10柱状图import matplotlib.pyplot as plt def plot_top10(df): plt.figure(figsize(12,6)) df.head(10).plot.bar(xseries_name, ycount) plt.title(新能源车销量TOP10) plt.xticks(rotation45) plt.tight_layout() plt.savefig(top10.png)7. 异常处理经验这些坑我都亲自踩过城市参数要URL编码urllib.parse.quote(成都)销量数字可能是字符串int(str_count.replace(,,))部分车型没有价格数据要用df[min_price].fillna(0)8. 项目结构建议规范的目录结构能让脚本更易维护dongchedi-spider/ ├── config.py # API配置 ├── crawler.py # 核心爬虫 ├── utils/ # 工具函数 │ ├── storage.py │ └── visual.py └── data/ # 存储结果 ├── raw/ # 原始JSON └── processed/ # 清洗后CSV当处理到具体车型的详细数据时可以进一步解析series_id关联的详情页API。比如五菱宏光MINIEV的详情页URL就包含其series_id4499这种设计让数据采集形成了完整闭环。