Scrapy框架之全站爬虫(CrawlSpider)
- 在之前 Scrapy 的基本使用当中,spider 如果要重新发送请求的话,就需要自己解析页面,然后发送请求。
- 而 CrawlSpider 则可以通过设置 url 条件自动发送请求。
LinkExtractors
- CrawlSpider 是 Spider 的一个派生类。
- CrawlSpider 与 spider 不同的是就在于下一次请求的 url 不需要自己手动解析,而这一点则是通过 LinkExtractors 实现的。
- LinkExtractor类的构造方法如下所示。
class scrapy.linkextractors.LinkExtractor(
allow = (),
deny = (),
allow_domains = (),
deny_domains = (),
restrict_xpaths = (),
tags = ('a','area'),
attrs = ('href'),
canonicalize = False,
unique = True,
process_value = None,
deny_extensions = None,
restrict_css=(),
strip=True
)
- 其中的参数为:
allow:允许的 url。所有满足这个正则表达式的 url 都会被提取
deny:禁止的 url。所有满足这个正则表达式的 url 都不会被提取
allow_domains:允许的域名。只有在这个里面指定的域名的 url 才会被提取
deny_domains:禁止的域名。所有在这个里面指定的域名的 url 都不会被提取
restrict_xpaths:严格的 xpath。和 allow 共同过滤链接
tags:接收一个标签或标签列表,提取标签内的列表,默认为[‘a’, ‘area’]
attrs:接收一个属性或属性列表,提取指定属性内的链接,默认为[‘href’]
Rule
- LinkExtractors 需要传递到 Rule 类对象中才能发挥作用。
- Rule 类常见的参数为:
link_extractors:是一个LinkExtractor对象,用于定义需要提取的链接
callback:从link_extractor中没获取链接时,参数所制定的值作为回调函数,该回调函数接受一个response作为起第一个参数
注意:当编写爬虫规则是,避免使用parse作为回调函数。由于CrawlSpider使用parse方法来实现其逻辑,如果覆盖了parse方法,CrawlSpider将会运行失败
follow:是一个布尔值(boolean),制定了根据该规则从response提取的链接是偶需要跟进。如果callback为None,follow默认设置为True,否则默认为Flase
process_links:指定该Spider中那个的函数将会被调用,从link_extractor中获取到链接列表是将会调用该函数。该方法主要用来过滤
process_request:指定该Spider中那个的函数将会被调用,该规则提取到每个request是都会调用该函数。(用来过滤request)
- 除了上述的这些差别,Crawlspider 和 spider 基本没有什么差别了。
CrawlSpider如何工作的?
-
因为CrawlSpider继承了Spider,所以具有Spider的所有函数。
- 首先由
start_requests
对start_urls
中的每一个url发起请求(make_requests_from_url
),这个请求会被parse接收。 - 在Spider里面的parse需要我们定义,但CrawlSpider定义
parse
去解析响应(self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)
)
- 首先由
-
_parse_response根据有无
callback
,follow
和self.follow_links
执行不同的操作 -
eg:
def _parse_response(self, response, callback, cb_kwargs, follow=True):
##如果传入了callback,使用这个callback解析页面并获取解析得到的reques或item
if callback:
cb_res = callback(response, **cb_kwargs) or ()
cb_res = self.process_results(response, cb_res)
for requests_or_item in iterate_spider_output(cb_res):
yield requests_or_item
## 其次判断有无follow,用_requests_to_follow解析响应是否有符合要求的link。
if follow and self._follow_links:
for request_or_item in self._requests_to_follow(response):
yield request_or_item
- 其中
_requests_to_follow
又会获取link_extractor
(这个是我们传入的LinkExtractor)解析页面得到的link(link_extractor.extract_links(response))
,- 对url进行加工(process_links,需要自定义),
- 对符合的link发起Request。
- 使用
.process_request
(需要自定义)处理响应。
全站爬虫案例
- 创建项目:
scrapy startproject imgPro
cd imgPro
scrapy genspider img
spider.img.py
# -*- coding: utf-8 -*-
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
import os
class ImgSpider(CrawlSpider):
name = 'img'
# allowed_domains = ["netbian.com"]
start_urls = ['http://www.daimg.com/pic/%E7%BE%8E%E5%A5%B3%E5%9B%BE%E7%89%87-0-0-0-0-0_1.html']
link = LinkExtractor(tags=['img'], attrs='src', deny_extensions=[''], )
link2 = LinkExtractor(allow=r'pic/%E7%BE%8E%E5%A5%B3%E5%9B%BE%E7%89%87')
rules = (
Rule(link, callback="parse_item", follow=False, ),
Rule(link2, follow=True),
)
def parse_item(self, response):
p = os.path.join("imgs", os.path.basename(response.url))
with open(p, 'wb') as f:
f.write(response.body)
print(f"{p}下载完成!")
- 注意事项:
标签:25.1,25,全站,url,CrawlSpider,parse,link,follow,response From: https://www.cnblogs.com/dream-ze/p/17335668.html
- crawlspider爬虫默认继承了CrawlSpider类。
- parse_item表示crawlspider爬虫的数据提取函数,在crawlspider爬虫中不能编写parse函数。parse函数是普通类独有的。
- rules是元组类型,小括号后面必须加逗号","
scrapy genspider -t crawl 爬虫名
可以直接生成CrawlSpider结构的模板代码