本次爬虫的目标是汽车之家的二手车销售信息,范围是全国,不过很可惜,汽车之家只显示100页信息,每页48条,也就是说最多只能够爬取4800条信息。

由于这次爬虫的主要目的是使用lxml解析器,所以在信息的查找上面完全只会涉及lxml中选择器的用法,虽然lxml可以同时使用CSS选择器和Xpath选择器,但是为了更加突出效果,暂且只使用Xpath。

爬虫老套路,分为3个步骤:

  1. 分析网页信息构成,找到切入点
  2. 获取网页,提取有效信息
  3. 储存信息

网页分析

网页结构分析的一般思路是先找到第一个需要爬取的链接,然后看看后面的链接是以什么方式构成的,进而选择一种方式全量爬取(一般使用循环或者递归的方式)。

找到切入点——第一个 URL

通过查看链接构成的规律很容易可以发现,汽车之家二手车的信息是由很多选择项来构成URL的,比如按照品牌,或者车系价格城市等等,如果选择清空筛选,那就得到了全国二手车信息的URL,这正是我需要的,URL为http://www.che168.com/china/list/。

分析【下一页】链接的构成

第一页的链接很容易得到,然后可以看到,二手车的信息总计只有100页,每页48个信息,也就是总共有4800个信息可以爬取到。

通过点击“下一页”可以直接看到第2页的链接大概是http://www.che168.com/china/a0_0msdgscncgpi1ltocsp2exb1x0/,继续点击下一页,查看第3页、第4页的链接http://www.che168.com/china/a0_0msdgscncgpi1ltocsp3exb1x0/可以看到,规律很明显,每页的链接构成除了页码中的数字不同外,其他部分完全一样。

选择一种构造链接的方法

通过上面的分析,构造所有100页的链接是件很简单的事情,只需要把链接中的数字部分循环替换一下就行了,这就是循环的方式了。这个方式对付这种链接很有规律的URL在适合不过了,具体参考代码:

for i in range(1,101):url = 'http://www.che168.com/china/a0_0msdgscncgpi1ltocsp{}exb1x0/'.format(i)

不过,为了更好的适应更加多变的URL,我更加倾向于使用递归的方式来爬取下一页的信息。因此本篇爬虫中不适用上面这种循环爬取的方式,转而使用递归爬取。

所谓递归,首先找到一个递归的出口,也就是爬虫的终点。对于这个爬虫,终点就是当爬到第100页的时候就要结束,既然思路明确了,那可以看看第100页与其他页面有什么不同。

提取信息

递归提取下一页链接

通过分析,可以看到1-99页都有一个“下一页”的按钮,而最后一页是没有这个按钮的,这就是出口。只需要设置一个判断就行了:

def get_items(self,url):html = requests.get(url,headers=self.headers).textselector = etree.HTML(html)next_page = selector.xpath('//*[@id="listpagination"]/a[last()]/@href')[0]next_text = selector.xpath('//*[@id="listpagination"]/a[last()]/text()')[0]url_list = selector.xpath('//*[@id="viewlist_ul"]/li/a/@href')for each in url_list:the_url = 'http://www.che168.com'+eachself.get_infos(the_url)if next_text == '下一页':next_url = 'http://www.che168.com/china'+next_pageself.get_items(next_url)

上面这段代码主要包含下面几个步骤:

html = requests.get(url,headers=self.headers).text

这一句是通过requests来获取网页结构,形成标签树。

selector = etree.HTML(html)
next_page = selector.xpath('//*[@id="listpagination"]/a[last()]/@href')[0]
next_text = selector.xpath('//*[@id="listpagination"]/a[last()]/text()')[0]

上面3句的用意是使用lxml解析网页,然后使用xpath选择器找到下一页的链接,同时尝试找到“下一页”这3个字。

每当找到“下一页”这个按钮,就执行if下面的代码,也就是把找到的下一页链接放入函数中去继续执行,这就形成了递归。当然,前面也说过了,只有1-99页是有这个按钮的,所以到了第100页就找不到这3个字了,这里的if判断就会停止执行, 递归也就结束了。

这一段就是递归的判断:

if next_text == '下一页':next_url = 'http://www.che168.com/china'+next_pageself.get_items(next_url)

提取二手车主页链接

通过查看页面就能看出来,每个页面有48个二手车信息,但是由于页面信息太少了,所以最好再把每个二手车的主页面打开,所以需要先提取到每个二手车的主页面的链接

