CrawlSpider

classscrapy.contrib.spiders.CrawlSpider

爬取一般站点经常使用的spider。其定义了一些规则(rule)来提供跟进link的方便的机制。 或许该spider并非全然适合您的特定站点或项目,但其对非常多情况都使用。 因此您能够以其为起点,依据需求改动部分方法。当然您也能够实现自己的spider。

除了从Spider继承过来的(您必须提供的)属性外,其提供了一个新的属性:

rules: Rule对象集合。定义了提取须要跟进url的一些规则。

parse_start_url(response):start_url的回调函数,返回Item或者Request对象的迭代。

基本函数的调用顺序和Spider类一样。见(Spider类源代码分析

  1. class CrawlSpider(Spider):
  2. rules = ()
  3. def __init__(self, *a, **kw):
  4. super(CrawlSpider, self).__init__(*a, **kw)
  5. self._compile_rules()
  6.  
  7. #首先调用parse()来处理start_urls中返回的response对象
  8. #parse()则将这些response对象传递给了_parse_response()函数处理。并设置回调函数为parse_start_url()
  9. #设置了跟进标志位True
  10. #parse将返回item和跟进了的Request对象
  11. def parse(self, response):
  12. return self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)
  13.  
  14. #处理start_url中返回的response。须要重写
  15. def parse_start_url(self, response):
  16. return []
  17.  
  18. def process_results(self, response, results):
  19. return results
  20.  
  21. #从response中抽取符合任一用户定义'规则'的链接。并构造成Resquest对象返回
  22. def _requests_to_follow(self, response):
  23. if not isinstance(response, HtmlResponse):
  24. return
  25. seen = set()
  26. #抽取之内的全部链接,仅仅要通过随意一个'规则'。即表示合法
  27. for n, rule in enumerate(self._rules):
  28. links = [l for l in rule.link_extractor.extract_links(response) if l not in seen]
  29. #使用用户指定的process_links处理每一个连接
  30. if links and rule.process_links:
  31. links = rule.process_links(links)
  32. #将链接增加seen集合,为每一个链接生成Request对象,并设置回调函数为_repsonse_downloaded()
  33. for link in links:
  34. seen.add(link)
  35. #构造Request对象,并将Rule规则中定义的回调函数作为这个Request对象的回调函数
  36. r = Request(url=link.url, callback=self._response_downloaded)
  37. r.meta.update(rule=n, link_text=link.text)
  38. #对每一个Request调用process_request()函数。
  39.  
  40. 该函数默觉得indentify,即不做不论什么处理,直接返回该Request.
  41. yield rule.process_request(r)
  42. #处理通过rule提取出的连接。并返回item以及request
  43. def _response_downloaded(self, response):
  44. rule = self._rules[response.meta['rule']]
  45. return self._parse_response(response, rule.callback, rule.cb_kwargs, rule.follow)
  46.  
  47. #解析response对象,会用callback解析处理他。并返回request或Item对象
  48. def _parse_response(self, response, callback, cb_kwargs, follow=True):
  49. #首先推断是否设置了回调函数。(该回调函数可能是rule中的解析函数。也可能是 parse_start_url函数)
  50. #假设设置了回调函数(parse_start_url())。那么首先用parse_start_url()处理response对象,
  51. #然后再交给process_results处理。返回cb_res的一个列表
  52. if callback:
  53. #假设是parse调用的,则会解析成Request对象
  54. #假设是rule callback,则会解析成Item
  55. cb_res = callback(response, **cb_kwargs) or ()
  56. cb_res = self.process_results(response, cb_res)
  57. for requests_or_item in iterate_spider_output(cb_res):
  58. yield requests_or_item
  59.  
  60. #假设须要跟进,那么使用定义的Rule规则提取并返回这些Request对象
  61. if follow and self._follow_links:
  62. #返回每一个Request对象
  63. for request_or_item in self._requests_to_follow(response):
  64. yield request_or_item
  65.  
  66. def _compile_rules(self):
  67. def get_method(method):
  68. if callable(method):
  69. return method
  70. elif isinstance(method, basestring):
  71. return getattr(self, method, None)
  72.  
  73. self._rules = [copy.copy(r) for r in self.rules]
  74. for rule in self._rules:
  75. rule.callback = get_method(rule.callback)
  76. rule.process_links = get_method(rule.process_links)
  77. rule.process_request = get_method(rule.process_request)
  78.  
  79. def set_crawler(self, crawler):
  80. super(CrawlSpider, self).set_crawler(crawler)
  81. self._follow_links = crawler.settings.getbool('CRAWLSPIDER_FOLLOW_LINKS', True)

