Scrapy - 请求和响应

描述

Scrapy 可以使用 RequestResponse 对象抓取网站。请求对象通过系统,使用蜘蛛执行请求,并在返回响应对象时返回请求。

请求对象

请求对象是生成响应的 HTTP 请求。它具有以下类 −

class scrapy.http.Request(url[, callback, method = 'GET', headers, body, cookies, meta,
   encoding = 'utf-8', priority = 0, dont_filter = False, errback])

下表显示了 Request 对象的参数 −

Sr.No 参数与说明
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

使用 errbacks 捕获请求处理中的异常

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 的一些键 −

Sr.No 键 &描述
1

dont_redirect

设置为 true 时,它​​是一个键,不会根据响应的状态重定向请求。

2

dont_retry

设置为 true 时,它​​是一个键,不会重试失败的请求,并且会被中间件忽略。

3

handle_httpstatus_list

它是一个键,定义可以允许每个请求的哪些响应代码。

4

handle_httpstatus_all

这是一个用于允许任何请求响应代码的键,通过将其设置为 true

5

dont_merge_cookies

这是一个用于避免与现有 cookie 合并的键,通过将其设置为 true

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 代理。

请求子类

您可以通过子类化请求类来实现自己的自定义功能。内置的请求子类如下 −

FormRequest 对象

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, ...])

下表显示了上述类的参数 −

Sr.No 参数与说明
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

响应对象

它是一个表示 HTTP 响应的对象,被提供给蜘蛛进行处理。它有以下类 −

class scrapy.http.Response(url[, status = 200, headers, body, flags])

下表显示了 Response 对象 − 的参数。

Sr.No 参数与说明
1

url

它是一个指定 URL 响应的字符串。

2

status

它是一个包含 HTTP 状态响应的整数。

3

headers

它是一个包含响应标头的字典。

4

body

它是一个包含响应主体的字符串。

5

flags

它是一个包含响应标志的列表。

响应子类

您可以通过子类化响应类来实现自己的自定义功能。内置的响应子类如下 −

TextResponse 对象

TextResponse 对象用于二进制数据(如图像、声音等),能够对基本 Response 类进行编码。它具有以下类 −

class scrapy.http.TextResponse(url[, encoding[,status = 200, headers, body, flags]])

以下是参数 −

encoding − 它是一个带有编码的字符串,用于对响应进行编码。

注意 −其余参数与响应类相同,并在响应对象部分中解释。

下表显示了 TextResponse 对象除了响应方法之外支持的属性 −

Sr.No 属性 &描述
1

text

它是一个响应主体,其中 response.text 可以多次访问。

2

encoding

它是一个包含响应编码的字符串。

3

selector

它是在第一次访问时实例化的属性,并使用响应作为目标。

下表显示了 TextResponse 对象除 response 方法之外支持的方法−

Sr.No 方法 &描述
1

xpath (query)

它是 TextResponse.selector.xpath(query) 的快捷方式。

2

css (query)

它是 TextResponse.selector.css(query) 的快捷方式。

3

body_as_unicode()

它是一个可用作方法的响应主体,其中 response.text 可多次访问。

HtmlResponse对象

它是一个支持通过查看 HTML 的 meta httpequiv 属性进行编码和自动发现的对象。其参数与响应类相同,并在响应对象部分中进行了说明。它具有以下类 −

class scrapy.http.HtmlResponse(url[,status = 200, headers, body, flags])

XmlResponse 对象

它是一个支持通过查看 XML 行进行编码和自动发现的对象。其参数与响应类相同,并在响应对象部分中进行了说明。它具有以下类 −

class scrapy.http.XmlResponse(url[, status = 200, headers, body, flags])