学习自:Python Scrapy 爬虫框架实例(一) - Blue·Sky - 博客园

这一节是对前两节内容的补充,涉及内容为一些额外的类与方法,来对原代码进行改进

原代码:这里并没有用前两节的代码,而是用了另一个爬虫的代码,作用是爬取千图网的图片信息。该爬虫的基本信息:

项目名:AdilCrawler

爬虫名:thousandPic

网址:www.58pic.com

开始爬取的网址:https://www.58pic.com/c/

Item类:AdilcrawlerItem

xpath表达式:

  1. Author:/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()
  2. Name:/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()
  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. # 这里使用 import 或是 下面from 的方式都行,关键要看 当前项目在pycharm的打开方式,是否是作为一个项目打开的,建议使用这一种方式。
  4. import AdilCrawler.items as items
  5.  
  6. class ThousandpicSpider(scrapy.Spider):
  7. name = 'thousandPic'
  8. allowed_domains = ['www.58pic.com']
  9. start_urls = ['https://www.58pic.com/c/']
  10.  
  11. def parse(self, response):
  12.  
  13. item = items.AdilcrawlerItem()
  14. author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
  15. theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
  16. item['author'] = author
  17. item['theme'] = theme
  18. return item

补充内容

1、日志打印,写在parse方法下:

  1. def parse(self,response):
  2. ...
  3. self.log(author)
  4. ...

2、ItemLoader类:代替extract()、xpath()方法

1)从scrapy.loader导入ItemLoader

  1. from scrapy.loader import ItemLoader

2)优化,写在spider.py文件

用add_xpath方法,代替XPath提取语句:xpath(xxx).extract()

  1. import scrapy
  2. from AdilCrawler.items import AdilcrawlerItem
  3. from scrapy.loader import ItemLoader
  4.  
  5. class ThousandpicoptimizeSpider(scrapy.Spider):
  6. name = 'thousandPicOptimize'
  7. allowed_domains = ['www.58pic.com']
  8. start_urls = ['http://www.58pic.com/c/']
  9.  
  10. def parse(self, response):
  11. i = ItemLoader(item = AdilcrawlerItem(),response = response )
  12. i.add_xpath('author','/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()')
  13. i.add_xpath('theme','/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()')
  14. return i.load_item()

相当于:

  1. i = items.AdilcrawerItem()
  2. author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
  3. theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
  4. i['author'] = author
  5. i['theme'] = theme
  6. yield i

  7. ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

  8. i = ItemLoader(item = AdilcrawlerItem(),response = response )
  9.      i.add_xpath('author','/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()')
  10.      i.add_xpath('theme','/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()')
  11. yield i.load_item()

3)修改pipelines.py,目的是将爬取到的内容保存到文件中;

Spider中爬取到的内容都会以参数item的形式传入pipelines.py文件中的相关方法,比如process_item,(这一点很重要,且对所有类型的爬虫都适用)

  1. import json
  2.  
  3. class AdilcrawlerPipeline(object):
  4. def __init__(self):
  5. self.filename = open('thousandPic.json','w')
  6. def process_item(self, item, spider):
  7. # ensure_ascii=False 可以解决 json 文件中 乱码的问题。
  8. text = json.dumps(dict(item), ensure_ascii=False) + ',\n' # 这里是一个字典一个字典存储的,后面加个 ',\n' 以便分隔和换行。
  9. self.filename.write(text)
  10.     return item
  11. def close_spider(self,spider):
  12. self.filename.close()

至于json序列化保存的方法,可以参考序列化 pickle JSON - ShineLe - 博客园

4)修改settings.py

  1. ITEM_PIPELINES = {
  2. 'AdilCrawler.pipelines.AdilcrawlerPipeline': 300,
  3. }
  4. # 加入后,相当于开启pipeline,此时在执行爬虫,会执行对应的pipelines下的类,并执行该类相关的方法,比如这里上面的保存数据功能。

5)执行;由于在pipelines.py中已经写了文件保存方法,故此处不用-o参数输出为文件

  1. scrapy crawl thousandPicOptimize

3、CrawlSpider类:翻页抓取

