建站之星怎么弄相册,网站建设的数据所有权,东莞网站优化什么方法,winserver wordpress本篇主要是整个项目的介绍#xff0c;没提到太多琐碎的技术细节#xff0c;以后有空的话会整理一下 Scrapy 和原生爬虫的差异#xff0c;还有它坑人的一些地方#xff0c;单发出来。
开源地址#xff1a;https://github.com/shandianchengzi/car_home_spider
使用说明没提到太多琐碎的技术细节以后有空的话会整理一下 Scrapy 和原生爬虫的差异还有它坑人的一些地方单发出来。
开源地址https://github.com/shandianchengzi/car_home_spider
使用说明切换到autohome_spider目录下运行run.bat。 文章目录 汽车之家大连市二手车车辆数据爬取、清洗与可视化一、项目简介二、项目架构1运行环境3系统架构图4数据库设计 三、项目核心代码说明1Scrapy框架数据爬取2Pandas数据清洗与可视化3Matplotlib数据可视化 四、项目运行截图1 爬虫结果截图2 持久化存储结果截图3 可视化分析图形截图 五、总结六、参考资料 汽车之家大连市二手车车辆数据爬取、清洗与可视化
一、项目简介
本项目旨在通过网络爬虫技术从“汽车之家”网站的二手车频道自动抓取各类汽车的详细信息包括品牌、车型、价格、公里数、上牌时间等然后利用Pandas库对数据进行清洗和可视化分析为用户提供直观的数据展示和分析结果。通过本项目用户可以了解到大连市二手车市场的价格分布、常购品牌等信息为购车提供参考依据。
二、项目架构
1运行环境
硬件系统Intel Core i7, 16GB RAM, NVIDIA GeForce GTX 1050 Ti操作系统Windows 10, Version 20H2软件版本Python 3.8.5, SQLite 3.31.1, Visual Studio Code 1.57.1运行时刻2024年7月13日 23:00
3系统架构图 4数据库设计
数据存入csv文件包含字段品牌、上市年份、车型、表显里程公里、上牌时间年、价格万、原厂保修时间、所属城市、链接。
三、项目核心代码说明
1Scrapy框架数据爬取
爬取之前先分析网站信息。 确定网页在网上汽车之家能找到两个网页是卖二手车的一个在产品库1里、另一个在二手车严选2上。结果显示2024年7月13日产品库中的车源更多有2714条而二手车严选里只有1934条。因此本项目选择产品库中的结果。 确定请求方式打开开发者工具并刷新然后搜索页面上的任意车辆的名称检查返回的结果对应的请求。结果表明请求方式为Get请求的就是网站的链接同时没有传递任何Get参数。 确定传参模式 筛选机制注意到网页本身拥有排序功能这样之后就不需要额外排序。它的排序选项不在参数中在链接中比较小众。比如a0_0msdgscncgpi1ltocsp2ex/ 对应默认排序a0_0msdgscncgpi1lto2cspex/ 对应价格降序。 翻页机制产品库的二手车页面中页码也在链接中。比如a0_0msdgscncgpi1lto2csp1ex/对应第一页a0_0msdgscncgpi1lto2csp2ex/对应第二页。 确定结果格式由于他返回的就是网页没有json之类的额外信息所以爬取的结果就是网页上能看到的结果。分析页面内容可知包含的信息为“品牌”、“上市年份”、“车型”、“实物图”、“表显里程”、“上牌时间”、“价格”、“原厂保修时间”、“所属城市”和详细信息的访问链接。观察到图片采用了懒加载技术需要额外请求别的链接才能返回加之数据分析时并不需要图片因此干脆去掉实物图这一个信息。 额外注意事项特别坑的一点是页数超过100页时会自动重定向回到100页而不是返回空这样代码中加空判断就无法真正停止下来。这里得额外写一个100页的判断。而且也因为这个最多返回结果数量2400条。考虑到总共也只有2714条可以认为该数量是可以接受的因此不更改筛选条件重新跑了。
分析好了这些内容之后再开始用Scrapy写爬虫代码如下
Spider中数据爬取解析
class AutohomeSpider(scrapy.Spider):name autohome_spiderallowed_domains [autohome.com.cn]base_url https://car.autohome.com.cn/2sc/dalian/a0_0msdgscncgpi1lto2csp{}ex/page 1start_urls [https://car.autohome.com.cn/2sc/dalian/a0_0msdgscncgpi1lto2csp1ex/]def parse(self, response):xml lxml.etree.HTML(response.text)piclist xml.xpath(//div[classpiclist]/ul/li)if len(piclist) 0 or self.page 100: # max page 100returnfor car in piclist:try:l ItemLoader(itemAutohomeItem())title car.xpath(div[classtitle]/a/text())[0]title_href car.xpath(div[classtitle]/a/href)[0]somethings title.split( , 2)if len(somethings) ! 3:with open(error.log, a) as f:f.write(title \n)continue# 获得icon_list里所有a标签的title属性并拼接非空的为字符串icon_list car.xpath(div[classicon-list]/a)city car.xpath(div[classicon-list]/span/span/text())[0]icons_info []for icon in icon_list:icon_info icon.xpath(title)if icon_info:icons_info.extend(icon_info)icons_info , .join(icons_info)# 用ItemLoader加载数据l.add_value(brand, somethings[0])l.add_value(year, somethings[1])l.add_value(model, somethings[2])l.add_value(mileage, getNumberAndFloat(car.xpath(*/div[classdetail-l]/p[1]/text())[0]))l.add_value(registration_time, getNumberAndFloat(car.xpath(*/div[classdetail-l]/p[2]/text())[0]))l.add_value(price, car.xpath(*/div[classdetail-r]/span/text()))l.add_value(warranty_time, icons_info)l.add_value(city, city)l.add_value(link, https: title_href)yield l.load_item()except Exception as e:# skip no full information carpass# 下一页self.page 1new_url self.base_url.format(self.page)yield scrapy.Request(new_url, callbackself.parse)Pipeline中做数据存储
class AutohomeSpiderPipeline:def open_spider(self, spider):self.file open(autohome.csv, w, newline, encodingutf-8)self.writer csv.DictWriter(self.file, fieldnames[brand, year, model, mileage, registration_time, price, warranty_time, city, link])# [品牌, 上市年份, 车型, 表显里程公里, 上牌时间年, 价格万, 原厂保修时间, 所属城市, 链接]self.writer.writeheader()def close_spider(self, spider):self.file.close()def process_item(self, item, spider):# let item: {field: [value]} to {field: value}item {k: v[0] for k, v in item.items()}self.writer.writerow(item)return item2Pandas数据清洗与可视化
数据清洗主要是将错误的数据修改正确或者删除以便进一步分析。我在爬虫代码的解析过程中对品牌的解析有误有一些品牌的名称本身就带空格我用空格做分割导致该列被解析到下一列中。代码如下
# 数据清洗
df.drop_duplicates(inplaceTrue) # 去重
df.dropna(subset[brand], inplaceTrue) # 去掉品牌为空的数据
# 合并前三列的数据形成字符串用正则重新解析查找xxxx款该字符串前面的是brand后面的是model中间的是year
df[brand_model_year] df[brand] df[year] df[model] # 辅助列
df[brand] df[brand_model_year].str.extract(r^(.*?)(\d{4}款)(.*))[0]
df[year] df[brand_model_year].str.extract(r^(.*?)(\d{4}款)(.*))[1]
df[model] df[brand_model_year].str.extract(r^(.*?)(\d{4}款)(.*))[2]
df.drop(columns[brand_model_year], inplaceTrue)
df[year] df[year].replace(款, , regexTrue)
# 如果原厂保修时间为空填充为0
df[warranty_time].fillna(0, inplaceTrue)
df.to_csv(result_path, indexFalse, encodinggbk) # for windows excel3Matplotlib数据可视化
多角度可视化代码如下
# 数据可视化
df.columns [品牌, 上市年份, 车型, 表显里程公里, 上牌时间年, 价格万, 原厂保修时间, 所属城市, 链接]
# 设置字体
plt.rcParams[font.sans-serif] [SimHei]
plt.rcParams[axes.unicode_minus] False
# 1. 各种数据的占比统计全画在一张图上
plt.figure(figsize(20, 10))
# 1.1 价格分布(只做0~200万的)
plt.subplot(2, 2, 1)
sns.histplot(df[price], bins20, kdeTrue)
plt.xlim(0, 200)
plt.title(价格分布)
# 1.2 里程分布
plt.subplot(2, 2, 2)
sns.histplot(df[mileage], bins20, kdeTrue)
plt.title(里程分布)
# 1.3 品牌分布前20扇形图不要x和y的label
plt.subplot(2, 2, 3)
df[brand].value_counts().head(20).plot.pie(autopct%1.1f%%)
plt.ylabel()
plt.title(品牌数量分布前20)
# 1.4 车型分布(前10扇形图不要x和y的label)
plt.subplot(2, 2, 4)
df[model].value_counts().head(10).plot.pie(autopct%1.1f%%)
plt.ylabel()
plt.title(车型数量分布前10)
plt.savefig(os.path.join(imgs_dir, 各种数据的占比统计.png))
# 2 时间分析
plt.figure(figsize(20, 10))
# 2.1 上牌时间分布
plt.subplot(1, 2, 1)
sns.histplot(df[registration_time], bins20, kdeTrue)
plt.title(上牌时间分布)
# 2.2 上市年份分布
plt.subplot(1, 2, 2)
sns.histplot(df[year], bins20, kdeTrue)
plt.title(上市年份分布)
plt.savefig(os.path.join(imgs_dir, 时间分析.png))
# 3. 保修存在性与其他数据的关系标好图例
plt.figure(figsize(20, 10))
# 3.1 保修存在占比1表示存在0表示不存在扇形图
plt.subplot(2, 2, 1)
df[warranty_time_exist].value_counts().plot.pie(autopct%1.1f%%)
plt.legend([无保修, 有保修])
plt.ylabel()
plt.title(保修存在占比)
# 3.2 保修存在与价格的关系
plt.subplot(2, 2, 2)
sns.boxplot(xwarranty_time_exist, yprice, datadf)
plt.xticks([0, 1], [无保修, 有保修])
plt.title(保修存在与价格的关系)
# 3.3 保修存在与里程的关系
plt.subplot(2, 2, 3)
sns.boxplot(xwarranty_time_exist, ymileage, datadf)
plt.xticks([0, 1], [无保修, 有保修])
plt.title(保修存在与里程的关系)
# 3.4 保修存在与上牌时间的关系
plt.subplot(2, 2, 4)
sns.boxplot(xwarranty_time_exist, yregistration_time, datadf)
plt.xticks([0, 1], [无保修, 有保修])
plt.title(保修存在与上牌时间的关系)
plt.savefig(os.path.join(imgs_dir, 保修是否存在与其他数据的关系.png))四、项目运行截图
1 爬虫结果截图 2 持久化存储结果截图 3 可视化分析图形截图
价格、里程、品牌和车型数量分布可视化 上牌时间和上市时间分布 保修的存在性与价格、里程和上牌时间的关联 五、总结
通过本项目我学习并掌握了网络爬虫的基本原理和方法以及如何利用Python进行数据处理和可视化分析。在项目中我使用Scrapy框架爬取了汽车之家网站的二手车信息然后利用Pandas库对数据进行清洗和整理最后使用Matplotlib库对数据进行可视化分析。通过这个项目我不仅提高了自己的数据处理和分析能力还为大连市二手车市场的价格分布、常购品牌等信息提供了直观的展示和分析结果为购车提供了参考依据。 以上都是套话下附真实的总结 这次发现 scrapy 自带 pipeline 挺不错的比我自己直接写一个强远了而且报错日志什么的也很方便。不过这个网站反爬太少header啥的根本不用加这块我就还没学到。框架的坏处也有很多东西一个 requests 改改参数能解决这个偏偏是类的函数得诡异地设置一些东西去传递参数还难写结束条件。 六、参考资料 Requests官方文档https://docs.python-requests.org/en/master/ BeautifulSoup官方文档https://www.crummy.com/software/BeautifulSoup/bs4/doc/ 通义千问AI问答https://lxblog.com/qianwen/share?shareId6f7c1cba-e39f-4e1e-8b59-b7477e346fa9 Scrapy笔记5- Item详解_scrapy item-CSDN博客https://blog.csdn.net/sdulsj/article/details/52984619#SnippetTab Python爬虫实战数据分析数据可视化汽车之家_基于大数据技术对汽车交易的可视化分析汽车之家-CSDN博客https://blog.csdn.net/qq_45821420/article/details/115366180 python爬虫学习笔记-scrapy框架之start_url_scrapy的start url-CSDN博客https://blog.csdn.net/weixin_42672765/article/details/85380212 https://car.autohome.com.cn/2sc/dalian/a0_0msdgscncgpi1lto2csp1ex/ ↩︎ https://www.che168.com/dalian/list/#pvareaid100945 ↩︎