爬虫:Scrapy之CrawlSpiader的使用

无人久伴 提交于 2019-11-30 09:28:12

1.我的目的

  • 了解Scrapy的CrawlSpider并使用

2.例子

  • 爬取豆瓣读书的所有小说的详情页面
    • 每一页的url
      /tag/小说?start=7600 、 /tag/小说?start=60
      正则匹配这些字符的话写法是 ” /tag/小说?start=[0-9]* “
      在这里插入图片描述
    • 某一部小说的url
      https://book.douban.com/subject/1045818/
      https://book.douban.com/subject/1046265/
      正则匹配这些字符的话写法是 " https://book.douban.com/subject/[0-9]*?/$ "
      (这里加$是为了结尾匹配,不匹配结尾的话能匹配到这种url ”https://book.douban.com/subject/1045818/buylinks/“ , 可能是不匹配结尾的话它会把用这个正则能匹配出数据的url都选取下来)
      在这里插入图片描述
    • 那么我们可以这样写
    class CrawlDoubanSpider(CrawlSpider):
    	name = 'crawl_douban'
    	allowed_domains = ['book.douban.com']
    	start_urls = ['https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T']
    
    	rules = (
        	Rule(LinkExtractor(allow="/tag/小说\?start=[0-9]*"), follow=True),
        	Rule(LinkExtractor(allow="https://book.douban.com/subject/[0-9]*?/$"), 		follow=False, callback="parse_item"),
    	)
    
    def parse_item(self, response):
    	# your code
    	# response返回的是小说详情页面
    

2.CrawlSpider

  • 1.作用
    在使用普通Spider类做爬虫时,我们需要自己解析出每一个url然后手动发送对此url的请求 ; 而使用CrawlSpider时,只需要我们设置一定的规则,它会自动按照这种规则去解析url然后发送请求,将结果返回给我们。
  • 2.特点及工作机制
    • 根据上面的例子理解其运行机制
    • 因为CrawlSpider是继承于Spider,所以继承了Spider的方法
      在这里插入图片描述

    • 首先由Spider的start_requests方法根据
      start_urls = [‘https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T’] 发送请求
      在这里插入图片描述

    • 这次请求的返回CrawlSpider写了函数_parse_response去接收返回的响应
    • 因为第一个请求是没有callback的,所以不走进第一个if callback。
    • follow默认值是true
    • pider._follow_links的值是从settings的CRAWLSPIDER_FOLLOW_LINKS值获取到的(不知道有什么用,先当做一个恒定true吧)
    • 所以会进入if follow这个逻辑中:可以看到将我们第一个网页的返回给了_requests_to_follow函数在这里插入图片描述
    • _requests_to_follow这个函数的作用是提取我们写的LinkExtractor,根据我们的自定义规则判定传入的网页中是否有满足要求的url,如果有则进行加工并发起Request(这里不附带源码,因为也不像上面的那样容易看懂)
    • 因为response中是豆瓣小说第一页的内容,根据我定义的规则,是能找到第一页所有小说的url以及下几页的url的,匹配之后他们被重新加工为Request再次请求豆瓣服务器
      • 第一种:eg.xxx小说具体内容 Rule(LinkExtractor(allow=“https://book.douban.com/subject/[0-9]*?/$”), follow=False, callback=“parse_item”)
        • 依然走进函数_parse_response,因为有callback,所以走进if callback的逻辑—将response返回给parse_item函数解析然后获取得到的Request或item
        • 这里我们手动设置了follow为False,所以_parse_response的第二个if逻辑就不会进去了
      • 第二种:eg.豆瓣小说第二页的内容 Rule(LinkExtractor(allow="/tag/小说?start=[0-9]*"), follow=True)
        • 没有设置callback,所以是不走进_parse_response的第一个if
        • follow为True,走进第二个if,做的事与第一次请求一样,只是因为第二页可提取的后面几页的url相比较第一页多(eg.第一页只能获取234,第二页就能获取345),所以我们需要将这里的follow设为True,不然就无法提取所有页中的小说了。
    • 后面的请求以此类推就可以了。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!