1)使用crawl模板创建一个CrawlSpider PicSpi(CrawlSpider的生成,与普通Spider不同)

  1. scrapy genspider -t crawl PicSpi www.58pic.com

2)items.py:与之前相同;

  1. import scrapy
  2. class PicsItem(scrapy.Item):
  3. authod=scrapy.Field() #作者
  4. theme=scrapy.Field() #主题

pipelines.py同2

3)Spider文件PicSpi.py

需要用到另外三个类:LinkExtractor、CrawlSpider、Rule

  1. from scrapy.linkextractors import LinkExtractor
  2. from scrapy.spider import CrawlSpider,Rule

完整代码:

  1. # 导入链接规则匹配类,用来提取符合规则的链接
  2. from scrapy.linkextractors import LinkExtractor
  3. # 导入CrawlSpider类和Rule              (①)
  4. from scrapy.spiders import CrawlSpider, Rule
  5. import AdilCrawler.items as items
  6.  
  7. class ThousandpicpagingSpider(CrawlSpider):
  8. name = 'thousandPicPaging'
  9. allowed_domains = ['www.58pic.com']
  10. start_urls = ['https://www.58pic.com/c/']
  11.  
  12. # Response中的链接提取规则,返回符合规则的链接匹配对象的List
  13. # 根据翻页链接地址 http://www.58pic.com/c/1-0-0-03.html 找到相应的正则表达式
  14. # 不能使用restrict_xpath,否则正则将失效
  15.    #(②)
  16. page_link = LinkExtractor(allow='https://www.58pic.com/c/\S-\S-\S-\S\S.html', allow_domains='www.58pic.com')
  17.    #(③)
  18. rules = (
  19. Rule(page_link, callback='parse_item', follow=True), # 此处的 ','不能省略
  20. )
  21.  
  22. # 方法parse_start_url是为了解决parse_item()不能抓取第一页数据的问题
  23. # 原因是第一页的正则表达式形式与之后若干页不同
  24. # 该方法是CrawlSpider类下的方法,这里重写一下即可
  25.   #(④)
  26. def parse_start_url(self, response):
  27. i = items.AdilcrawerItem()
  28. author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
  29. theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
  30. i['author'] = author
  31. i['theme'] = theme
  32. yield i
  33.   #(⑤)
  34. def parse_item(self, response):
  35. i = items.AdilcrawerItem()
  36. author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
  37. theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
  38. i['author'] = author
  39. i['theme'] = theme
  40. yield i

对这段代码的说明:

①:库的导入,这一部分的内容是在通过指令生成CrawlSpider的时候自动生成的

②:得到每一页的链接

  1. page_link = LinkExtractor(allow='https://www.58pic.com/c/\S-\S-\S-\S\S.html', allow_domains='www.58pic.com')

LInkExtractor构建链接时,需要参数allow与allow_domains,参数allow是各页URL的完整正则表达式,allow_domains是限定访问的范围;这样page_link便保存了访问每一页的方法。

③:根据每页链接构建访问规则

  1. rules = (
  2. Rule(page_link, callback='parse_item', follow=True), # 此处的 ','不能省略
  3. )

a、用Rule方法,参数有三项:page_link、callback、follow,作用分别是:

page_link:②中构建的链接,由于是正则表达式,所以是一系列的链接

callback:对这些链接进行处理的函数,需要在之后补充在同一个类中

follow:是否根据链接自动进行下去

b、最后,必须加,逗号,以表明这是一个Tuple元组

④:访问第一页(针对第一页URL不与正则表达式相匹配的情况):parse_start_url

⑤:访问其他页(代码相同,只是方法名不同):parse_item

  1. i = items.AdilcrawerItem()
  2. author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
  3. theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
  4. i['author'] = author
  5. i['theme'] = theme
  6. yield i

代码内容与普通情况下的要素提取相同

4)运行;运行方法倒是相同

  1. scrapy crawl thousandPicPaging

