Scrapy使用request对象来爬取web站点。

request对象由spiders对象产生,经由Scheduler传送到Downloader,Downloader执行request并返回response给spiders。

Scrapy架构:

1、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请求,通常有Spider产生,经Downloader执行从而产生一个Response。

Paremeters:     url(string): 用于请求的URL

callback(callable):指定一个回调函数,该回调函数以这个request是的response作为第一个参数。如果未指定callback,

则默认使用spider的parse()方法。

method(string):HTTP请求的方法,默认为GET(看到GET你应该明白了,过不不明白建议先学习urllib或者requets模块)

meta(dict):指定Request.meta属性的初始值。如果给了该参数,dict将会浅拷贝。(浅拷贝不懂的赶紧回炉)

body(str):the request body.(这个没有理解,若有哪位大神明白,请指教,谢谢)

headers(dict):request的头信息。

cookies(dict or list):cookie有两种格式。

1、使用dict:

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

2、使用字典的list

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

后面这种形式可以定制cookie的domain和path属性,只有cookies为接下来的请求保存的时候才有用。

当网站在response中返回cookie时,这些cookie将被保存以便未来的访问请求。这是常规浏览器的行为。如果你想避免修改当前

正在使用的cookie,你可以通过设置Request.meta中的dont_merge_cookies为True来实现。

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

encoding(string):请求的编码, 默认为utf-8

priority(int):请求的优先级

dont_filter(boolean):指定该请求是否被 Scheduler过滤。该参数可以是request重复使用(Scheduler默认过滤重复请求)。谨慎使用!!

errback(callable):处理异常的回调函数。

属性和方法:

url: 包含request的URL的字符串

method: 代表HTTP的请求方法的字符串,例如'GET', 'POST'...

headers: request的头信息

body: 请求体

meta: 一个dict,包含request的任意元数据。该dict在新Requests中为空,当Scrapy的其他扩展启用的时候填充数据。dict在传输是浅拷贝。

copy(): 拷贝当前Request

replace([url, method, headers, body, cookies, meta, encoding, dont_filter, callback, errback]): 返回一个参数相同的Request,

可以为参数指定新数据。

给回调函数传递数据

当request的response被下载是,就会调用回调函数,并以response对象为第一个参数

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)

example

在某些情况下,你希望在回调函数们之间传递参数,可以使用Request.meta。(其实有点类似全局变量的赶脚)

def parse_page1(self, response):
item = MyItem()
item['main_url'] = response.url
request = scrapy.Request("http://www.example.com/some_page.html",
callback=self.parse_page2)
request.meta['item'] = item
yield request def parse_page2(self, response):
item = response.meta['item']
item['other_url'] = response.url
yield item

使用errback来捕获请求执行中的异常

当request执行时有异常抛出将会调用errback回调函数。

它接收一个Twisted Failure实例作为第一个参数,并被用来回溯连接超时或DNS错误等。

 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/", # HTTP 200 expected
"http://www.httpbin.org/status/404", # Not found error
"http://www.httpbin.org/status/500", # server issue
"http://www.httpbin.org:12345/", # non-responding host, 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('Got successful response from {}'.format(response.url))
# do something useful here... def errback_httpbin(self, failure):
# log all failures
self.logger.error(repr(failure)) # in case you want to do something special for some errors,
# you may need the failure's type: if failure.check(HttpError):
# these exceptions come from HttpError spider middleware
# you can get the non-200 response
response = failure.value.response
self.logger.error('HttpError on %s', response.url) elif failure.check(DNSLookupError):
# this is the original request
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)

example

Request.meta的特殊关键字

Request.meta可以包含任意的数据,但Scrapy和内置扩展提供了一些特殊的关键字

  • dont_redirect             (其实dont就是don't,嗯哼~)
  • dont_retry
  • handle_httpstatus_list
  • handle_httpstatus_all
  • dont_merge_cookies (see cookies parameter of Request constructor)
  • cookiejar
  • dont_cache
  • redirect_urls
  • bindaddress
  • dont_obey_robotstxt
  • download_timeout(下载超时)
  • download_maxsize
  • download_latency(下载延时)
  • proxy

2、Request subclasses

FormRequest object

FormRequest继承自Request类,增加了处理HTML表单数据的功能

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

FormRequest类新增了'formdata'参数在构造方法中,其他参数与Request类相同,不再赘述。

Parameters:

formdata (dict or iterable of tuple)是一个字典(或键值对的可迭代元组),包含HTML表单数据(会被url_encode)并部署到请求体重。

FormRequest对象支持一个标准Request方法之外的类方法

classmethod from_response(response[, formname=Noneformid=Noneformnumber=0formdata=Noneformxpath=Noneformcss=None

clickdata=Nonedont_click=False...])

根据response找到HTML的<from>元素,以此来填充给定的form字段值,并返回一个新的FormRequest对象。

在任何看起来可点击(例如<input type="submit">)的表单控制处,该策略默认自动模拟点击。虽然很方便,但有时会造成很难debug的问题,例如当满是javascript的and/or提交时,

默认的from_response就不再合适了。可以通过设置dont_click为True关闭这个动作。你也可以使用clickdata参数来改变对点击的控制。

parameters: 

response(Response object): 包含HTML form的response对象,用来填充form字段

formname(string): 如果设置,name为该值的form将被使用

formid(string): 如果设置,id为该值的form将被使用。

formxpath(string): 如果设置,和xpath匹配的第一个form将被使用

formcss(string): 如果设置,和css选择器匹配的第一个form将被使用

formnumber(integer): 当response包含多个form的时候,指定使用的数量。第一个为0 (也是默认值)

formdata(dict): 用来重写form数据的字段。如果某个字段在response的<form>元素中已经存在一个值,那么现存的值将被重写。

clickdata(dict): (没明白,暂时不写)

dont_click(boolean): 如果为True, form数据将会提交而不点击任何元素。

Request应用实例

使用FormRequest通过HTML POST发送数据

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

return [FormRequest(url="http://www.example.com/post/action",
formdata={'name': 'John Doe', 'age': ''},
callback=self.after_post)]

FormRequest

使用FormRequest.from_response模拟用户登录

web站点通常通过<input type="hidden">元素要求填充Form字段,比如会话相关数据或者验证口令(登录界面)。在爬取时,你想自动填充并重写这些字段,就像输入用户名和密码。可以使用

FormRequest.from_response()来实现。

import scrapy

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):
# check login succeed before going on
if "authentication failed" in response.body:
self.logger.error("Login failed")
return # continue scraping with authenticated session...

