Scrapy-请求和响应

news/2024/7/19 11:47:13 标签: scrapy, python, 爬虫

Scrapy使用RequestResponse对象来爬行网站。通常,Request对象是在爬虫中生成的,并在整个系统中传递,直到它们到达下载器,后者执行请求并返回一个Response对象,该对象返回发出Request爬虫

RequestResponse类都有子类,这些子类添加了基类中不需要的功能。这些将在下面的Request子类和Response子类中进行描述

Request

scrapy.http.Request(*args, **kwargs)类,表示HTTP请求,该请求通常在爬虫中生成并由下载器执行,从而生成Responsescrapy.http.Request(*args, **kwargs)类接收以下参数:

  • url: 此请求的URL,str类型。如果该URL无效,则会引发ValueError异常|
  • callback: 将使用此请求的响应作为其第一个参数来调用的函数,collections.abc.Callable类型
  • method: 此请求的HTTP方法,str类型。默认为GET
  • meta: Request.meta熟悉的初始值, dict类型。如果给定,则将浅拷贝传入此dict
  • body: 请求主体。bytes或str类型
  • headers: 此请求的标头, dict类型。注意:如果需要为请求设置cookie,请使用cookies参数
  • cookies: 请求cookies, dict或list。
python">from scrapy.http import Request

# 使用DICT
request_with_cookies = Request(url='http://www.example.com',
                               cookies={'currency': 'USD', 'country': 'UY'})

# 使用LIST
request_with_cookies = Request(url='http://www.example.com',
                               cookies=[{
                                   'name': 'currency',
                                   'value': 'USD',
                                   'domain': 'example.com',
                                   'path': '/currency'
                               }])

List类型cookies允许自定义cookies的domainpath属性。这只在为以后得请求保存cookies时有用。

  • encondig: 此请求的编码,str类型。默认为utf-8
  • priority: 此请求的优先级,int类型,默认为0
  • dont_filter: 指示调度器不应筛选此请求,bool类型,默认为False。当您希望多次执行相同的请求时,可以使用此选项忽略重复的筛选器
  • errback: 如果在处理请求时引发任何异常,则将调用该函数,这包括出现404错误等错误的页面,collections.abc.Callable类型。
  • flags: 发送到请求的标志,可用于日志记录或类似用途, list类型
  • cb_kwargs: 具有任意数据的dict,将作为关键字参数传递到请求的回调,dict类型。

Request除了接收上面这些参数之外,它还具有以下属性和方法:

  • url: 此请求的URL的字符串。此属性是只读的,如果想要更改请求的URL,请使用Request.replace()方法
  • method: 表示请求中HTTP方法的字符串,而且是大写的,例如GET, POST等。
  • headers: 包含请求头的类似字典的对象
  • body: 以bytes表示的请求正文。此属性是只读的,要更改请求正文,请使用Request.replace()方法
  • meta: 包含此请求的任意元数据的dict。
  • cb_kwargs: 包含此请求的任意元数据的字典,它的内容将作为关键字参数传递给请求的回调
  • copy(): 返回一个新的请求,它是此请求的副本。
  • replace([url, method, headers, body, cookies, meta, flags, encoding, priority, dont_filter, callback, errback, cb_kwargs]): 返回一个具有相同成员的Request对象,但由指定的关键字参数赋予新值的成员除外。这个cb_kwargsmeta默认情况下,属性被浅复制
  • classmethod from_curl(curl_command, ignore_unknown_options=True, **kwargs): 从包含cURL命令的字符串创建Request对象。它填充HTTP方法、URL、报头、Cookie和正文。它接受与Request类相同的参数,采用优先级并覆盖cURL命令中包含的相同参数的值
  • to_dict(*, spider): 返回包含请求数据的字典

向回调函数传递附加数据

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

python">def parse_page_1(self, response):
    return scrapy.Request('http://www.example.com/some_page.html',
                          callback=self.parse_page_2)
    
def parse_page_2(self, response):
    self.logger.info(f'Visited {response.url}')

在某些情况下,你可能对向这些回调函数传递参数感兴趣,以便稍后在第二个回调中接收这些参数。下面的示例演示如何通过使用Request.cb_kwargs属性:

