共计 3937 个字符,预计需要花费 10 分钟才能阅读完成。
Scrapy 基本介绍
scrapy 是一种用于爬虫的框架,并提供了相当成熟的模版,大大减少了程序员在编写爬虫时的劳动需要。
Command line tool & Project structure
使用 scrapy 需要先创建 scrapy project,之后再于 project 文件夹路径下生成 spider(爬虫)文件,编写完程序后,再运行爬虫(手动指定保存文件)。以上过程由命令行执行,具体如下:
- scrapy startproject <myproject>
- scrapy genspider <spider_name> <domain>
- scrapy crawl <spider_name> [-o filename]
后面两个命令均要在 myproject 文件夹(第一个 myproject)路径下执行。而由第一个命令创建的 scrapy 项目结构如下:
myproject/
scrapy.cfg
myproject/
__init__.py
items.py
middlewares.py
pipelines.py
settings.py
spiders/
__init__.py
spider_name.py
Scrapy Overview
上图是 scrapy 的基本结构,易见 scrapy 的程序执行和数据流动是由 engine 来调度控制的,关于该结构的具体解释见:scrapy document overview.
Scrapy Spider 详解
基础的使用 scrapy 一般只需要在 spider_name.py 中进行编写,该文件是我们使用 scrapy genspider <spider_name> 命令后自动创建中,文件中还自动 import 了 scrapy 并且还自动创建了一个模版 spider 类(自动继承自 scrapy.Spider)。spider 的功能简介于此:scrapy document spider。这里介绍一些常用的 scray.Spider 类的属性及方法:
Attribute:
name:name 属性即是我们使用命令行时所指定的 spider_name, 这是 scrapy 框架中用于标识 spider 所用,每个 spider 都必须有一个独一无二的 name。
allowed_domains: 该属性为一个以 string 为元素的 list,每个元素 string 为一个 domain,限定爬虫所能爬取的网址。
start_urls:该属性同样为一个以 string 为元素的 list,每个元素 string 对应一个完整的 url,是 spider 开始时需要爬取的初始网址。
custom_settings: 该属性的形式为一个 dict,即如修改 user-agent,开启 pipeline,指定 log_level 之类的,并且局限于 http header。
method:
start_requests:该方法用于在 scrapy 开始爬虫时以 start_urls 返回一个 Request iterable 或者一个 generator,该方法在一次爬虫过程中仅被调用一次。其默认实现为:Request(url, dont_filter=True) for each url in start_urls。
parse:这是 spider 类中最重要的一个方法。由 scrapy 文档中对 spider 的介绍,spider 每发出一个 Request,便要对该 Request 的 Response 进行处理,处理的函数称为 callback function,即 one Request corresponds to one Callback。而 parse 就是默认的 callback 函数,它负责对传回的 response 进行解析(xpath),提取数据(item dict-like object)并交予,并且还会根据需要发出新的 Request 请求。和 start_requests 一样,它的返回值也须要是一个 iterable 或是一个 generator。一般来说,先 yield item,再根据对 response 的解析得到新的 url 以 yield Request(url,callback)。这里对于 response 的解析和数据提取交予过程略过,具体可以见于 b 站教程。
由以上介绍可见对于 start_request 和 parse 方法的返回值要求,scrapy 框架的内部代码逻辑应该是像 for 循环一样轮询两者的返回值,对于 parse 方法还需要判断其返回值的类型 (item/Request) 来区别处理。
Scrapy Request and Response
Typically, Request objects are generated in the spiders and pass across the system until they reach the Downloader, which executes the request and returns a Response object which travels back to the spider that issued the request.
Request object
scrapy.Request(url,callback,method=”GET”,headers=None,body=None,cookies=None,meta=None,..,dont_filter=False)
- 其中 url 参数即为我们想要爬取网站的 url
- callback 为该 request 对应的在返回 response 时的处理函数
- method 是 http 请求方法,常用的有:”GET”,”POST”
- headers 是请求头,形式为 dict
- body 是 http 请求的请求数据,即一般的表单数据,形式为 bytes 字符串
- cookies 形式为 dict
- 这里先讲 dont_filter,默认值为 False,scrapy 中默认对于同一 url 是不重复爬取的,所以会把相同的 url 给 filter 掉,而有时我们需要爬取同一 url(如爬取某个不断更新的论坛页面),就需要把该值设为 True
-
meta The initial values for the Request.meta attribute. If given, the dict passed in this parameter will be shallow copied. 该参数也是字典形式,是为了在 spider 类的多个 parse 函数之间传递信息,见知乎。注意 Response 对象也有一个它对应的 Request 对象:The Request object that generated this response. This attribute is assigned in the Scrapy engine, after the response and the request have passed through all Downloader Middlewares In particular, this means that:
- HTTP redirections will cause the original request (to the URL before redirection) to be assigned to the redirected response (with the final URL after redirection).
- Response.request.url doesn’t always equal Response.url
- This attribute is only available in the spider code, and in the Spider Middlewares, but not in Downloader Middlewares (although you have the Request available there by other means) and handlers of the response_downloaded signal.
- But Unlike the Response.request attribute, the Response.meta attribute is propagated along redirects and retries, so you will get the original Request.meta sent from your spider.
Response obejct
这里仅介绍一些 reponse 对象的属性:
- url 即该 response 的来源 url
- status 即该 response 的状态码
- headers response 的响应头,形式为 dict
- body response 的相应数据体,形式为 bytes
- request response 对应的 Request 对象,对于它上文已经介绍,即 Response.url 可能不等于 Reponse.request.url,因为 redirection 的原因
Settings
Settings can be populated using different mechanisms, each of which having a different precedence. Here is the list of them in decreasing order of precedence:
- Command line options (most precedence)
- Settings per-spider
- Project settings module(settings.py)
-
Default settings per-command
- Default global settings (less precedence)
一般我们直接在 settings.py 文件中对其进行修改,常见需要增改的有:user-agent 指定,ITEM_PIPELINES 解除注释以开启 pipeline 功能,LOG_LEVEL 和 LOG_FILE 指定,ROBOTSTXT_OBEY 设为 False 等等。