4、综合,将2、3结合起来,同时使用ItemLoader、CrawlSpider

  1. import scrapy
  2. from scrapy.loader import ItemLoader
  3. from scrapy.spiders import CrawlSpider,Rule
  4. import AdilCrawler.items as items
  5.  
  6. class ThousandpicpagingopSpider(CrawlSpider):
  7. name='thousandPicPagingOp'
  8. allowed_domains = ['www.58pic.com']
  9. start_urls = ['http://www.58pic.com/c/']
  10.  
  11. page_link=LinkExtractor(allow='http://www.58pic.com/c/\S-\S-\S-\S\S.html',allow_domains='www.58pic.com')
  12. rules=(
  13. Rule(page_link,callback='parse_item',follow=True),
  14. )
  15.  
  16. def parse_start_url(self,response):
  17. i=ItemLoader(item=items.AdilcrawlerItem(),response=response)
  18. i.add_xpath('author','/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()')
  19.      i.add_xpath('theme','/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()')
  20. yield i.load_item()
  21.  
  22. def parse_item(self, response):
  23. i = ItemLoader(item = items.AdilcrawlerItem(),response = response )
  24. i.add_xpath('author','/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()')
  25. i.add_xpath('theme','/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()')
  26.  
  27. yield i.load_item()

5、总结

用CrawlSpider和ItemLoader写一个可以自动翻页的爬虫的一般流程及文件配置。

1)创建项目与爬虫

  1. scrapy startproject XXX
  2. scrapy genspider -t crawl xxxS url

2)items.py

  1. import scrapy
  2.  
  3. class xxxItem(scrapy.Item):
  4. attr1=scrapy.Field()
  5. attr2=scrapy.Field()
  6. ...
  7. attrn=scrapy.Field()

3)pipelines.py

  1. import json
  2.  
  3. class xxxPipeline(object):
  4. def __init__(self):
  5. self.filename = open('xxx.json','w') #保存文件
  6.  
  7. def process_item(self,item,spider):
  8. # ensure_ascii=False 可以解决 json 文件中 乱码的问题。
  9. text = json.dumps(dict(item), ensure_ascii=False)
  10. self.filename.write(text)
  11. return item
  12. def close_spider(self,spider):
  13. self.filename.close()

4)settings.py

  1. BOT_NAME =
  2. SPIDER_MODULES =
  3. NEWSPIDER_MODULE =
  4. ROBOTSTXT_OBEY = False
  5. ITEM_PIPELINES = {
  6. 'XXX.pipelines.xxxPipeline': 300,
  7. }

5)spider.py

  1. import scrapy
  2. from scrapy.linkextractors import LinkExtractor
  3. from scrapy.loader import ItemLoader
  4. from scrapy.spiders import CrawlSpider, Rule
  5. import XXX.items as items
  6.  
  7. class XXXSpider(CrawlSpider):
  8. name = 'xxxS'
  9. allowed_domains = ['url']
  10. start_urls = ['url']
  11.  
  12. page_link = LinkExtractor(allow='url regex', allow_domains='url')
  13. rules = (
  14. Rule(page_link, callback='parse_item', follow=True),
  15. )
  16.  
  17. #处理首页
  18. def parse_start_url(self, response):
  19. i = ItemLoader(item = items.XXXItem(),response = response )
  20. i.add_xpath('attr1','attr1 xpath')
  21. i.add_xpath('attr2','attr2 xpath')
  22. yield i.load_item()
  23.  
  24. # 处理其他页
  25. def parse_item(self, response):
  26. i = ItemLoader(item = items.XXXItem(),response = response )
  27. i.add_xpath('attr1','attr1 xpath')
  28. i.add_xpath('attr2','attr2 xpath')
  29. yield i.load_item()

6)运行爬虫

  1. scrapy crawl xxxS