python">def parse_page_1(self, response):
    request = scrapy.Request('http://www.example.com/some_page.html',
                             callback=self.parse_page_2,
                             cb_kwargs=dict(main_url=response.url))
    request.cb_kwargs['foo'] = 'bar'
    yield request
    
def parse_page_2(self, response, main_url, foo):
    yield dict(main_url=main_url,
               other_url=response.url,
               foo=foo)

errback回调函数

errback是一个函数,在处理异常时将调用该函数。它收到一个Failure作为第一个参数,可用于跟踪连接建立超时、DNS错误等。如下:

python">import scrapy
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError

def parse(self, response):
    request = scrapy.Request('http://www.example.com/some_page.html',
                             callback=self.parse_page_1,
                             errback=self.parse_page_2,
                             cb_kwargs=dict(main_url=response.url))
    yield request
    
def parse_page_1(self, response, main_url):
    pass
    
def parse_page_2(self, failure):
    if failure.check(HttpError):
        response = failure.value.response
        self.logger.error(f"HttpError on {response.url}")
    
    elif failure.check(DNSLookupError):
        request = failure.request
        self.logger.error(f"DNSLookupError on {request.url}")
    
    elif failure.check(TimeoutError, TCPTimedOutError):
        request = failure.request
        self.logger.error(f'TimeoutError on {request.url}')
    elif failure.check(TimeoutError, TCPTimedOutError):
        request = failure.request
        self.logger.error('TimeoutError on %s', request.url)

Request子类

这些是内置的Request子类,您还可以将其子类化,以实现你自己的自定义功能

FormRequest

scrapy.http.FormRequest(url[, formdata, ...])类扩展了Request, 具有处理HTML表单的功能。它使用lxml.html.forms用来自Response对象的表单数据预填充表单字段。

这个FormRequest类将新的关键字参数添加到__init__方法。其余的参数与Request类相同,这里不作记录:

  • formdata: 包含HTML表单数据的字段(或可为(键、值)元组),这些数据将被URL编码并分配给请求主体。

FormRequest对象还支持以下类方法:

  • classmethod from_response(response, formname=None, formid=None, formnumber=0, formdata=None, clickdata=None, dont_click=False, formxpath=None, formcss=None, **kwargs)

返回新的FormRequest对象,其表单字段值预填充在HTML中<form>包含在给定响应中的元素。默认情况下,策略是在任何看起来可点击的窗体控件上自动模拟单击,如<input type="submit">. 尽管这非常方便,而且通常是理想的行为,但有时它会导致难以调试的问题。例如,当处理使用javascript填写或/提交的表单时,默认的from_response()行为可能不是最合适的。要禁用这种行为,可以将dont_click参数设置为True。另外,如果你想改变控件点击(而不是禁用它),你也可以使用clickdata参数。

from_response()接收的参数详解如下:

  • response: 包含用于预填充表单字段的HTML表单响应,为一个Response对象
  • formname: 如果给出,表单的name属性将设置为该值。str类型
  • formid: 如果给出,表单的id属性将设置为该值。str类型
  • formxpath: 如果给出,将使用与xpath匹配的第一个表单。str类型
  • formcss: 如果给出,将使用与css匹配的第一个表单。str类型
  • formnumber: 当response包含多个表单时要使用的第几个表单,第一个是0。int类型
  • formdata: 要在表单数据中重写的字段,如果响应中已经存在字段<form>元素,其值将被此参数中传递的值重写。dict类型
  • clickdata: 用于查找单击的控件的属性。如果没有给出,将提交表单数据,模拟单击第一个可单击元素。dict类型
  • dont_click: 如果为True,则表单的数据将在不单击任何元素的情况下提交。bool类型

FormRequest使用如下:

python">import scrapy

def authentication_failed(response):
    pass
    
class LoginSpider(scrapy.Spider):
    name = 'example.com'
    start_urls = ['http://www.example.com/users/login.php']
    
    def parse(self, response):
        return scrapy.FormRequest.from_response(
            response,
            formdata={'username': 'john', 'password': 'secret'},
            callback=self.after_login
        )
    
    def ater_login(self, response):
        if authentication_failed(response):
            self.logger.error('login failed')
            return

