form 表单添加请求头_第二章 第三节 Request请求对象详解

Request对象和Response对象是必须熟悉的。
Request对象负责请求的构造和处理
Response对象负责返回资源的解析和处理

一、Request对象参数

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

参数默认值是否必须说明url无Y请求的urlcallbackself.parseY下载器完成后的回调函数methodGETN请求类型: 支持GET、POST、PUT...headers{}N默认无, 但是有中间件会构造默认的请求头bodyb''N请求体, 只支持string, 内部会转换成bytecookies{}N附加cookie信息meta{}N元数据priority0N请求优先级, 数字越大, 优先级越高dont_filterFalseN是否过滤重复请求, True: 不过滤, False: 过滤, 默认会过滤重复请求errbackN发生错误时的回调函数, 部分中间件中的错误也会传送给这个方法flags[]N可以在中间件针对性的处理每个requestcb_kwargs{}N传递给callback方法的参数

1. 发起一般请求

# -*- coding: utf-8 -*-
import scrapy
from ccidcom.items import DocumentItem


class CcidcomSpider(scrapy.Spider):
    name = 'ccidcomSpider'
    allowed_domains = ['www.ccidcom.com']

    def start_requests(self):
        yield scrapy.Request(
            'http://www.ccidcom.com/yaowen/index.html',
            callback=self.parse,
            headers={  # 指定请求头
                'Content-Type': 'text',
            },
            cookies={'test_cookie': 'aaa'},
            meta={'column': 'yaowen'},
            dont_filter=True,
            errback=self.parse_error,
            cb_kwargs={'column': 'yaowen'})

    def parse(self, response, column):
        request = response.request
        print('自定义参数: ', column)
        print('请求头: ', request.headers)
        print('请求Cookies: ', request.cookies)
        print('元数据: ', response.meta)

    def parse_error(self, response):
        pass

运行scrapy crawl ccidcomSpider

# 输出
...
自定义参数:  yaowen
请求头:  {b'Content-Type': [b'text'], b'Accept': [b'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'], b'Accept-Language': [b'en'], b'User-Agent': [b'Scrapy/1.7.3 (+https://scrapy.org)'], b'Accept-Encoding': [b'gzip,deflate'], b'Cookie': [b'test_cookie=aaa']}
请求Cookies:  {'test_cookie': 'aaa'}
元数据:  {'column': 'yaowen', 'download_timeout': 180.0, 'download_slot': 'www.ccidcom.com', 'download_latency': 0.19195008277893066}
...

我们可以看到, 除了我们自己添加的headers, scrapy也会添加一些其他headers选项cookies会添加我们指定的cookie信息meta 可以将请求的所需要的数据从request传递到response中, 这样我们就可以在parse方法中直接读取到了, 在这里也要注意一点, 禁止meta里传递request对象

而且在meta中也附加了一些数据, download_timeout是指下载超时时间, download_slot: 跟踪的下载器插槽, 也就是调度器用来区分到底是哪个下载器, 根据主域名进行区分, download_latency: 下载器花费掉的时间, 单位是s

# 下面这种写法是完全禁止的
_req = scrapy.Request('http://www.baidu.com')
yield scrapy.Request('http://www.baidu.com', meta={'request': _req})

2. meta详解

  1. meta里的指定的key, 不能再用做业务, 否则会出错
  2. meta里禁止传递对象等, 防止无法销毁掉

key说明dont_redirectTrue/False, 禁止301,302跳转dont_retryTrue/False, 禁止失败重试handle_httpstatus_list允许的http状态码 [200, 400]handle_httpstatus_allTrue/False, 所有的状态码都是正常请求dont_merge_cookiesTrue/False禁止合并cookies, 当设置cookies参数的时候, 默认scrapy的cookie中间件可能覆盖掉你设置的cookies(key一样), 设置为False,则使用你设置的cookiescookiejar指定传递的cookiejar版本, scrapy中cookie不会自动传递, 所以必须指定一个cookiejar来传递, 稍后会详解dont_cacheTrue/False, 禁止缓存此请求redirect_reasons保存重定向的理由, [301,302, 'meta refresh']redirect_urls保存经过重定向的urlbindaddress设置请求的源ip, 有时候不起作用dont_obey_robotstxt是否遵守robot.txt协议download_timeout下载超时时间设置, 默认是设置里的DOWNLOAD_TIMEOUTdownload_maxsize下载的最大资源限制download_latency只读, 从开始请求到请求完成的时间download_fail_on_dataloss是否在响应中断是抛出错误, True/Falseproxy设置代理ipftp_userftp请求的用户ftp_passwordftp请求的密码referrer_policyheader头中的Referrer-Policy的值max_retry_times最大重试次数

