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 它是一个包含utf-8编码的字符串,用于编码URL。
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的一些键:

序号 重点和说明
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时的关键,即使ROBOTSTXT_OBEY已启用,也不会过滤robots.txt排除标准禁止的请求。
11 download_timeout 它用于设置下载器在超时之前等待的每个蜘蛛的超时(以秒为单位)。
12 download_maxsize 它用于设置每个蜘蛛的最大大小(以字节为单位),下载器将下载。
13 proxy 可以为请求对象设置代理,以便为使用请求设置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对象的参数:

序号 参数和说明
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]])

编码 - 它是一种用于编码响应的编码字符串。

- 剩余参数与响应类相同,在“ 响应对象” 部分进行了说明。

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

序号 属性和描述
1 text 它是一个响应主体,可以多次访问response.text。
2 encoding 它是一个包含响应编码的字符串。
3 selector 它是第一次访问时实例化的属性,并将响应用作目标。

下表显示除了 响应 方法外 TextResponse 对象支持的方法 :

Sr.No 方法和描述
1 xpath(查询) 这是TextResponse.selector.xpath(查询)的快捷方式。
2 css(查询) 这是TextResponse.selector.css(查询)的快捷方式。
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])

下一章:Scrapy 链接提取器

Scrapy链接提取器:正如名称本身所示,链接提取器是用于使用 scrapy.http.Response 对象从网页中提取链接的对象。在Scrapy中,有内置提取器,如 scrapy.linkextractors import LinkEx ...