python爬虫框架scrapy实战之爬取京东商城进阶篇


Posted in Python onApril 24, 2017

前言

之前的一篇文章已经讲过怎样获取链接,怎样获得参数了,详情请看python爬取京东商城普通篇,本文将详细介绍利用python爬虫框架scrapy如何爬取京东商城,下面话不多说了,来看看详细的介绍吧。

代码详解

1、首先应该构造请求,这里使用scrapy.Request,这个方法默认调用的是start_urls构造请求,如果要改变默认的请求,那么必须重载该方法,这个方法的返回值必须是一个可迭代的对象,一般是用yield返回。

代码如下:

def start_requests(self):
 for i in range(1,101):
 page=i*2-1 #这里是构造请求url的page,表示奇数
 url=self.start_url+str(page)
 yield scrapy.Request(url,meta={'search_page':page+1},callback=self.parse_url) #这里使用meta想回调函数传入数据,回调函数使用response.meta['search-page']接受数据

下面就是解析网页了,从上面看出这里的解析回调函数是parse_url,因此在此函数中解析网页。这里还是和上面说的一样,这个url得到的仅仅是前一半的信息,如果想要得到后一半的信息还有再次请求,这里还有注意的就是一个技巧:一般先解析出一个数据的数组,不急着取出第一个数,先要用if语句判断,因为如果得到的是[],那么直接取出[0]是会报错的,这只是一个避免报错的方法吧。

代码如下:

def parse_url(self,response):
 if response.status==200: #判断是否请求成功
 # print response.url
 pids = set() #这个集合用于过滤和保存得到的id,用于作为后面的ajax请求的url构成
 try:
 all_goods = response.xpath("//div[@id='J_goodsList']/ul/li") #首先得到所有衣服的整个框架,然后从中抽取每一个框架
 for goods in all_goods: #从中解析每一个
 # scrapy.shell.inspect_response(response,self) #这是一个调试的方法,这里会直接打开调试模式
 items = JdSpiderItem() #定义要抓取的数据
 img_url_src = goods.xpath("div/div[1]/a/img/@src").extract() # 如果不存在就是一个空数组[],因此不能在这里取[0]
 img_url_delay = goods.xpath(
  "div/div[1]/a/img/@data-lazy-img").extract() # 这个是没有加载出来的图片,这里不能写上数组取第一个[0]
 price = goods.xpath("div/div[3]/strong/i/text()").extract() #价格
 cloths_name = goods.xpath("div/div[4]/a/em/text()").extract()
 shop_id = goods.xpath("div/div[7]/@ data-shopid").extract()
 cloths_url = goods.xpath("div/div[1]/a/@href").extract()
 person_number = goods.xpath("div/div[5]/strong/a/text()").extract()
 pid = goods.xpath("@data-pid").extract()
 # product_id=goods.xpath("@data-sku").extract()
 if pid:
  pids.add(pid[0])
 if img_url_src: # 如果img_url_src存在
  print img_url_src[0]
  items['img_url'] = img_url_src[0]
 if img_url_delay: # 如果到了没有加载完成的图片,就取这个url
  print img_url_delay[0]
  items['img_url'] = img_url_delay[0] # 这里如果数组不是空的,就能写了
 if price:
  items['price'] = price[0]
 if cloths_name:
  items['cloths_name'] = cloths_name[0]
 if shop_id:
  items['shop_id'] = shop_id[0]
  shop_url = "https://mall.jd.com/index-" + str(shop_id[0]) + ".html"
  items['shop_url'] = shop_url
 if cloths_url:
  items['cloths_url'] = cloths_url[0]
 if person_number:
  items['person_number'] = person_number[0]
 # if product_id:
 # print "************************************csdjkvjfskvnk***********************"
 # print self.comments_url.format(str(product_id[0]),str(self.count))
 # yield scrapy.Request(url=self.comments_url.format(str(product_id[0]),str(self.count)),callback=self.comments)
 #yield scrapy.Request写在这里就是每解析一个键裤子就会调用回调函数一次
 yield items
 except Exception:
 print "********************************************ERROR**********************************************************************"
 yield scrapy.Request(url=self.search_url.format(str(response.meta['search_page']),",".join(pids)),callback=self.next_half_parse) #再次请求,这里是请求ajax加载的数据,必须放在这里,因为只有等到得到所有的pid才能构成这个请求,回调函数用于下面的解析

2、从上面代码的最后可以看出最后就是解析ajax加载的网页了,这里调用的next_half_parse函数,和解析前面一个网页一样,这里需要的注意的是,如果前面定义的数据没有搜索完毕是不能使用yield items的,必须将items通过meta传入下一个回调函数继续完善后才能yield items,这里就不需要了。

代码如下:

#分析异步加载的网页
 def next_half_parse(self,response):
 if response.status==200:
 print response.url
 items=JdSpiderItem()
 #scrapy.shell.inspect_response(response,self) #y用来调试的
 try:
 lis=response.xpath("//li[@class='gl-item']")
 for li in lis:
  cloths_url=li.xpath("div/div[1]/a/@href").extract()
  img_url_1=li.xpath("div/div[1]/a/img/@src").extract()
  img_url_2=li.xpath("div/div[1]/a/img/@data-lazy-img").extract()
  cloths_name=li.xpath("div/div[4]/a/em/text()").extract()
  price=li.xpath("div/div[3]/strong/i/text()").extract()
  shop_id=li.xpath("div/div[7]/@data-shopid").extract()
  person_number=li.xpath("div/div[5]/strong/a/text()").extract()
  if cloths_url:
  print cloths_url[0]
  items['cloths_url']=cloths_url[0]
  if img_url_1:
  print img_url_1[0]
  items['img_url']=img_url_1
  if img_url_2:
  print img_url_2[0]
  items['img_url']=img_url_2[0]
  if cloths_name:
  items['cloths_name']=cloths_name[0]
  if price:
  items['price']=price[0]
  if shop_id:
  items['shop_id']=shop_id[0]
  items['shop_url']="https://mall.jd.com/index-" + str(shop_id[0]) + ".html"
  if person_number:
  items['person_number']=person_number[0]
  yield items #又一次的生成,这里是完整的数据,因此可以yield items
 except Exception:
 print "**************************************************"