JsonRequest

scrapy.http.JsonRequest(url[, ...,data, dumps_kwargs])类扩展了Request类,具有处理JSON请求的功能。这个FormRequest类将新的关键字参数添加到__init__方法。其余的参数与Request类相同,这里不作记录:

  • data: 是需要对JSON编码并分配给主体的任何JSON可序列化对象。如果Request.body提供了此参数,此参数将被忽略。如果Request.body未提供参数,并且提供了data参数,Request.method将被自动设置为POST
  • dumps_kwargs: 将传递给json.dumps()方法的参数,用于将数据序列化为JSON对象。dict类型

JsonRequest使用如下:

python">data = {
    'name1': 'value1',
    'name2': 'value2'
}
yield JsonRequest(url='http://www.example.com/post/action', data=data)

Response

scrapy.http.Response(*args, **kwargs)表示HTTP响应的对象,通常下载并提供给Spider进行处理。Response接收以下参数:

  • url: 此响应的URL,str类型
  • status: 响应的HTTP状态,int类型, 默认为200
  • headers: 此响应的头,dict类型
  • body: 响应体,bytes类型
  • flags: 是一个Response.flags属性初始值的列表,如果给定,将浅复制列表
  • request: Response.request属性的初始值。这代表Request产生了这个响应
  • certificate: 表示服务器的SSL证书的对象
  • ip_address: 从哪个服务器发出的响应的IP地址
  • protocol: 用于下载响应的协议,str类型。例如:“HTTP/1.0”、“HTTP/1.1”、“h2”

Response除了接收上面这些参数之外,它还具有以下属性和方法:

  • url: 包含响应的URL的字符串。此属性是只读的,要修改响应的URL,请使用replace()方法
  • status: 表示响应的HTTP状态的整数。例子:200, 404
  • headers: 包含响应头的类似字典的对象。可以使用get()来访问具有指定名称的第一个头值,或者使用getlist()返回具有指定名称的所有头值。
python">response.headers.getlist('Set-Cookie')
  • body: 作为正文响应字节。此属性是只读的,要修改响应的body,请使用replace()方法
  • request: 生成此响应的Request对象。在响应和请求通过所有Downloader中间件之后,在Scrapy引擎中分配此属性
  • meta: 生成此响应的Request对象中的meta属性
  • cb_kwargs: 生成此响应的Request对象中的cb_kwargs属性
  • flags: 包含此响应标志的列表。flags是用于标记响应的标签,例如:‘cached’, 'redirect’等等
  • certificate: 为一个twisted.internet.ssl.Certificate对象,用于表示服务器SSL证书的。仅为https响应填充,否则为None
  • ip_address: 表示从哪个服务器发出响应的IP地址
  • protocol: 用于下载响应的协议。例如:“HTTP/1.0”、“HTTP/1.1”
  • copy(): 返回此响应的副本的新响应
  • replace([url, status, headers, body, request, flags, cls]): 返回具有相同成员的响应对象,除了那些通过指定的关键字参数赋予新值的成员。属性meta默认情况下是复制的
  • urljoin(url): 通过将响应的url与可能的相对url组合起来构造一个绝对url
  • follow(url, callback=None, method='GET', headers=None, body=None, cookies=None, meta=None, encoding='utf-8', priority=0, dont_filter=False, errback=None, cb_kwargs=None, flags=None): 返回一个Request实例来跟随一个链接url。它接受与Request相同的参数,但url可以是一个相对url或scrapy.link.Link对象,而不仅仅是一个绝对url.
  • follow_all(urls, callback=None, method='GET', headers=None, body=None, cookies=None, meta=None, encoding='utf-8', priority=0, dont_filter=False, errback=None, cb_kwargs=None, flags=None): 返回一个可迭代的Request实例,以跟踪url中的所有链接。它接受与Request相同的参数,但url可以是一个相对url或scrapy.link.Link对象,而不仅仅是一个绝对url.

Response子类

这些是内置的Response子类,您还可以将其子类化,以实现你自己的自定义功能

TextResponse

