Scrapy-Request和Response(请求和响应)




请求和响应

Scrapy的Request和Response对象用于爬网网站。

通常,Request对象在爬虫程序中生成并传递到系统,直到它们到达下载程序,后者执行请求并返回一个Response对象,该对象返回到发出请求的爬虫程序。

上面一段话比较拗口,有web经验的同学,应该都了解的,不明白看下面的图大概理解下。


 
 
  1. 爬虫->Request:创建
  2. Request->Response:获取下载数据
  3. Response->爬虫:数据

两个类Request和Response类都有一些子类,它们添加基类中不需要的功能。这些在下面的请求子类和 响应子类中描述。



Request objects

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

一个Request对象表示一个HTTP请求,它通常是在爬虫生成,并由下载执行,从而生成Response。

参数:

  • url(string) -
    此请求的网址
  • callback(callable) -
    将使用此请求的响应(一旦下载)作为其第一个参数调用的函数。有关更多信息,请参阅下面的将附加数据传递给回调函数。如果请求没有指定回调,parse()将使用spider的
    方法。请注意,如果在处理期间引发异常,则会调用errback。
  • method(string) -
    此请求的HTTP方法。默认为’GET’。
  • meta(dict) -
    属性的初始值Request.meta。如果给定,在此参数中传递的dict将被浅复制。
  • body(str或unicode) -
    请求体。如果unicode传递了a,那么它被编码为 str使用传递的编码(默认为utf-8)。如果 body没有给出,则存储一个空字符串。不管这个参数的类型,存储的最终值将是一个str(不会是unicode或None)。
  • headers(dict) -
    这个请求的头。dict值可以是字符串(对于单值标头)或列表(对于多值标头)。如果 None作为值传递,则不会发送HTTP头。

