Scrapy
使用Request
和Response
对象来爬行网站。通常,Request
对象是在爬虫中生成的,并在整个系统中传递,直到它们到达下载器,后者执行请求并返回一个Response
对象,该对象返回发出Request
的爬虫。
Request
和Response
类都有子类,这些子类添加了基类中不需要的功能。这些将在下面的Request
子类和Response
子类中进行描述
scrapy.http.Request(*args, **kwargs)
类,表示HTTP请求,该请求通常在爬虫中生成并由下载器执行,从而生成Response
。scrapy.http.Request(*args, **kwargs)
类接收以下参数:
url
: 此请求的URL,str
类型。如果该URL无效,则会引发ValueError
异常|callback
: 将使用此请求的响应作为其第一个参数来调用的函数,collections.abc.Callable
类型method
: 此请求的HTTP方法,str
类型。默认为GET
meta
: Request.meta
熟悉的初始值, dict
类型。如果给定,则将浅拷贝传入此dictbody
: 请求主体。bytes或str类型headers
: 此请求的标头, dict类型。注意:如果需要为请求设置cookie,请使用cookies参数cookies
: 请求cookies, dict或list。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的domain
和path
属性。这只在为以后得请求保存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_kwargs
和meta
默认情况下,属性被浅复制classmethod from_curl(curl_command, ignore_unknown_options=True, **kwargs)
: 从包含cURL命令的字符串创建Request
对象。它填充HTTP方法、URL、报头、Cookie和正文。它接受与Request
类相同的参数,采用优先级并覆盖cURL命令中包含的相同参数的值to_dict(*, spider)
: 返回包含请求数据的字典请求的回调是一个函数,在下载请求的响应时将调用该函数。将使用下载的Response
对象作为其第一个参数。如下:
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
属性:
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
是一个函数,在处理异常时将调用该函数。它收到一个Failure
作为第一个参数,可用于跟踪连接建立超时、DNS错误等。如下:
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
子类,您还可以将其子类化,以实现你自己的自定义功能
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中包含在给定响应中的元素。默认情况下,策略是在任何看起来可点击的窗体控件上自动模拟单击,如
. 尽管这非常方便,而且通常是理想的行为,但有时它会导致难以调试的问题。例如,当处理使用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
: 要在表单数据中重写的字段,如果响应中已经存在字段
元素,其值将被此参数中传递的值重写。dict
类型clickdata
: 用于查找单击的控件的属性。如果没有给出,将提交表单数据,模拟单击第一个可单击元素。dict
类型dont_click
: 如果为True,则表单的数据将在不单击任何元素的情况下提交。bool
类型FormRequest
使用如下:
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
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
使用如下:
data = {
'name1': 'value1',
'name2': 'value2'
}
yield JsonRequest(url='http://www.example.com/post/action', data=data)
scrapy.http.Response(*args, **kwargs)
表示HTTP响应的对象,通常下载并提供给Spider进行处理。Response
接收以下参数:
url
: 此响应的URL,str
类型status
: 响应的HTTP状态,int类型
, 默认为200headers
: 此响应的头,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()
返回具有指定名称的所有头值。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响应填充,否则为Noneip_address
: 表示从哪个服务器发出响应的IP地址protocol
: 用于下载响应的协议。例如:“HTTP/1.0”、“HTTP/1.1”copy()
: 返回此响应的副本的新响应replace([url, status, headers, body, request, flags, cls])
: 返回具有相同成员的响应对象,除了那些通过指定的关键字参数赋予新值的成员。属性meta
默认情况下是复制的urljoin(url)
: 通过将响应的url
与可能的相对url组合起来构造一个绝对urlfollow(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
子类,您还可以将其子类化,以实现你自己的自定义功能
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对象scrapy.http.HtmlResponse
为TextResponse
的子类,它通过查找HTML元http-equiv属性添加了编码自动发现支持
scrapy.http.XmlResponse
为TextResponse
的子类,它通过查找XML声明行添加了编码自动发现支持