这段代码就是提取每个页面的所有二手车链接,并且对每个链接执行函数去提取有效信息:

url_list = selector.xpath('//*[@id="viewlist_ul"]/li/a/@href')
for each in url_list:the_url = 'http://www.che168.com'+eachself.get_infos(the_url)

可以看到,提取页面中二手车信息的代码是封装到了一个函数中,而这个函数需要传入一个参数,那就是相应的二手车主页URL。

提取每个主页的信息

每个主页是一个单独的链接,所以可以写一个函数,传入一个url,然后输出需要提取的信息就行了,具体代码如下:

def get_infos(self,page_url):dic = {}html = requests.get(page_url,headers=self.headers).textselector = etree.HTML(html)car_info = selector.xpath('//div[@class="car-info"]')if car_info:dic['title'] = car_info[0].xpath('//div[@class="car-title"]/h2/text()')[0]price = car_info[0].xpath('//div[@class="car-price"]/ins/text()')[0]dic['price'] = price.strip(' ').replace('¥','')dic['xslc'] = car_info[0].xpath('//div[@class="details"]/ul/li/span/text()')[0]dic['scsp'] = car_info[0].xpath('//div[@class="details"]/ul/li/span/text()')[1]dic['dwpl'] = car_info[0].xpath('//div[@class="details"]/ul/li/span/text()')[2]dic['city'] = car_info[0].xpath('//div[@class="details"]/ul/li/span/text()')[3]dic['call_num'] = car_info[0].xpath("//a[contains(@class,'btn') and contains(@class,'btn-iphone3')]/text()")[0]commitment_tag = car_info[0].xpath('//div[@class="commitment-tag"]/ul/li/span/text()')dic['commitment_tag'] = '/'.join(commitment_tag)dic['address'] = car_info[0].xpath('//div[@class="car-address"]/text()')[0].strip()dic['call_man'] = car_info[0].xpath('//div[@class="car-address"]/text()')[-1].strip()print(dic)self.coll.insert(dic)

在这段代码中,首先创建一个空的字典,然后为了后续存储信息更加方便,因此把所有的信息都放到一个字典中去。

提取的方式依然是使用xpath选择器,由于有的信息格式不符合之后要保存的格式,所以使用python的基本方法稍微处理了一下。

最后,再保存信息之前,只用print打印一下提取到信息,查看信息的完整性和准确性。

这样,一个爬虫的前2步就已经完成了,剩下一的就是选中一个合适的方式将信息储存起来。数据库是个好工具,mongodb更是一个好数据库,没错,就是你了!

使用数据库保存信息

连接数据库

由于爬虫的信息不需要太明确的关系,主要目的是存储信息,所以数据库的选择上优先选择mongodb,这种非关系型数据库真是最好不过了。

首先需要导入相应的数据库工具库

from pymongo import MongoClient

然后是连接数据库,由于这个爬虫是写到一个AutohomeSpider类中,因此可以在初始化的时候直接链接指定的数据库,并且可以同时创建表格。

具体代码如下:

self.coon = MongoClient('localhost',27017)
self.coll = self.coon['autohome']['Oldcars']

上述代码可以看到,连接了本地mongodb之后,可以直接创建之前不存在的数据库和数据表。

存入信息

mongodb插入信息的方式非常简单,只需要将数据存放到一个字典中,然后使用 insert() 方法就行。

具体插入信息的代码在上面代码中的

self.coll.insert(dic)

也就是每爬取一条信息就存入mongodb中。

最后爬虫结束,可以使用第三方可视化工具查看一下mongodb中存储的数据:

爬虫源码

爬虫比较简单,爬取的信息也没有多大的价值,因此不做后续深入研究,这个爬虫主要是为了介绍lxml解析器和Xpath选择器。

源码:https://github.com/Hopetree/Spiders100/blob/master/autohome.py

转载于:https://www.cnblogs.com/gopythoner/p/7801470.html

