zoukankan      html  css  js  c++  java
  • 关于Scrapy中post请求

    Scrapy默认的是get请求,想要发送post请求,就需要再method中说明,一般常用写法如下

    scrapy.Request(url=url,method="POST",headers=self.headers,callback=self.get_goods_list)

    但post请求通常会带有表单参数,对于表单参数的注入,引出了两种方式,这里说明一下。

    一、FormRequest

    普通请求使用scrapy.Request类就可以实现,但是遇到模拟表单或Ajax提交post请求的时候,就可以使用Request 子类 FormRequest类,因为他自带 formdata ,专门用来设置表单字段数据,默认method也是POST。

    scrapy.FormRequest(url=url,formdata=formdata,cookies=self.cookie,headers=self.headers,callback=self.get_goods_list)

    但要注意的是,这里的formdata是dict格式的,里面不能存在数字,如果有数字用引号括起来;

    如下:

     formdata = {"mode": "list", "year: ": "default","prev":"false","side_year":""}
     yield FormRequest(url=new_url, formdata = formdata, callback=self.parse_category, meta=meta)

    在FormRequest的说明文档中介绍:

    The FormRequest class adds a new argument to the constructor. The remaining arguments are the same as for the Request class and are not documented here.

    Parameters: formdata (dict or iterable of tuples) – is a dictionary (or iterable of (key, value) tuples) containing HTML Form data which will be url-encoded and assigned to the body of the request.

    说FormRequest新增加了一个参数formdata,接受包含表单数据的字典或者可迭代的元组,并将其转化为请求的body。并且FormRequest是继承Request的。

    class FormRequest(Request):
    
        def __init__(self, *args, **kwargs):
            formdata = kwargs.pop('formdata', None)
            if formdata and kwargs.get('method') is None:
                kwargs['method'] = 'POST'
    
            super(FormRequest, self).__init__(*args, **kwargs)
    
            if formdata:
                items = formdata.items() if isinstance(formdata, dict) else formdata
                querystr = _urlencode(items, self.encoding)
                if self.method == 'POST':
                    self.headers.setdefault(b'Content-Type', b'application/x-www-form-urlencoded')
                    self._set_body(querystr)
                else:
                    self._set_url(self.url + ('&' if '?' in self.url else '?') + querystr)
                ###
    
    
    def _urlencode(seq, enc):
        values = [(to_bytes(k, enc), to_bytes(v, enc))
                  for k, vs in seq
                  for v in (vs if is_listlike(vs) else [vs])]
        return urlencode(values, doseq=1)

    最终我们传递的{'key': 'value', 'k': 'v'}会被转化为'key=value&k=v' 并且默认的method是POST,这其实也暗示如果表单参数很少的时候,直接拼接到url上会更方便一些。

    再来看看Request

    二、Request

    scrapy.Request(url=url,method="POST",body=formdata,cookies=self.cookie,headers=self.headers,callback=self.get_goods_list)

    但这里的formdata必须得是序列化的json字符串,如果是表单格式,那么需要用json.dumps()转为字符串格式

     formdata = {"mode": "list", "year: ": "default","prev":"false","side_year":""}
     yield Request(url=new_url, body = json.dumps(formdata), callback=self.parse_category, meta=meta)

    参考:https://zhuanlan.zhihu.com/p/42817660

    作者:王陸

    -------------------------------------------

    个性签名:罔谈彼短,靡持己长。做一个谦逊爱学的人!

    本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位置注明作者及出处。鉴于博主处于考研复习期间,有什么问题请在评论区中提出,博主尽可能当天回复,加微信好友请注明原因

  • 相关阅读:
    C陷阱与缺陷代码分析之第2章语法陷阱
    Linux tail命令
    spring利用扫描方式对bean的处理(对任何版本如何获取xml配置信息的处理)
    mysql 初识之日志文件篇
    JavaScript实现复制功能
    [置顶] Hibernate从入门到精通(七)多对一单向关联映射
    android操作通讯录的联系人
    数据结构读书笔记(三)(C语言)
    Nginx 日志分析
    [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/14988056.html
Copyright © 2011-2022 走看看