- Scrapy 教程
- Scrapy - 首页
- Scrapy 基础概念
- Scrapy - 概述
- Scrapy - 环境配置
- Scrapy - 命令行工具
- Scrapy - 爬虫 (Spider)
- Scrapy - 选择器
- Scrapy - 项目 (Item)
- Scrapy - 项目加载器 (Item Loader)
- Scrapy - Shell
- Scrapy - 项目管道 (Item Pipeline)
- Scrapy - 数据导出 (Feed exports)
- Scrapy - 请求 & 响应
- Scrapy - 链接提取器
- Scrapy - 设置
- Scrapy - 异常处理
- Scrapy 实战项目
- Scrapy - 创建项目
- Scrapy - 定义项目
- Scrapy - 第一个爬虫
- Scrapy - 爬取数据
- Scrapy - 提取项目数据
- Scrapy - 使用项目
- Scrapy - 跟踪链接
- Scrapy - 爬取的数据
- Scrapy 有用资源
- Scrapy - 快速指南
- Scrapy - 有用资源
- Scrapy - 讨论
Scrapy - 请求和响应
描述
Scrapy 可以使用Request 和 Response 对象来爬取网站。请求对象在系统中传递,使用爬虫执行请求,并在返回响应对象时返回请求。
请求对象 (Request Objects)
请求对象是一个生成响应的 HTTP 请求。它具有以下类:
class scrapy.http.Request(url[, callback, method = 'GET', headers, body, cookies, meta, encoding = 'utf-8', priority = 0, dont_filter = False, errback])
下表显示了请求对象的参数:
序号 | 参数 & 描述 |
---|---|
1 | url 指定 URL 请求的字符串。 |
2 | callback 一个可调用函数,它使用请求的响应作为第一个参数。 |
3 | method 指定 HTTP 方法请求的字符串。 |
4 | headers 包含请求头的字典。 |
5 | body 包含请求主体的字符串或 Unicode 字符串。 |
6 | cookies 包含请求 Cookie 的列表。 |
7 | meta 包含请求元数据的字典。 |
8 | encoding 用于编码 URL 的 utf-8 编码字符串。 |
9 | priority 一个整数,调度程序使用优先级来定义处理请求的顺序。 |
10 | dont_filter 一个布尔值,指定调度程序是否不应过滤请求。 |
11 | errback 当处理请求时引发异常时要调用的可调用函数。 |
将附加数据传递给回调函数
下载响应后,将调用请求的回调函数,其第一个参数为响应。
例如:
def parse_page1(self, response): return scrapy.Request("http://www.something.com/some_page.html", callback = self.parse_page2) def parse_page2(self, response): self.logger.info("%s page visited", response.url)
如果要将参数传递给可调用函数并在第二个回调中接收这些参数,可以使用Request.meta 属性,如下例所示:
def parse_page1(self, response): item = DemoItem() item['foremost_link'] = response.url request = scrapy.Request("http://www.something.com/some_page.html", callback = self.parse_page2) request.meta['item'] = item return request def parse_page2(self, response): item = response.meta['item'] item['other_link'] = response.url return item
使用 errback 捕获请求处理中的异常
errback 是一个可调用函数,当处理请求时引发异常时会调用它。
以下示例演示了这一点:
import scrapy from scrapy.spidermiddlewares.httperror import HttpError from twisted.internet.error import DNSLookupError from twisted.internet.error import TimeoutError, TCPTimedOutError class DemoSpider(scrapy.Spider): name = "demo" start_urls = [ "http://www.httpbin.org/", # HTTP 200 expected "http://www.httpbin.org/status/404", # Webpage not found "http://www.httpbin.org/status/500", # Internal server error "http://www.httpbin.org:12345/", # timeout expected "http://www.httphttpbinbin.org/", # DNS error expected ] def start_requests(self): for u in self.start_urls: yield scrapy.Request(u, callback = self.parse_httpbin, errback = self.errback_httpbin, dont_filter=True) def parse_httpbin(self, response): self.logger.info('Recieved response from {}'.format(response.url)) # ... def errback_httpbin(self, failure): # logs failures self.logger.error(repr(failure)) if failure.check(HttpError): response = failure.value.response self.logger.error("HttpError occurred on %s", response.url) elif failure.check(DNSLookupError): request = failure.request self.logger.error("DNSLookupError occurred on %s", request.url) elif failure.check(TimeoutError, TCPTimedOutError): request = failure.request self.logger.error("TimeoutError occurred on %s", request.url)
Request.meta 特殊键
request.meta 特殊键是由 Scrapy 识别的特殊元键列表。
下表显示了一些 Request.meta 的键:
序号 | 键 & 描述 |
---|---|
1 | dont_redirect 如果设置为 true,则不会根据响应状态重定向请求。 |
2 | dont_retry 如果设置为 true,则不会重试失败的请求,并将被中间件忽略。 |
3 | handle_httpstatus_list 定义每个请求允许哪些响应代码。 |
4 | handle_httpstatus_all 通过将其设置为 true 来允许任何请求的响应代码。 |
5 | dont_merge_cookies 通过将其设置为 true 来避免与现有 Cookie 合并。 |
6 | cookiejar 用于为每个爬虫保留多个 Cookie 会话。 |
7 | dont_cache 用于避免根据每个策略缓存 HTTP 请求和响应。 |
8 | redirect_urls 包含请求经过的 URL。 |
9 | bindaddress 可以用来执行请求的传出 IP 地址的 IP。 |
10 | dont_obey_robotstxt 如果设置为 true,则不会过滤 robots.txt 排除标准禁止的请求,即使启用了 ROBOTSTXT_OBEY。 |
11 | download_timeout 用于为每个爬虫设置超时时间(以秒为单位),下载器将在其超时前等待。 |
12 | download_maxsize 用于为每个爬虫设置下载器将下载的最大大小(以字节为单位)。 |
13 | proxy 可以为 Request 对象设置代理,以便使用请求设置 HTTP 代理。 |
请求子类 (Request Subclasses)
可以通过子类化请求类来实现自己的自定义功能。内置的请求子类如下:
表单请求对象 (FormRequest Objects)
FormRequest 类通过扩展基本请求来处理 HTML 表单。它具有以下类:
class scrapy.http.FormRequest(url[,formdata, callback, method = 'GET', headers, body, cookies, meta, encoding = 'utf-8', priority = 0, dont_filter = False, errback])
参数如下:
formdata - 一个包含分配给请求主体的 HTML 表单数据的字典。
注意 - 其余参数与请求类相同,在请求对象部分进行了解释。
除了请求方法外,FormRequest 对象还支持以下类方法:
classmethod from_response(response[, formname = None, formnumber = 0, formdata = None, formxpath = None, formcss = None, clickdata = None, dont_click = False, ...])
下表显示了上述类的参数:
序号 | 参数 & 描述 |
---|---|
1 | response 用于使用响应的 HTML 表单预填充表单字段的对象。 |
2 | formname 一个字符串,如果指定,则将使用具有 name 属性的表单。 |
3 | formnumber 当响应中有多个表单时,要使用的表单的整数。 |
4 | formdata 用于覆盖的表单数据中的字段字典。 |
5 | formxpath 一个字符串,如果指定,则使用与 xpath 匹配的表单。 |
6 | formcss 一个字符串,如果指定,则使用与 css 选择器匹配的表单。 |
7 | clickdata 用于观察被点击控件的属性字典。 |
8 | dont_click 如果设置为 true,则将在不点击任何元素的情况下提交表单数据。 |
示例
以下是请求使用的一些示例:
使用 FormRequest 通过 HTTP POST 发送数据
以下代码演示了当您想要在爬虫中复制 HTML 表单 POST 时如何返回FormRequest 对象:
return [FormRequest(url = "http://www.something.com/post/action", formdata = {'firstname': 'John', 'lastname': 'dave'}, callback = self.after_post)]
使用 FormRequest.from_response() 模拟用户登录
通常,网站使用提供预填充表单字段的元素。
当您希望在抓取时自动填充这些字段时,可以使用FormRequest.form_response() 方法。
以下示例演示了这一点。
import scrapy class DemoSpider(scrapy.Spider): name = 'demo' start_urls = ['http://www.something.com/users/login.php'] def parse(self, response): return scrapy.FormRequest.from_response( response, formdata = {'username': 'admin', 'password': 'confidential'}, callback = self.after_login ) def after_login(self, response): if "authentication failed" in response.body: self.logger.error("Login failed") return # You can continue scraping here
响应对象 (Response Objects)
这是一个表示 HTTP 响应的对象,它被馈送到爬虫以进行处理。它具有以下类:
class scrapy.http.Response(url[, status = 200, headers, body, flags])
下表显示了响应对象的参数:
序号 | 参数 & 描述 |
---|---|
1 | url 指定 URL 响应的字符串。 |
2 | status 包含 HTTP 状态响应的整数。 |
3 | headers 包含响应头的字典。 |
4 | body 包含响应主体的字符串。 |
5 | flags 包含响应标志的列表。 |
响应子类 (Response Subclasses)
可以通过子类化响应类来实现自己的自定义功能。内置的响应子类如下:
文本响应对象 (TextResponse objects)
TextResponse 对象用于二进制数据(例如图像、声音等),它能够编码基本 Response 类。它具有以下类:
class scrapy.http.TextResponse(url[, encoding[,status = 200, headers, body, flags]])
参数如下:
encoding - 用于编码响应的字符串编码。
注意 - 其余参数与响应类相同,在响应对象部分进行了解释。
下表显示了 TextResponse 对象除了响应方法之外还支持的属性:
序号 | 属性 & 描述 |
---|---|
1 | text 响应主体,response.text 可以多次访问。 |
2 | encoding 包含响应编码的字符串。 |
3 | selector 在第一次访问时实例化的属性,并使用响应作为目标。 |
下表显示了除了response 方法之外TextResponse 对象还支持的方法:
序号 | 方法 & 描述 |
---|---|
1 | xpath (query) 这是 TextResponse.selector.xpath(query) 的快捷方式。 |
2 | css (query) 这是 TextResponse.selector.css(query) 的快捷方式。 |
3 | body_as_unicode() 作为方法提供的响应主体,response.text 可以多次访问。 |
HTML 响应对象 (HtmlResponse Objects)
这是一个支持编码和自动发现的对象,它通过查看 HTML 的meta httpequiv 属性来实现。其参数与响应类相同,在响应对象部分进行了解释。它具有以下类:
class scrapy.http.HtmlResponse(url[,status = 200, headers, body, flags])
XML 响应对象 (XmlResponse Objects)
这是一个支持编码和自动发现的对象,它通过查看 XML 行来实现。其参数与响应类相同,在响应对象部分进行了解释。它具有以下类:
class scrapy.http.XmlResponse(url[, status = 200, headers, body, flags])