scrapy.http.TextResponse对象向基本Response类添加了编码功能,它仅用于二进制数据,如图像、声音或任何媒体文件。这个TextResponse类将新的关键字参数添加到__init__方法。其余的参数与Response类相同,这里不作记录:

  • encoding: 包含用于此响应的编码字符串。如果您创建了一个以字符串为body的TextResponse对象,它将被转换为使用这种编码方式编码的字节。如果encoding为None,则将在响应头和正文中查找编码。

TextResponse对象除了包含Response中的属性和方法之外,对象还支持以下属性和方法:

  • text: 字符串格式的响应体
  • enconding: 响应编码的字符串
  • selector: 使用响应作为目标的Selector实例
  • xpath(query): xpath提取操作
  • css(query): css提取操作
  • json(): 将JSON文档反序列化为Python对象

HtmlResponse

scrapy.http.HtmlResponseTextResponse的子类,它通过查找HTML元http-equiv属性添加了编码自动发现支持

XmlResponse

scrapy.http.XmlResponseTextResponse的子类,它通过查找XML声明行添加了编码自动发现支持


http://www.niftyadmin.cn/n/209620.html

相关文章

String类的20种常见方法

和长度有关的方法 返回类型方法名作用intlength()得到一个字符串的字符个数一个中文是一个字符&#xff0c;一个英文是一个字符&#xff0c;一个转义字符是一个字符 和数组有关的方法 返回类型方法名作用byte[]getBytes()将一个字符串转换成字节数组char[]toCharArray()将一个…

C++语法(13)---- 模拟实现priority_queue

C语法&#xff08;12&#xff09;---- 模拟实现queue和stack_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/130068637 目录 1.使用 2.模拟实现 1.数据元素 2.数据建立 3.函数实现 4.向上调整和向下调整 3.仿函数&#xff08;函数对象&…

函数的参数

函数的默认实参 函数默认参数&#xff1a;函数的形参可以有默认值&#xff0c;如果我们自己传入参数&#xff0c;就用自己的数据&#xff0c;如果没有&#xff0c;那么用默认值 特别注意*&#xff1a; 如果某个位置有了默认参数&#xff0c;那么从这个位置往后&#xff0c;必…

P5717 【深基3.习8】三角形分类

题目描述 给出三条线段 a,b,ca,b,c 的长度&#xff0c;均是不大于 1000010000 的正整数。打算把这三条线段拼成一个三角形&#xff0c;它可以是什么三角形呢&#xff1f; 如果三条线段不能组成一个三角形&#xff0c;输出Not triangle&#xff1b;如果是直角三角形&#xff0c;…

QT5.15.2 在线安装下载速度慢的解决办法

系列文章目录 文章目录系列文章目录前言一、解决前言 QT对5.15以及以上版本已经停止提供离线安装包&#xff0c;在线安装网速慢如蜗牛&#xff0c;而且一旦断了又得从头下载&#xff0c;不支持断点续传 由于Qt5.15及以上版本不提供离线安装包&#xff0c;则需要使用在线安装进…

ARM与C语言的混合编程【嵌入式系统】

ARM与C语言的相互调用【嵌入式系统】前言推荐ARM与C语言的相互调用说明ARM7汇编语言与C语言间的模块接口ARM7汇编程序与C程序间变量互访ARM7汇编程序调用C程序C程序调用汇编程序C程序中内嵌ARM7汇编代码最后前言 以下内容源自《【嵌入式系统】》 仅供学习交流使用 推荐 Keil…

一文懂KL散度KL Divergence

本文翻译自https://naokishibuya.medium.com/demystifying-kl-divergence-7ebe4317ee68 KL散度中的KL全称是Kullback-Leibler&#xff0c;分别表示Solomon Kullback和Richard A.Leibler这两个人。 一、KL散度的定义 KL散度表明概率分布Q和概率分布P之间的相似性&#xff0c;由…

挖掘潜在用户:2023年海外社交电商网红营销策略解析

近年来&#xff0c;随着社交媒体的不断发展和电商行业的崛起&#xff0c;海外社交电商平台已经成为了一个飞速发展的领域。然而&#xff0c;随着市场竞争的加剧&#xff0c;越来越多的海外社交电商平台开始采用网红营销策略来提升品牌知名度和销售业绩。本文Nox聚星将和大家探讨…