cookie(dict或list) - 请求cookie。这些可以以两种形式发送。

  • 使用dict:

 
 
  1. request_with_cookies = Request( url= "http://www.example.com",
  2. cookies={ 'currency': 'USD', 'country': 'UY'})


 
 
  1. * 使用列表:
  2. </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> request_with_cookies = Request(url=<span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">"http://www.example.com"</span></span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> cookies=[{<span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'name'</span></span>: <span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'currency'</span></span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'value'</span></span>: <span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'USD'</span></span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'domain'</span></span>: <span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'example.com'</span></span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'path'</span></span>: <span class="hljs-string" style="color:rgb(42,161,152);"><span class="hljs-string">'/currency'</span></span>}])</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">

后一种形式允许定制 cookie的属性domain和path属性。这只有在保存Cookie用于以后的请求时才有用。

当某些网站返回Cookie(在响应中)时,这些Cookie会存储在该域的Cookie中,并在将来的请求中再次发送。这是任何常规网络浏览器的典型行为。但是,如果由于某种原因,您想要避免与现有Cookie合并,您可以通过将dont_merge_cookies关键字设置为True 来指示Scrapy如此操作 Request.meta。

不合并Cookie的请求示例:


 
 
  1. request_with_cookies = Request( url= "http://www.example.com",
  2. cookies={ 'currency': 'USD', 'country': 'UY'},
  3. meta={ 'dont_merge_cookies': True})

有关详细信息,请参阅CookiesMiddleware

  • encoding(string) -
    此请求的编码(默认为’utf-8’)。此编码将用于对URL进行百分比编码,并将正文转换为str(如果给定unicode)。
  • priority(int) -
    此请求的优先级(默认为0)。调度器使用优先级来定义用于处理请求的顺序。具有较高优先级值的请求将较早执行。允许负值以指示相对低优先级。
  • dont_filter(boolean) -
    表示此请求不应由调度程序过滤。当您想要多次执行相同的请求时忽略重复过滤器时使用。小心使用它,或者你会进入爬行循环。默认为False。

errback(callable) - 如果在处理请求时引发任何异常,将调用的函数。这包括失败的404 HTTP错误等页面。它接收一个Twisted Failure实例作为第一个参数。有关更多信息,请参阅使用errbacks在请求处理捕获异常

  • url
    包含此请求的网址的字符串。请记住,此属性包含转义的网址,因此它可能与构造函数中传递的网址不同。


    此属性为只读。更改请求使用的URL replace()


    • method
      表示请求中的HTTP方法的字符串。这保证是大写的。例如:"GET","POST","PUT"

    • headers
      包含请求标头的类似字典的对象。

    • body
      包含请求正文的str。


    此属性为只读。更改请求使用的正文 replace()


    • meta
      包含此请求的任意元数据的字典。此dict对于新请求为空,通常由不同的Scrapy组件(扩展程序,中间件等)填充。因此,此dict中包含的数据取决于您启用的扩展。


    有关Scrapy识别的特殊元键列表,请参阅Request.meta特殊键

    当使用or 方法克隆请求时,此dict是浅复制的 ,并且也可以在您的爬虫中从属性访问。copy()replace()response.meta

    copy()
    返回一个新的请求,它是这个请求的副本。另请参见: 将附加数据传递到回调函数

  • replace([url, method, headers, body, cookies, meta, encoding, dont_filter, callback, errback])
    返回具有相同成员的Request对象,但通过指定的任何关键字参数赋予新值的成员除外。该属性Request.meta是默认复制(除非新的值在给定的meta参数)。另请参见 将附加数据传递给回调函数


    将附加数据传递给回调函数

    请求的回调是当下载该请求的响应时将被调用的函数。将使用下载的Response对象作为其第一个参数来调用回调函数。

    例:

    
     
     
    1. def parse_page1(self, response):
    2. return scrapy.Request("http://www.example.com/some_page.html",
    3. callback=self.parse_page2)
    4. def parse_page2(self, response):
    5. # this would log http://www.example.com/some_page.html
    6. self.logger.info("Visited %s", response.url)

    在某些情况下,您可能有兴趣向这些回调函数传递参数,以便稍后在第二个回调中接收参数。您可以使用该Request.meta属性。

    以下是使用此机制传递项目以填充来自不同页面的不同字段的示例:

    
     
     
    1. def parse_page1(self, response):
    2. item = MyItem()
    3. item['main_url'] = response.url
    4. request = scrapy.Request("http://www.example.com/some_page.html",
    5. callback=self.parse_page2)
    6. request.meta['item'] = item
    7. yield request
    8. def parse_page2(self, response):
    9. item = response.meta['item']
    10. item['other_url'] = response.url
    11. yield item

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

    请求的errback是在处理异常时被调用的函数。

    它接收一个Twisted Failure实例作为第一个参数,并可用于跟踪连接建立超时,DNS错误等。

    这里有一个示例爬虫记录所有错误,并捕获一些特定的错误,如果需要:

    
     
     
    1. import scrapy
    2. from scrapy.spidermiddlewares.httperror import HttpError
    3. from twisted.internet.error import DNSLookupError
    4. from twisted.internet.error import TimeoutError, TCPTimedOutError
    5. class ErrbackSpider(scrapy.Spider):
    6. name = "errback_example"
    7. start_urls = [
    8. "http://www.httpbin.org/", # HTTP 200 expected
    9. "http://www.httpbin.org/status/404", # Not found error
    10. "http://www.httpbin.org/status/500", # server issue
    11. "http://www.httpbin.org:12345/", # non-responding host, timeout expected
    12. "http://www.httphttpbinbin.org/", # DNS error expected
    13. ]
    14. def start_requests(self):
    15. for u in self.start_urls:
    16. yield scrapy.Request(u, callback=self.parse_httpbin,
    17. errback=self.errback_httpbin,
    18. dont_filter=True)
    19. def parse_httpbin(self, response):
    20. self.logger.info('Got successful response from {}'.format(response.url))
    21. # do something useful here...
    22. def errback_httpbin(self, failure):
    23. # log all failures
    24. self.logger.error(repr(failure))
    25. # in case you want to do something special for some errors,
    26. # you may need the failure's type:
    27. if failure.check(HttpError):
    28. # these exceptions come from HttpError spider middleware
    29. # you can get the non-200 response
    30. response = failure.value.response
    31. self.logger.error('HttpError on %s', response.url)
    32. elif failure.check(DNSLookupError):
    33. # this is the original request
    34. request = failure.request
    35. self.logger.error('DNSLookupError on %s', request.url)
    36. elif failure.check(TimeoutError, TCPTimedOutError):
    37. request = failure.request
    38. self.logger.error('TimeoutError on %s', request.url)



    Request.meta特殊键

    Request.meta属性可以包含任何任意数据,但有一些特殊的键由Scrapy及其内置扩展识别。

    那些是:

    
     
     
    1. dont_redirect
    2. dont_retry
    3. handle_httpstatus_list
    4. handle_httpstatus_all
    5. dont_merge_cookies(参见cookies构造函数的 Request参数)
    6. cookiejar
    7. dont_cache
    8. redirect_urls
    9. bindaddress
    10. dont_obey_robotstxt
    11. download_timeout
    12. download_maxsize
    13. download_latency
    14. proxy
    bindaddress

    用于执行请求的出站IP地址的IP。

    download_timeout

    下载器在超时前等待的时间量(以秒为单位)。参见:DOWNLOAD_TIMEOUT

    download_latency

    自请求已启动以来,用于获取响应的时间量,即通过网络发送的HTTP消息。此元键仅在响应已下载时可用。虽然大多数其他元键用于控制Scrapy行为,但这应该是只读的。

    请求子类

    这里是内置子类的Request列表。您还可以将其子类化以实现您自己的自定义功能。

    FormRequest对象
    FormRequest类扩展了Request具有处理HTML表单的功能的基础。它使用lxml.html表单 从Response对象的表单数据预填充表单字段。

    class scrapy.http.FormRequest(url[, formdata, ...])

    FormRequest类增加了新的构造函数的参数。其余的参数与Request类相同,这里没有记录。

    • 参数:formdata(元组的dict或iterable) - 是一个包含HTML Form数据的字典(或(key,value)元组的迭代),它将被url编码并分配给请求的主体。
      FormRequest对象支持除标准以下类方法Request的方法:
    classmethod from_response(response[, formname=None, formid=None, formnumber=0, formdata=None, formxpath=None, formcss=None, clickdata=None, dont_click=False, ...])
     
     

    返回一个新FormRequest对象,其中的表单字段值已预先<form>填充在给定响应中包含的HTML 元素中。有关示例,请参阅 使用FormRequest.from_response()来模拟用户登录

    该策略是在任何可查看的表单控件上默认自动模拟点击,如a 。即使这是相当方便,并且经常想要的行为,有时它可能导致难以调试的问题。例如,当使用使用javascript填充和/或提交的表单时,默认行为可能不是最合适的。要禁用此行为,您可以将参数设置 为。此外,如果要更改单击的控件(而不是禁用它),您还可以使用 参数。<input type="submit"> from_response() dont_click True clickdata

    参数:

    • response(Responseobject) - 包含将用于预填充表单字段的HTML表单的响应
    • formname(string) - 如果给定,将使用name属性设置为此值的形式。
    • formid(string) - 如果给定,将使用id属性设置为此值的形式。
    • formxpath(string) - 如果给定,将使用匹配xpath的第一个表单。
    • formcss(string) - 如果给定,将使用匹配css选择器的第一个形式。
    • formnumber(integer) - 当响应包含多个表单时要使用的表单的数量。第一个(也是默认)是0。
    • formdata(dict) - 要在表单数据中覆盖的字段。如果响应<form>元素中已存在字段,则其值将被在此参数中传递的值覆盖。
    • clickdata(dict) - 查找控件被点击的属性。如果没有提供,表单数据将被提交,模拟第一个可点击元素的点击。除了html属性,控件可以通过其相对于表单中其他提交表输入的基于零的索引,通过nr属性来标识。
    • dont_click(boolean) - 如果为True,表单数据将在不点击任何元素的情况下提交。

    这个类方法的其他参数直接传递给 FormRequest构造函数。
    在新版本0.10.3:该formname参数。
    在新版本0.17:该formxpath参数。
    新的版本1.1.0:该formcss参数。
    新的版本1.1.0:该formid参数。




    请求使用示例

    使用FormRequest通过HTTP POST发送数据

    如果你想在你的爬虫中模拟HTML表单POST并发送几个键值字段,你可以返回一个FormRequest对象(从你的爬虫)像这样:

    
     
     
    1. return [FormRequest(url= "http://www.example.com/post/action",
    2. formdata={ 'name': 'John Doe', 'age': '27'},
    3. callback= self.after_post)]
    使用FormRequest.from_response()来模拟用户登录

    网站通常通过元素(例如会话相关数据或认证令牌(用于登录页面))提供预填充的表单字段。进行剪贴时,您需要自动预填充这些字段,并且只覆盖其中的一些,例如用户名和密码。您可以使用 此作业的方法。这里有一个使用它的爬虫示例:<input type="hidden"> FormRequest.from_response()

    
     
     
    1. import scrapy
    2. class LoginSpider(scrapy.Spider):
    3. name = 'example.com'
    4. start_urls = ['http://www.example.com/users/login.php']
    5. def parse(self, response):
    6. return scrapy.FormRequest.from_response(
    7. response,
    8. formdata={'username': 'john', 'password': 'secret'},
    9. callback=self.after_login
    10. )
    11. def after_login(self, response):
    12. # check login succeed before going on
    13. if "authentication failed" in response.body:
    14. self.logger.error("Login failed")
    15. return
    16. # continue scraping with authenticated session...

    响应对象

    class scrapy.http.Response(url[, status=200, headers=None, body=b'', flags=None, request=None])
    一个Response对象表示的HTTP响应,这通常是下载(由下载),并供给到爬虫进行处理。

    参数:

    • url(string) - 此响应的URL
    • status(integer) - 响应的HTTP状态。默认为200。
    • headers(dict) - 这个响应的头。dict值可以是字符串(对于单值标头)或列表(对于多值标头)。
    • body(str) - 响应体。它必须是str,而不是unicode,除非你使用一个编码感知响应子类,如 TextResponse
    • flags(list) - 是一个包含属性初始值的 Response.flags列表。如果给定,列表将被浅复制。
    • request(Requestobject) - 属性的初始值Response.request。这代表Request生成此响应。


    url
    包含响应的URL的字符串。

    此属性为只读。更改响应使用的URL replace()。

    status
    表示响应的HTTP状态的整数。示例:200, 404。

    headers
    包含响应标题的类字典对象。可以使用get()返回具有指定名称的第一个标头值或getlist()返回具有指定名称的所有标头值来访问值。例如,此调用会为您提供标题中的所有Cookie:

    response.headers.getlist('Set-Cookie')
     
     

    body
    本回复的正文。记住Response.body总是一个字节对象。如果你想unicode版本使用 TextResponse.text(只在TextResponse 和子类中可用)。

    此属性为只读。更改响应使用的主体 replace()。

    request
    Request生成此响应的对象。在响应和请求通过所有下载中间件后,此属性在Scrapy引擎中分配。特别地,这意味着:

    HTTP重定向将导致将原始请求(重定向之前的URL)分配给重定向响应(重定向后具有最终URL)。
    Response.request.url并不总是等于Response.url
    此属性仅在爬虫程序代码和 Spider Middleware中可用,但不能在Downloader Middleware中使用(尽管您有通过其他方式可用的请求)和处理程序response_downloaded。

    meta
    的快捷方式Request.meta的属性 Response.request对象(即self.request.meta)。

    与Response.request属性不同,Response.meta 属性沿重定向和重试传播,因此您将获得Request.meta从您的爬虫发送的原始属性。

    也可以看看

    Request.meta 属性

    flags
    包含此响应的标志的列表。标志是用于标记响应的标签。例如:’cached’,’redirected ‘等等。它们显示在Response( str 方法)的字符串表示上,它被引擎用于日志记录。

    copy()
    返回一个新的响应,它是此响应的副本。

    replace([ url,status,headers,body,request,flags,cls ] )
    返回具有相同成员的Response对象,但通过指定的任何关键字参数赋予新值的成员除外。该属性Response.meta是默认复制。

    urljoin(url )
    通过将响应url与可能的相对URL 组合构造绝对url。

    这是一个包装在urlparse.urljoin,它只是一个别名,使这个调用:

    urlparse.urljoin(response.url, url)
     
     

    响应子类

    这里是可用的内置Response子类的列表。您还可以将Response类子类化以实现您自己的功能。

    TextResponse对象

    class scrapy.http.TextResponse(url[, encoding[, ...]])

    TextResponse对象向基Response类添加编码能力 ,这意味着仅用于二进制数据,例如图像,声音或任何媒体文件。

    TextResponse对象支持一个新的构造函数参数,除了基础Response对象。其余的功能与Response类相同,这里没有记录。

    参数: encoding(string) - 是一个字符串,包含用于此响应的编码。如果你创建一个TextResponse具有unicode主体的对象,它将使用这个编码进行编码(记住body属性总是一个字符串)。如果encoding是None(默认值),则将在响应标头和正文中查找编码。
    TextResponse除了标准对象之外,对象还支持以下属性Response

    text
    响应体,如unicode。

    同样response.body.decode(response.encoding),但结果是在第一次调用后缓存,因此您可以访问 response.text多次,无需额外的开销。

    注意
    unicode(response.body)不是一个正确的方法来将响应身体转换为unicode:您将使用系统默认编码(通常为ascii)而不是响应编码。

    encoding
    包含此响应的编码的字符串。编码通过尝试以下机制按顺序解决:

    1. 在构造函数编码参数中传递的编码
    2. 在Content-Type HTTP头中声明的编码。如果此编码无效(即未知),则会被忽略,并尝试下一个解析机制。
    3. 在响应主体中声明的编码。TextResponse类不提供任何特殊功能。然而, HtmlResponse和XmlResponse类做。
    4. 通过查看响应体来推断的编码。这是更脆弱的方法,但也是最后一个尝试。


    selector
    一个Selector使用响应为目标实例。选择器在第一次访问时被延迟实例化。

    TextResponse对象除了标准对象外还支持以下方法Response:

    xpath(查询)
    快捷方式TextResponse.selector.xpath(query)

    response.xpath('//p')
     
     

    css(query)
    快捷方式 TextResponse.selector.css(query):

    response.css('p')
     
     

    body_as_unicode()
    同样text,但可用作方法。保留此方法以实现向后兼容; 请喜欢response.text。

    HtmlResponse对象

    class scrapy.http.HtmlResponse(url [,... ] )
    本HtmlResponse类的子类,TextResponse 这增加了通过查看HTML编码自动发现支持META HTTP-EQUIV属性。见TextResponse.encoding。

    XmlResponse对象

    class scrapy.http.XmlResponse(url [,... ] )
    本XmlResponse类的子类,TextResponse这增加了通过查看XML声明线路编码自动发现支持。见TextResponse.encoding。

            </div>
                </div>
            </article>
    

    转载自:https://blog.csdn.net/weixin_37947156/article/details/74974208

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值