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用fork来创建子进程注意事项
Jul 03 Python
详细介绍Python的鸭子类型
Sep 12 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
Feb 14 Python
python+selenium开发环境搭建图文教程
Aug 11 Python
Python中的pygal安装和绘制直方图代码分享
Dec 08 Python
Python入门学习指南分享
Apr 11 Python
分享一下Python数据分析常用的8款工具
Apr 29 Python
Python selenium抓取微博内容的示例代码
May 17 Python
python微信公众号之关键词自动回复
Jun 15 Python
Python实现微信自动好友验证,自动回复,发送群聊链接方法
Feb 21 Python
Python 识别12306图片验证码物品的实现示例
Jan 20 Python
翻转数列python实现,求前n项和,并能输出整个数列的案例
May 03 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
PHP Pear 安装及使用
2009/03/19 PHP
MySQL连接数超过限制的解决方法
2011/07/17 PHP
php封装的表单验证类完整实例
2016/10/19 PHP
laravel5.4利用163邮箱发送邮件的步骤详解
2017/09/22 PHP
PHP封装的非对称加密RSA算法示例
2018/05/28 PHP
jQuery Ajax方法调用 Asp.Net WebService 的详细实例代码
2011/04/27 Javascript
按下回车键指向下一个位置的一个函数代码
2014/03/10 Javascript
复制网页内容,粘贴之后自动加上网址的实现方法(脚本之家特别整理)
2014/10/16 Javascript
jQuery实现折线图的方法
2015/02/28 Javascript
javascript删除元素节点removeChild()用法实例
2015/05/26 Javascript
js实现可控制左右方向的无缝滚动效果
2016/05/29 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
2016/12/26 Javascript
如何获取TypeScript的声明文件.d.ts
2018/05/01 Javascript
Vue自定义toast组件的实例代码
2018/08/15 Javascript
Vue实现点击显示不同图片的效果
2019/08/10 Javascript
Python根据文件名批量转移图片的方法
2018/10/21 Python
Django使用Channels实现WebSocket的方法
2019/07/28 Python
Tensorflow:转置函数 transpose的使用详解
2020/02/11 Python
Python日志:自定义输出字段 json格式输出方式
2020/04/27 Python
Django中Q查询及Q()对象 F查询及F()对象用法
2020/07/09 Python
Python图像处理二值化方法实例汇总
2020/07/24 Python
利用Python将图片中扭曲矩形的复原
2020/09/07 Python
美国知名的摄影器材销售网站:Adorama
2017/02/01 全球购物
阿联酋航空官方网站:Emirates
2017/10/17 全球购物
导游实习生自荐书
2014/01/28 职场文书
运动会稿件50字
2014/02/17 职场文书
幼儿园教师演讲稿
2014/05/06 职场文书
公司周年庆活动方案
2014/08/25 职场文书
关于读书的演讲稿500字
2014/08/27 职场文书
简单的离婚协议书范本
2014/11/16 职场文书
2015年新学期寄语
2015/02/26 职场文书
投资公司董事长岗位职责
2015/04/16 职场文书
微信搭讪开场白
2015/05/28 职场文书
代码解析React中setState同步和异步问题
2021/06/03 Javascript
postgresql 删除重复数据案例详解
2021/08/02 PostgreSQL
正则表达式基础与常用验证表达式
2022/06/16 Javascript