Python:Scrapy(三) 进阶:额外的一些类ItemLoader与CrawlSpider,使用原理及总结的更多相关文章

  1. python进阶01 面向对象、类、实例、属性封装、实例方法

    python进阶01 面向对象.类.实例.属性封装.实例方法 一.面向对象 1.什么是对象 #一切皆对象,可以简单地将“对象”理解为“某个东西” #“对象”之所以称之为对象,是因为它具有属于它自己的“ ...

  2. Python进阶开发之元类编程

    系列文章 √第一章 元类编程,已完成 ; 本文目录 类是如何产生的如何使用type创建类理解什么是元类使用元类的意义元类实战:ORM . 类是如何产生的 类是如何产生?这个问题肯定很傻.实则不然,很多 ...

  3. 孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习

     孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.close() 当一个file对象执行此方法时,将关闭当前 ...

  4. python scrapy 抓取脚本之家文章(scrapy 入门使用简介)

    老早之前就听说过python的scrapy.这是一个分布式爬虫的框架,可以让你轻松写出高性能的分布式异步爬虫.使用框架的最大好处当然就是不同重复造轮子了,因为有很多东西框架当中都有了,直接拿过来使用就 ...

  5. python基础——面向对象进阶下

    python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...

  6. 【转】Python之函数进阶

    [转]Python之函数进阶 本节内容 上一篇中介绍了Python中函数的定义.函数的调用.函数的参数以及变量的作用域等内容,现在来说下函数的一些高级特性: 递归函数 嵌套函数与闭包 匿名函数 高阶函 ...

  7. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  8. python Scrapy安装和介绍

    python Scrapy安装和介绍 Windows7下安装1.执行easy_install Scrapy Centos6.5下安装 1.库文件安装yum install libxslt-devel ...

  9. python 面向对象终极进阶之开发流程

    好了,你现在会了面向对象的各种语法了,  但是你会发现很多同学都是学会了面向对象的语法,却依然写不出面向对象的程序,原因是什么呢?原因就是因为你还没掌握一门面向对象设计利器, 此刻有经验的人可能会想到 ...

随机推荐

  1. react diff算法浅析

    diff算法作为Virtual DOM的加速器,其算法的改进优化是React整个界面渲染的基础和性能的保障,同时也是React源码中最神秘的,最不可思议的部分 1.传统diff算法计算一棵树形结构转换 ...

  2. linux安装第三方软件 python3

    一:linux安装python3 安装第三方软件的目录 进入目录 /usr/local 下载rpm安装包 安装pyton yum安装python : yum install python3 查看pyt ...

  3. Floyd 循环检测算法(快慢指针法/龟兔指针法)

    Floyd Cycle Detection Algorithm   Floyd Cycle Detection Algorithm,即 Floyd 循环检测算法,又称快慢指针法.龟兔指针法.该算法用于 ...

  4. String Reversal

    Educational Codeforces Round 96 (Rated for Div. 2) - E. String Reversal 跳转链接 题目描述 定义一个操作为交换字符串中相邻的两个 ...

  5. ApacheCN 数据科学译文集 2020.8

    协议:CC BY-NC-SA 4.0 不要担心自己的形象,只关心如何实现目标.--<原则>,生活原则 2.3.c 在线阅读 ApacheCN 面试求职交流群 724187166 Apach ...

  6. 掌握这些常用Linux命令,一起提升工作效率

    开始上班了,新一年的奋斗的之路启程了,要继续[奔赴山海,奔赴热爱]. 汪国真在<热爱生命>这首诗中写到:既然选择了远方,便只顾风雨兼程.技术上还是持续精进和学习,远方虽远,要迈开脚步,一步 ...

  7. 「JOI 2014 Final」裁剪线

    做法一 首先将边界也视作四条裁剪线,整个平面作为一张纸,视存在 \(y = -\infty, y = +\infty, x = -\infty, x = +\infty\) 四条直线. 按照纵坐标依次 ...

  8. Java泛型T与?

    感谢大佬:http://m.mamicode.com/info-detail-2657551.html 一.区别 单独的T 代表一个类型 ,而 Class<T>代表这个类型所对应的类, C ...

  9. 获取缓存文件大小并清理 By HL

    通常用于删除缓存的时,计算缓存大小 //单个文件的大小 - (long long) fileSizeAtPath:(NSString*) filePath{ NSFileManager* manage ...

  10. Apache——配置与应用

    Apache配置与应用 1.概述 2.httpd服务支持的虚拟主机类型 3.构建虚拟Web主机 4.构建Web虚拟目录与用户授权限制 5.日志分割 6.AWStats分析系统 1.概述: 虚拟web主 ...