1写在前面的话
今天继续更新scrapy的专栏文章,今天我们来聊一聊scrapy中spiders的用法。我们知道在整个框架体系中,spiders是我们主要进行编写的部分,所以弄清楚spiders这一块的知识,对我们学习scrapy有着很大的好处。但是这一章里大多数都是一些spiders里面的一些模板的介绍,实战代码可能会比较少,但是大家了解了这些之后,对于scrapy的使用会更加的得心应手!
2spider运行的大致流程
- 以初始的URL初始化Request,并设置回调函数。 当该request下载完毕并返回时,将生成response,并作为参数传给该回调函数。
spider中初始的request是通过调用start_requests()
来获取的。start_requests()
读取start_urls
中的URL, 并以parse
为回调函数生成Request
。
- 在回调函数内分析返回的(网页)内容,返回
Item
对象或者Request
或者一个包括二者的可迭代容器。 返回的Request对象之后会经过Scrapy处理,下载相应的内容,并调用设置的callback函数(函数可相同)。
- 在回调函数内,您可以使用 选择器(Selectors) (您也可以使用BeautifulSoup, lxml 或者您想用的任何解析器) 来分析网页内容,并根据分析的数据生成item。(Scrapy框架| 选择器-Xpath和CSS的那些事)
- 最后,由spider返回的item将被存到数据库(由某些 Item Pipeline 处理)或使用 Feed exports 存入到文件中。
3spiders用法介绍
首先,我们还是来上一段代码:
# -*- coding: utf-8 -*-import scrapyclass ToScrapeSpiderXPath(scrapy.Spider): name = 'toscrape-xpath' allowed_domains = ['quotes.toscrape.com'] start_urls = [ 'http://quotes.toscrape.com/', ] def parse(self, response): for quote in response.xpath('//div[@class="quote"]'): yield { 'text': quote.xpath('./span[@class="text"]/text()').extract_first(), 'author': quote.xpath('.//small[@class="author"]/text()').extract_first(), 'tags': quote.xpath('.//div[@class="tags"]/a[@class="tag"]/text()').extract() } next_page_url = response.xpath('//li[@class="next"]/a/@href').extract_first() if next_page_url is not None: yield scrapy.Request(response.urljoin(next_page_url))
可以看到我们这个类继承的是Spider类,这里来介绍一下Spider类,Spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。
我们可以看到类中有几个变量,我们来一一解释:
name:
从字面意思上看,想必大家都知道这是啥意思了,这是我们爬虫的名字,这里的名字name是唯一不可重复的,这是我们整个spider最重要的一个属性。对于爬虫的命名,如果我们需要爬取www.baidu.com,我们一般的name就会写成baidu,这样有利于区分!
allowed_domains:
这个其实是一个可写可不写的属性,主要包含了spider允许爬取的域名列表list。
start_urls:
URL列表。当没有指定特定的URL时,spider将从该列表中开始进行爬取。 因此,第一个被获取到的页面的URL将是该列表之一。 后续的URL将会从获取到的数据中提取。并以parse作为回调函数生成Request对象
4常用的几个回调函数
start_request():
该方法必须返回一个可迭代对象(iterable)。该对象包含了spider用于爬取的第一个Request。
当spider启动爬取并且未制定URL时,该方法被调用。 当指定了URL时,make_requests_from_url()
将被调用来创建Request对象。 该方法仅仅会被Scrapy调用一次,因此您可以将其实现为生成器。
该方法的默认实现是使用 start_urls
的url生成Request。
如果您想要修改最初爬取某个网站的Request对象,您可以重写(override)该方法。 例如,如果您需要在启动时以POST登录某个网站,你可以这么写:
def start_requests(self): return [scrapy.FormRequest("http://www.example.com/login", formdata={'user': 'john', 'pass': 'secret'}, callback=self.logged_in)] def logged_in(self, response): # here you would extract links to follow and return Requests for # each of them, with another callback pass
parse
(response):
当response没有指定回调函数时,该方法是Scrapy处理下载的response的默认方法。
parse
负责处理response并返回处理的数据以及(/或)跟进的URL。 Spider
对其他的Request的回调函数也有相同的要求。
该方法及其他的Request回调函数必须返回一个包含 Request
及(或) Item
的可迭代的对象。