【Scrapy 框架翻译】请求和回应(Requests and Responses) 篇
版本号:Scrapy 2.4
内容介绍
Scrapy 中的 Request 和 Response 用于抓取网站的数据使用。
Request 对象在数据抓取中生成,并在系统中传递到达下载程序,后者执行请求并返回 Response 对象,该对象返回到发出请求的spider。
请求对象(Request objects)
class scrapy.http.Request(*args, **kwargs)
主要参数:
url (str) :请求的URL,如果URL无效,则ValueError引发异常
callback :回调函数,用于执行下一步的指定的回调方法
method:HTTP访问的方法,默认GET
meta:传递参数的字典
body :抓取的request文本信息,默认编码utf-8
headers : 设置的request的hearder信息,通常会采用新的方法随机更换
cookies:设置的request的cookies信息,一般存储方式为字典
encoding:默认为utf-8
priority:处理程序的优先级
dont_filter:是否忽略重复的过滤设置
errback:错误回调函数
flags:用于日志记录
cb_kwargs:任意数据的dict,这些数据将作为关键字参数传递给请求的回调函数
附加数据传递给回调函数
请求的回调是在下载该请求的响应时调用的函数
def parse_page1(self, response):
return scrapy.Request("http://www.example.com/some_page.html",
callback=self.parse_page2)
def parse_page2(self, response):
# this would log http://www.example.com/some_page.html
self.logger.info("Visited %s", response.url)
在第二个回调中接收参数使用Request.cb_kwargs属性
def parse(self, response):
request = scrapy.Request('http://www.example.com/index.html',
callback=self.parse_page2,
cb_kwargs=dict(main_url=response.url))
request.cb_kwargs['foo'] = 'bar' # add more arguments for the callback
yield request
def parse_page2(self, response, main_url, foo):
yield dict(
main_url=main_url,
other_url=response.url,
foo=foo,
)
请求处理中使用回退捕获异常
import scrapy
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError
class ErrbackSpider(scrapy.Spider):
name = "errback_example"
start_urls = [
"http://www.httpbin.org/", # 200 正常访问
"http://www.httpbin.org/status/404", # 404 无页面
"http://www.httpbin.org/status/500", # 500 服务器挂了
"http://www.httpbin.org:12345/", # 超时访问不到主机端口
"http://www.httphttpbinbin.org/", # DNS解析错误
]
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('Got successful response from {}'.format(response.url))
......
def errback_httpbin(self, failure):
# 全部的失败日志
self.logger.error(repr(failure))
# 如果想对某些错误进行特殊处理,需要失败的类型
if failure.check(HttpError):
# 这些异常来自HttpError Spider中间件获得非200的相应
response = failure.value.response
self.logger.error('HttpError on %s', response.url)
elif failure.check(DNSLookupError):
# 这是原始请求
request = failure.request
self.logger.error('DNSLookupError on %s', request.url)
elif failure.check(TimeoutError, TCPTimedOutError):
request = failure.request
self.logger.error('TimeoutError on %s', request.url)
访问errback函数中的其他数据
在处理请求失败时,可能要访问回调函数的参数,可以根据errback中的参数进行处理。
def parse(self, response):
request = scrapy.Request('http://www.example.com/index.html',
callback=self.parse_page2,
errback=self.errback_page2,
cb_kwargs=dict(main_url=response.url))
yield request
def parse_page2(self, response, main_url):
pass
def errback_page2(self, failure):
yield dict(
main_url=failure.request.cb_kwargs['main_url'],
)
Request.meta 特别键
更多详细的操作参考中间件和实际应用案例,这里只做出一些简单的解释
-
dont_redirect:如果Request.meta的dont_redirect**设置为True,则该中间件将忽略该请求。
-
dont_retry:如果Request.meta的dont_retry**设置为True,则此中间件将忽略该请求。
-
handle_httpstatus_list:如果仍要处理该范围以外的响应代码,则可以使用handle_httpstatus_list蜘蛛属性或HTTPERROR_ALLOWED_CODES设置指定spider能够处理的响应代码。
-
handle_httpstatus_all:Request.meta的handle_httpstatus_list键也可以用于指定每个请求允许的响应代码。如果要允许请求的任何响应代码,也可以将元键handle_httpstatus_all设置为True。
-
dont_merge_cookies:请求cookie。
-
cookiejar:支持使用cookiejar请求元**在每个蜘蛛中保留多个cookie会话。默认情况下,它使用单个cookie罐(会话),但是您可以传递一个标识符以使用其他标识符。
-
dont_cache:避免使用非True的dont_cache元键在每个策略上缓存响应。
-
redirect_reasons:可以在redirect_reasons Request.meta键中找到redirect_urls中每个重定向的原因。
-
redirect_urls:请求通过的URL(在重定向时)可以在redirect_urls Request.meta键中找到。
-
bindaddress:用于执行请求的传出IP地址的IP。
-
dont_obey_robotstxt:如果Request.meta的dont_obey_robotstxt**设置为True,则即使启用了ROBOTSTXT_OBEY,该中间件也将忽略该请求。
-
download_timeout:超时之前,下载程序将等待的时间(以秒为单位)。另请参阅:DOWNLOAD_TIMEOUT。
-
download_maxsize:可以使用download_maxsize spider属性为每个spider设置大小,并使用download_maxsize Request.meta键为每个请求设置大小。
-
download_latency:自请求开始以来(即通过网络发送的HTTP消息),获取响应所花费的时间。仅在下载响应后,此元**才可用。虽然大多数其他元**用于控制Scrapy行为,但该**应该是只读的。
-
download_fail_on_dataloss:是否因响应失败而失败。
-
proxy:该中间件通过为Request对象设置代理元值来设置HTTP代理用于请求。
-
ftp_user:当请求元中没有“ ftp_user”时,用于FTP连接的用户名。
-
ftp_password:当请求元中没有“ ftp_password”时,用于FTP连接的密码。
-
referrer_policy:填充请求“ Referer”标头时要应用的Referrer策略。
-
max_retry_times:使用元**设置每个请求的重试时间。初始化后,max_retry_times元键的优先级高于RETRY_TIMES设置。
停止响应
import scrapy
class StopSpider(scrapy.Spider):
name = "stop"
start_urls = ["https://docs.scrapy.org/en/latest/"]
@classmethod
def from_crawler(cls, crawler):
spider = super().from_crawler(crawler)
crawler.signals.connect(spider.on_bytes_received, signal=scrapy.signals.bytes_received)
return spider
def parse(self, response):
# “ last_chars”表明未下载完整响应
yield {"len": len(response.text), "last_chars": response.text[-40:]}
def on_bytes_received(self, data, request, spider):
raise scrapy.exceptions.StopDownload(fail=False)
请求子类
class scrapy.http.FormRequest(url[, formdata, …])
FormRequest对象,用于传递参数的类,具有处理HTML表单的功能。返回一个新FormRequest对象,该对象的表单字段值预先填充了给定响应中包含的HTML元素中的表单字段值。
主要参数
response(Response对象):包含HTML表单的响应用于填充表单字段
formname(str):若定义,将使用name属性设置为该值的表单。
formid(str):若定义,将使用id属性设置为此值的表单。
formxpath(str):若定义,将使用与xpath匹配的第一个形式。
formcss(str):若定义,将使用与css选择器匹配的第一个形式。
formnumber(int):响应包含多个表单时要使用的表单数。第一个(也是默认值)是0。
formdata(dict):表单数据中要覆盖的字段。如果响应元素中已经存在一个字段,则该字段的值将被传入此参数的字段覆盖。如果在此参数中传递的值为None,则即使该字段存在于响应元素中,该字段也不会包含在请求中。
clickdata(dict):查找单击的控件的属性。如果未提供,则将模拟第一个clickable元素上的单击提交表单数据。除了html属性外,还可以通过该nr属性,通过相对于表单内其他可提交输入的,从零开始的索引来标识该控件。
dont_click(bool):如果为True,则无需单击任何元素即可提交表单数据。
使用FormRequest通过HTTP POST发送数据
import scrapy
def authentication_failed(response):
# 检查响应的内容,如果失败,则返回True;如果成功,则返回False。
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 after_login(self, response):
if authentication_failed(response):
self.logger.error("Login failed")
return
class scrapy.http.JsonRequest(url[, … data, dumps_kwargs])
JsonRequest 中 header设置
{
'Content-Type':'application/json',
'Accept':'application/json, text/javascript, */*; q=0.01'
}
参数说明:
- data(对象):是需要JSON编码并分配给主体的任何JSON可序列化对象。如果Request.body提供了参数,则将忽略此参数。如果Request.body未提供参数而提供了数据参数Request.method将’POST’自动设置为。
- dumps_kwargs(dict):将传递给基础json.dumps()方法的参数,该方法用于将数据序列化为JSON格式。
发送带有JSON有效负载的JSON POST请求
data = {
'name1': 'value1',
'name2': 'value2',
}
yield JsonRequest(url='http://www.example.com/post/action', data=data)
响应对象
class scrapy.http.Response(* args,** kwargs)
一个Response对象代表一个HTTP响应,通常会下载该HTTP响应(由下载程序下载),然后到Spider进行处理。
参数说明:
-
url(str):该响应的URL
-
status(int):响应的HTTP状态。默认为200。
-
headers(dict):此响应的标头。dict值可以是字符串(对于单值标头)或列表(对于多值标头)。
-
body (字节):响应正文。要以字符串形式访问解码后的文本,请使用 response.text可识别编码的 Response子类,例如TextResponse。
-
flags (list):是一个包含Response.flags属性初始值的列表 。如果给出,列表将被浅表复制。
-
request(scrapy.http.Request):Response.request属性的初始值。这表示Request生成此响应。
-
certificate (twisted.internet.ssl.Certificate):代表服务器SSL证书的对象。
-
ip_address(ipaddress.IPv4Address或ipaddress.IPv6Address):发起响应的服务器的IP地址。
响应子类
可用的内置Response子类的列表,可以对Response类进行子类化,以实现设置的功能。
class scrapy.http.TextResponse(url[, encoding[, …]])
TextResponse对象为基Response类增加了编码功能,该功能 只能用于二进制数据,例如图像,声音或任何媒体文件。
这里数据处理的方式同响应部分,都是对字符串进行处理,就不重复了。
class scrapy.http.HtmlResponse(url[, …])
HtmlResponse对象,其增加了通过查看HTML编码自动发现支持META HTTP-EQUIV属性。
class scrapy.http.XmlResponse(url[, …])
XmlResponse对象,其增加了通过查看XML声明行编码自动发现支持。
下一篇: 【JS】从Function说原型