一、爬取准备
-
网站分析
-
总体分析:经过分析发现,中关村手机基本上都是传统的网页模式,并没有用到前后端分离(json传输数据),这个时候只要对页面的URL进行分析
-
URL分析:url也是规规矩矩的拼接
subcate57_list_1.html
末尾的list_1,这里的数字代替页数
-
然后通过每个手机的链接获得其手机代号(姑且取名叫代号吧)
手机信息url:cell_phone/index1241574.shtml 这个url里index后的几位数字即为手机代号 手机详细参数url:cn/1242/1241574/param.shtml 很容易发现中间的4位数字是后面长数字前4位+1(1242 = 1241xxxx+1),接下来可以开干了
-
二、代码
-
scrapy
-
代码很简单,就不贴出来了
... ...
-
考虑到要存入到Mysql数据库,一直苦于没有像MongoDB,redis那么好用,如果每条都建立一个连接,就scrapy这个爬取速度肯定是吃不消的,网上找了一个处理scrapy—mysql的例子,用起来挺舒服的,而且查看了Mysql,并没有造成阻塞,数据丢失,连接数爆炸等情况,所以重点分享一下这个Pipeline,最后记得到settings里启用
# pipelines.py class MysqlPipelineZ(object): def __init__(self, dbpool): self.dbpool = dbpool @classmethod def from_settings(cls, settings): """ 数据库建立连接 :param settings: 配置参数 :return: 实例化参数 """ adbparams = dict( host=settings['MYSQL_HOST'], db=settings['MYSQL_DB'], user=settings['MYSQL_USER'], password=settings['MYSQL_PASSWORD'], cursorclass=pymysql.cursors.DictCursor # 指定cursor类型 ) # 连接数据池ConnectionPool,使用pymysql dbpool = adbapi.ConnectionPool('pymysql', **adbparams) # 返回实例化参数 return cls(dbpool) def process_item(self, item, spider): """ 使用twisted将MySQL插入变成异步执行。通过连接池执行具体的sql操作,返回一个对象 """ query = self.dbpool.runInteraction(self.do_insert, item) # 指定操作方法和操作数据 # 添加异常处理 query.addCallback(self.handle_error) # 处理异常 def do_insert(self, cursor, item): # 对数据库进行插入操作,并不需要commit,twisted会自动commit insert_sql = """ insert into zolPhone(model,sellTime,updateTime) VALUES (%s,%s,%s) """ cursor.execute(insert_sql, (item['phone_name'], item['sell_time'], item['update_time'])) def handle_error(self, failure): if failure: # 打印错误信息 print(failure)
-
三、小结
整个爬取过程和速度非常满意,之前偷懒用requests爬取大约20min,改用scrapy大概40s,好久没写新的爬虫了,都快要忘记最初的兴趣了,希望来年多多历练,大家一起进步!
网友评论