周末的时候,老婆向我吐槽公司(某河互联)运营数据居然靠人工从汽车之家网站的搬运数据,他们老大给他们小组每个人还分配了任务,每人多少车型,限时完成。为了不让老婆这么费时费力地做些无用功,我决定帮她写个程序去爬汽车之家的数据。工欲善其事必先利其器,这次我决定用大名鼎鼎的scrapy来完成这个小任务。
scrapy框架简介
scrapy是大名鼎鼎的爬虫框架,以前也是只听说过没用过,这次现学现卖了。官网,文档
安装非常简单:
pip install scrapy
创建Autohome项目
安装完成之后,就需要创建一个项目来进行我们的爬取行动:
scrapy startproject authome
创建完之后在spiders文件夹下创建我们的spider文件:autohome_spider.py
获取汽车之家车型信息
我们需要先获取车的品牌信息,然后根据品牌信息获取子品牌的信息,然后具体到某个型号,才能开始抓取口碑,参数等信息。
汽车之家的品牌都在 http://car.autohome.com.cn/AsLeftMenu/As_LeftListNew.ashx?typeId=1%20&brandId={bid}%20&fctId=0%20&seriesId=0 这个连接里,其中brandId=0是所有的品牌,根据品牌的brandid再次传入这个url就能获取子品牌信息:
获取品牌信息的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31def parsebrand(self,response):
brands = response.xpath("//li")
brand_lib={}
for brand in brands:
brand_id = brand.xpath('attribute::id').extract()[0].split('b')[1]
brand_name = brand.xpath('h3/a/text()').extract()[0]
brand_lib[brand_name]=brand_id
#获取品牌库后,获取款式代码
data = xlrd.open_workbook('test.xls')
self.wb = copy(data)
sheet = data.sheets()[0]
brand,subrand,ctype=False,False,False
for row in range(1,sheet.nrows):
if sheet.cell(row,0).value:
brand = sheet.cell(row,0).value.strip() #汽车品牌
if sheet.cell(row,1).value:
subrand = sheet.cell(row,1).value.strip() #款式
if sheet.cell(row,3).value:
ctype = sheet.cell(row,3).value.strip() #具体型号
index = u"{brand}:{sub}:{ctype}".format(brand=brand,sub=subrand,ctype=ctype)
value = row
self.b_s_ctypes.append({index:value})
for row in self.b_s_ctypes:
for key,value in row.iteritems():
branb,subrand,ctype = key.split(':')
print branb,subrand,ctype,value
#获取品牌库下面的款式库
yield scrapy.Request(dont_filter=True,url=self.brand_url.format(bid=brand_lib[branb]),callback=lambda response,name=subrand,row=value,ctype=ctype: self.parsesub(response,name,row,ctype))
运行爬虫
到爬虫项目根目录下执行:scrapy crawl autohomed
重复连接的问题
scrapy 默认情况下是不会访问重复的连接的,所以我在循环中需要重复的访问某个连接获取子品牌的时候就只会获取到第一条信息。解决这个问题的方法,是在Request方法中加入dont_filter=True参数。
写入Excel
读写Excel是个老生常谈的问题了,引入xlrd,xlwt库,操作起来非常方便。