Ⅳ.Re:Scrapy 之 Spider
Spiders
Spiders 是定义如何抓取某个网站(或一组网站)的类。
包括如何进行抓取(即跟随链接)以及如何从其页面中提取结构化数据(即抓取项目)。
换句话说,Spiders 是你定义业务逻辑的地方,用于抓取和解析特定网站(或在某些情况下,一组网站)的页面。
name
必要,自定义爬虫名称,爬虫的唯一标识
allowed_domains
可选,规定爬虫爬行范围。实现代码
scrapy.spidermiddlewares.offsite.OffsiteMiddleware
的get_host_regex
start_urls
可选,种子URL列表,一般放入可GET请求的URL,POST请求可重写
start_requests()
方法实现
start_requests()
可选,默认从
start_urls
中获取 URL 且dont_filter=True
,重写需要返回可迭代的抓取请求。
# scrapy/spiders/__init__.py#Spider start_requests(self)
def start_requests(self):
if not self.start_urls and hasattr(self, 'start_url'):
raise AttributeError(
"Crawling could not start: 'start_urls' not found "
"or empty (but found 'start_url' attribute instead, "
"did you miss an 's'?)")
for url in self.start_urls:
yield Request(url, dont_filter=True)
parse(self, response, **kwargs)
必要,没有进行
callback
指定是,处理下载响应的默认回调,必须返回一个Request
或Items对象
其他
通用 Spiders 模板
Scrapy 提供了四套通用模板:
CrawlSpider
、SitemapSpider
、XMLFeedSpider
、CSVFeedSpider
SitemapSpider
、XMLFeedSpider
、CSVFeedSpider
适用性较低,暂不展开
CrawlSpider
适用于常规网站
start_urls
依然是 种子URL列表
rules
序列化一组或多组Rule
Rule
scrapy.spiders.Rule(link_extractor=None, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None, errback=None)
link_extractor
是链接提取器对象,可以从页面中提取链接。常用参数如下:- allow (str or list) :保留符合正则的链接。例:
allow=(r'catalogue/page-\d+.html',)
- deny (str or list) :排除符合正则的链接。
- restrict_xpaths (str or list) :用XPath来限定提取某些区域中的链接。
- 其他参数,详见👉https://docs.scrapy.org/en/latest/topics/link-extractors.html#module-scrapy.linkextractors.lxmlhtml
- allow (str or list) :保留符合正则的链接。例:
callback
回调到对应接收方法中follow
若callback
为空,默认为True
;否则为False
- 其他参数,详见👉https://docs.scrapy.org/en/latest/topics/spiders.html#crawling-rules
CRAWLSPIDER_FOLLOW_LINKS
根据源码得知,settings 文件中
CRAWLSPIDER_FOLLOW_LINKS
值的真假,会影响是否继续解析下层链接
# scrapy/spiders/crawl.py#CrawlSpider from_crawler(cls, crawler, *args, **kwargs)
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = super().from_crawler(crawler, *args, **kwargs)
spider._follow_links = crawler.settings.getbool('CRAWLSPIDER_FOLLOW_LINKS', True)
return spider
# scrapy/spiders/crawl.py#CrawlSpider _parse_response(self, response, callback, cb_kwargs, follow=True)
def _parse_response(self, response, callback, cb_kwargs, follow=True):
if callback:
cb_res = callback(response, **cb_kwargs) or ()
cb_res = self.process_results(response, cb_res)
for request_or_item in iterate_spider_output(cb_res):
yield request_or_item
if follow and self._follow_links:
for request_or_item in self._requests_to_follow(response):
yield request_or_item