FormRequest.from_response

(本编为本人学习Scrapy文档时的翻译,因为英语不好看了后面忘前面实在痛苦,自己做了这篇翻译,水平有限,若有错误请指正,谢谢!)

参考文献:

https://doc.scrapy.org/en/1.3/topics/request-response.html#topics-request-response-ref-request-callback-arguments

Scrapy框架--Requests对象的更多相关文章

  1. 关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案

    Python爬虫总结 总的来说,Python爬虫所做的事情分为两个部分,1:将网页的内容全部抓取下来,2:对抓取到的内容和进行解析,得到我们需要的信息. 目前公认比较好用的爬虫框架为Scrapy,而且 ...

  2. python爬虫入门(六) Scrapy框架之原理介绍

    Scrapy框架 Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬 ...

  3. python爬虫入门(七)Scrapy框架之Spider类

    Spider类 Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取的动作 ...

  4. Scrapy 框架流程详解

    框架流程图 Scrapy 使用了 Twisted 异步非阻塞网络库来处理网络通讯,整体架构大致如下(绿线是数据流向): 简单叙述一下每层图的含义吧: Spiders(爬虫):它负责处理所有Respon ...

  5. 爬虫基础(五)-----scrapy框架简介

    ---------------------------------------------------摆脱穷人思维 <五> :拓展自己的视野,适当做一些眼前''无用''的事情,防止进入只关 ...

  6. Scrapy 框架简介

    Scrapy 框架 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前Scrapy的 ...

  7. 爬虫之Scrapy框架介绍

    Scrapy介绍 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内 ...

  8. 解读Scrapy框架

    Scrapy框架基础:Twsited Scrapy内部基于事件循环的机制实现爬虫的并发.原来: url_list = ['http://www.baidu.com','http://www.baidu ...

  9. Scrapy 框架 安装 五大核心组件 settings 配置 管道存储

    scrapy 框架的使用 博客: https://www.cnblogs.com/bobo-zhang/p/10561617.html 安装: pip install wheel 下载 Twisted ...

随机推荐

  1. 全面解析for循环

    牛刀小试: for(var i = 0 ; i < 100; i++) {console.log(i);} var i = 0;//第一个代码段 i < 100; //第二个代码段 i++ ...

  2. HTML5 贝塞尔绘画 桃心

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. 201521123051《Java程序设计》第八周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 集合与泛型综合示例 import java.util.ArrayLis ...

  4. 201521123007《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  5. 201521123017 《Java程序设计》第13周学习总结

    1. 本周学习总结 2. 书面作业 Q1.网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? 1.2 te ...

  6. 201521123085 《java程序设计》 第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前 ...

  7. Java课程设计——学生基本信息管理

    1.团队名称.团队成员介绍 团队名称:学生基本信息管理设计小组 团队成员:花雨芸(组长)--负责管理界面的编写 丁蓉(组员)--负责登陆的设计编写 2.项目git地址 https://git.osch ...

  8. python之---进程

    一.进程 1.什么是进程 (1)正在进行的一个过程或者说一个任务,而负责执行的就是CPU 2.进程与程序的区别 (1)程序仅仅是一堆代码而已,而进程指的是程序的运行过程 同一个程序执行两次,也是两个进 ...

  9. 如何定制 Calico 网络 Policy - 每天5分钟玩转 Docker 容器技术(70)

    Calico 默认的 policy 规则是:容器只能与同一个 calico 网络中的容器通信.本节讨论如何定制 policy. calico 能够让用户定义灵活的 policy 规则,精细化控制进出容 ...

  10. 你必知必会的SQL面试题

    写在前面的话 本文参考原博<走向面试之数据库基础:一.你必知必会的SQL语句练习-Part 1>和<走向面试之数据库基础:一.你必知必会的SQL语句练习-Part 2>进行练习 ...