Python爬虫——使用 lxml 解析器爬取汽车之家二手车信息相关推荐

  1. php采集汽车之家demo,Python 爬虫实例(15) 爬取 汽车之家(汽车授权经销商)...

    有人给我吹牛逼,说汽车之家反爬很厉害,我不服气,所以就爬取了一下这个网址. 本片博客的目的是重点的分析定向爬虫的过程,希望读者能学会爬虫的分析流程. 一:爬虫的目标: 打开汽车之家的链接:https: ...

  2. Python 爬虫实例(15) 爬取 汽车之家(汽车授权经销商)

    有人给我吹牛逼,说汽车之家反爬很厉害,我不服气,所以就爬取了一下这个网址. 本片博客的目的是重点的分析定向爬虫的过程,希望读者能学会爬虫的分析流程. 一:爬虫的目标: 打开汽车之家的链接:https: ...

  3. python3爬虫系列16之多线程爬取汽车之家批量下载图片

    python3爬虫系列16之多线程爬取汽车之家批量下载图片 1.前言 上一篇呢,python3爬虫系列14之爬虫增速多线程,线程池,队列的用法(通俗易懂),主要介绍了线程,多线程,和两个线程池的使用. ...

  4. Python爬虫练习-Xpath解析批量爬取PPT

    批量爬取PPT,分页爬取 import os import requests from lxml import etreeif __name__ == '__main__':# UA伪装headers ...

  5. 二手车java爬虫技术_Golang爬虫 爬取汽车之家 二手车产品库

    目标 最近经常有人在耳边提起汽车之家,也好奇二手车在国内的价格是怎么样的,因此本次的目标站点是 汽车之家 的二手车产品库 分析目标源: 一页共24条 含分页,但这个老产品库,在100页后会存在问题,因 ...

  6. Python 爬虫实战入门——爬取汽车之家网站促销优惠与经销商信息

    在4S店实习,市场部经理让我写一个小程序自动爬取汽车之家网站上自家品牌的促销文章,因为区域经理需要各店上报在网站上每一家经销商文章的露出频率,于是就自己尝试写一个爬虫,正好当入门了. 一.自动爬取并输 ...

  7. python爬虫入门练习:BeautifulSoup爬取猫眼电影TOP100排行榜,pandas保存本地excel文件

    传送门:[python爬虫入门练习]正则表达式爬取猫眼电影TOP100排行榜,openpyxl保存本地excel文件 对于上文使用的正则表达式匹配网页内容,的确是有些许麻烦,替换出现任何的差错都会导致 ...

  8. 从入门到入土:Python爬虫学习|实例练手|爬取百度翻译|Selenium出击|绕过反爬机制|

    此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...

  9. 从入门到入土:Python爬虫学习|实例练手|爬取百度产品列表|Xpath定位标签爬取|代码注释详解

    此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...

最新文章

  1. 《Pro ASP.NET MVC 3 Framework》学习笔记之二十七【视图1】
  2. 重入锁、死锁、活锁、公平非公平锁……一下子都给你屡清楚了
  3. [Kafka与Spark集成系列一] Spark入门
  4. linux组手机nas,linux 搭建nas服务器
  5. 使用 Blazor 开发内部后台(四):基于Card组件快速搭建导航首页
  6. 别以为程序员的工作就是写代码
  7. CAN笔记(15) STM32-M4 CAN通讯
  8. mysql中union,左连接,右连接,与内连接
  9. python类和对象基础_Python(基础)---类和面向对象编程
  10. Python中,如何使用ImageDraw在Image上绘制粗线?
  11. PLSQL使用相关详细配置
  12. matlab如何进行图像读取,matlab如何读取图像
  13. HTML网页图片滚动代码
  14. 快速云:管理企业中云蔓延的7个技巧
  15. 请将标为Service Pack 2 CD-ROM的光盘插入CD-ROM驱动器(D:),然后单击确定。如何解决? 在windows server 2003服务器上。
  16. 计算机书籍推荐 活着,信息朗读者 |《活着》——19级计算机实验班蔺子健
  17. Ubuntu系统配置花生壳内网穿透
  18. Django笔记 CMS框架Mezzanine 2
  19. 函数指针的用法以及用途详解
  20. 商业竞争中的战争策略 - 读《商战》

热门文章

  1. 芜湖,这是一棵会唱歌的圣诞树
  2. php gvim,Windows下gvim配置
  3. 关于启用EBS应收票据的设置
  4. 一个充满争议的末代皇帝——崇祯
  5. STM32一线协议-DS18B20温度传感器采样实现
  6. 关于机器人状态估计(1)-高斯分布应用
  7. 画图流程图需要使用软件
  8. 汽车OS 大战背后:关于制造商、谷歌、安卓和 Android Auto,QNX
  9. 黑泽明和他的电影(七武士)
  10. 【毕业设计】大数据购物商品数据关联分析 - Apriori python