Scrapy源代码分析-经常使用的爬虫类-CrawlSpider(三)的更多相关文章

  1. ffdshow 源代码分析 9: 编解码器有关类的总结

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  2. ffdshow 源代码分析 8: 视频解码器类(TvideoCodecDec)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  3. Juce源代码分析(九)应用程序基类ApplicationBase

    在前面的几篇文章,分析的都是Juce库里面Core模块的内存部分,除了骨灰级C++爱好者之外,貌似大家对这些都不是非常感兴趣.相信大家更想知道Juce是怎么用于产品开发,而对于它的构成不是非常感兴趣. ...

  4. ffdshow 源代码分析 7: libavcodec视频解码器类(TvideoCodecLibavcodec)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  5. ffdshow 源代码分析 6: 对解码器的dll的封装(libavcodec)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  6. ffdshow 源代码分析 5: 位图覆盖滤镜(总结)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  7. ffdshow 源代码分析 4: 位图覆盖滤镜(滤镜部分Filter)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  8. ffdshow 源代码分析 3: 位图覆盖滤镜(设置部分Settings)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  9. ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

随机推荐

  1. Quartz实现执行任务记录数据库,方便计算任务的执行次数以及成功次数

    任务执行实体 /** * 任务执行情况详情 */ public class JobExecuteDetail implements Serializable{ /** * */ private sta ...

  2. cookie/session在nodes中的实战

    cookie 和 session 众所周知,HTTP 是一个无状态协议,所以客户端每次发出请求时,下一次请求无法得知上一次请求所包含的状态数据,如何能把一个用户的状态数据关联起来呢? 比如在淘宝的某个 ...

  3. ★Java面向对象(一)——————————基本概念

    package boll; /* 用Java语言对现实生活中的事物进行描述. 通过类的形式来体现, 怎么描述呢? 对于事物的描述通常只有两个方面,一个是属性,一个是行为. 只要明确该事物的行为和属性并 ...

  4. 微软CRM4.0 页面表单和腾讯QQ在线整合

    现在通过QQ和客户联系.洽谈业务及沟通感情的场合越来越多,在微软CRM表单上整合QQ可以方便的显示客户QQ在线状态,点击图标即可和客户进行QQ聊天. 客户在线状态: 客户离线状态: 输入QQ号码后即时 ...

  5. Visual Studio UI Automation 学习(二)

    今天恰好有时间,继续学习了一下UI Automation的知识.看了两篇博客,对UI Automation有了进一步的了解. https://blog.csdn.net/qq_37546891/art ...

  6. 时序分析:ARMA方法(平稳序列)

    憔悴到了转述中文综述的时候了........ 在统计学角度来看,时间序列分析是统计学中的一个重要分支, 是基于随机过程理论和数理统计学的一种重要方法和应用研究领域.  时间序列按其统计特性可分为平稳性 ...

  7. Swift Method Dispatching — a summary of my talk at Swift Warsaw

    Swift Method Dispatching When announcing Swift, Apple described it as being much faster than Objecti ...

  8. 怎样批量删除PDF文件中的注释

    日常我们在阅读一些PDF文章时候,我们会发现有些PDF文章带有非常多的注释,显得非常不美观,影响了阅读体验.那么PDF文章里的批注应该怎么进行删除呢?怎样批量删除PDF文件中的注释?   操作教程: ...

  9. 前端面试题总结 -vue

    1.active-class是哪个组件的属性? vue-router模块的router-link组件. 2.嵌套路由怎么定义? 在 VueRouter 的参数中使用 children 配置,这样就可以 ...

  10. turn.js中文API 写一个翻页效果的参数详细解释

    $('.flipbook').turn({     width: 922,     height: 600,     elevation: 50,     gradients: true,     a ...