这里的参数, 在稍后会详细讲解

二、FormRequest对象

FormRequest对象用来模拟post表单请求

FormRequest对象的参数和Request基本都是一样的, 但是多了一个formdataformdata是一个dict或者可迭代的元组, 包含form表单请求的具体内容

1. 发起表单请求

def start_requests(self):
        yield scrapy.FormRequest(url='http://www.ccidcom.com/user/dologin.do',
                                 formdata={
                                     'username': '你的账号',
                                     'password': '你的登录密码'
                                 },
                                 callback=self.after_login)

运行爬虫scrapy crawl CcidcomFormSpider
查看输出:

2019-08-16 14:54:41 [scrapy.core.engine] DEBUG: Crawled (200) <POST http://www.ccidcom.com/user/dologin.do> (referer: None)
返回的数据: {"code":1}
2019-08-16 14:54:41 [scrapy.core.engine] INFO: Closing spider (finished)

2. 从资源中获取表单数据提交, form_response

这种方法, 会读取到form标签中的所有元素的信息, 并且填入你指定的表单的值, 然后发起请求
目的在于, 很多表单中有一些隐藏的元素等, 或者表单唯一值, 来防止表单被重复提交, 这个方法就可以自动去获取到表单中的元素的值来提交

具体的方法:classmethod from_response(response[, formname=None, formid=None, formnumber=0, formdata=None, formxpath=None, formcss=None, clickdata=None, dont_click=False, …])

key默认值是否必须说明responseY上一页请求拿到的response对象formnameNoneN如果给出, 则解析form标签中含有name=value的表单formidNoneN同上, 解析id=给定值的表单formxpathNoneN同上, 解析指定的xpath的表单formcssNoneN同上, 解析给定的css的表单formnumber0N如果解析出来, 包含多个表单, 指定具体哪个表单, 默认0formdata{}N要提交的表单信息clickdataNoneN给定可点击的元素dont_clickFalseN如果是True, 则表单会在不包含点击按钮的情况下提交

优势:

  1. 不用去手动看表单中的隐藏元素, 也不用再代码中指定了, scrapy会自动帮你做到
  2. 不用在代码里指定表单的提交地址, scrapy会从标签自动获取

缺点:

  1. 现在绝大部分网站都是js模拟表单请求的, 根本没有标签, 这种情况不适用的
  2. 页面是渲染出来的, 也无法使用这个方法

现在我们来看一个例子

def start_requests(self):
        # 先访问表单所在的页面
        yield scrapy.Request('http://www.dcic-china.com/login/index.html',
                             callback=self.parse)

    def parse(self, response):
        # 这个方法会将上一个表单页面的资源传入, 并且自动解析表单元素
        # 然后补足你提供的表单的值(你自定义的值可能会覆盖表单页面的值)
        yield scrapy.FormRequest.from_response(response,
                                               formdata={
                                                   'username': '你的账号',
                                                   'password': '你的密码',
                                                   'code': '1111'
                                               },
                                               callback=self.after_login)

    def after_login(self, response):
        print('返回的数据: {}'.format(response.css('p.error::text').get()))

运行爬虫

...
2019-08-16 15:11:12 [scrapy.core.engine] DEBUG: Crawled (200) <POST http://www.dcic-china.com/login/index.html> (referer: http://www.dcic-china.com/login/index.html)
返回的数据: 验证码不正确
2019-08-16 15:11:12 [scrapy.core.engine] INFO: Closing spider (finished)
...

欢迎关注Python开发之路(微信号: python-developer)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值