3、当然这里还用到了设置请求池,mysql存储,没有使用到ip代理,这个在我前面的博客中又讲到,这里就不再赘述了。

想看源代码的朋友请

小技巧

  • 人们会抱怨为什么自己的爬虫在中途断开就要重头开始爬,为什么不能从断开那里开始爬呢,这里提供一个方法:在配置文件settings.py中加入JOBDIR=file_name,这里的file_name是一个文件的名字
  • 设置下载延迟防止被ban:DOWNLOAD_DELAY = 2:设置每一次的间隔时间 RANDOMIZE_DOWNLOAD_DELAY = True:这个是随机设置延迟时间 在设置的时间的0.5-1.5倍之间,这样可以更有效的防止被ban,一般是配套使用的
  • ROBOTSTXT_OBEY = False :这里是表示不遵循robots.txt文件,默认是True表示遵循,这里将之改成False
  • CONCURRENT_REQUESTS :设置最大请求数,这里默认的时16,我们可以根据自己电脑的配置改的大一点来加快请求的速度

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python字符串格式化输出方法分析
Apr 13 Python
同时安装Python2 & Python3 cmd下版本自由选择的方法
Dec 09 Python
Python使用wxPython实现计算器
Jan 30 Python
TensorFlow平台下Python实现神经网络
Mar 10 Python
Python实现的逻辑回归算法示例【附测试csv文件下载】
Dec 28 Python
Python最小二乘法矩阵
Jan 02 Python
python 对类的成员函数开启线程的方法
Jan 22 Python
pandas 数据结构之Series的使用方法
Jun 21 Python
python使用百度文字识别功能方法详解
Jul 23 Python
python 两个一样的字符串用==结果为false问题的解决
Mar 12 Python
Python数据正态性检验实现过程
Apr 18 Python
Python 使用office365邮箱的示例
Oct 29 Python
python爬虫实战之爬取京东商城实例教程
Apr 24 #Python
python中urllib.unquote乱码的原因与解决方法
Apr 24 #Python
Python面向对象特殊成员
Apr 24 #Python
Python解惑之整数比较详解
Apr 24 #Python
Python解惑之True和False详解
Apr 24 #Python
Python新手入门最容易犯的错误总结
Apr 24 #Python
Python正则抓取新闻标题和链接的方法示例
Apr 24 #Python
You might like
关于时间计算的结总
2006/12/06 PHP
php 无法加载mysql的module的时候的配置的解决方案引发的思考
2012/01/27 PHP
php动态生成缩略图并输出显示的方法
2015/04/20 PHP
thinkPHP5.0框架命名空间详解
2017/03/18 PHP
jquery+json 通用三级联动下拉列表
2010/04/19 Javascript
jquery弹出框的用法示例(2)
2013/08/26 Javascript
jquery validate添加自定义验证规则(验证邮箱 邮政编码)
2013/12/04 Javascript
javascript学习笔记(八)正则表达式
2014/10/08 Javascript
JavaScript跨平台的开源框架NativeScript
2015/03/24 Javascript
轻松实现javascript数据双向绑定
2015/11/11 Javascript
详解JavaScript中的自定义事件编写
2016/05/10 Javascript
jquery表单插件Autotab使用方法详解
2016/06/24 Javascript
jQuery 更改checkbox的状态,无效的解决方法
2016/07/22 Javascript
jQuery实现表格文本框淡入更改值后淡出效果
2016/09/27 Javascript
jQuery点击页面其他部分隐藏下拉菜单功能
2018/11/27 jQuery
Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验
2019/04/22 Javascript
jQuery实现动态生成年月日级联下拉列表示例
2019/05/11 jQuery
nodejs脚本centos开机启动实操方法
2020/03/04 NodeJs
[01:01:23]完美世界DOTA2联赛PWL S2 Forest vs FTD.C 第一场 11.26
2020/11/30 DOTA
Python+Django在windows下的开发环境配置图解
2009/11/11 Python
基于python的字节编译详解
2017/09/20 Python
Python语言描述随机梯度下降法
2018/01/04 Python
python装饰器-限制函数调用次数的方法(10s调用一次)
2018/04/21 Python
python3读取csv和xlsx文件的实例
2018/06/22 Python
Selenium鼠标与键盘事件常用操作方法示例
2018/08/13 Python
python实现zabbix发送短信脚本
2018/09/17 Python
在tensorflow中实现屏蔽输出的log信息
2020/02/04 Python
matplotlib源码解析标题实现(窗口标题,标题,子图标题不同之间的差异)
2021/02/22 Python
Clarria化妆品官方网站:购买天然和有机化妆品系列
2018/04/08 全球购物
Ellesse英国官网:意大利高级运动品牌
2019/07/23 全球购物
董事长岗位职责
2013/11/30 职场文书
宿舍违规检讨书
2014/01/12 职场文书
代理班主任的自我评价
2014/02/04 职场文书
保护环境演讲稿
2014/05/10 职场文书
中学生纪念九一八事变演讲稿
2014/09/14 职场文书
windows系统安装配置nginx环境
2022/06/28 Servers