欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python使用scrapy發(fā)送post請求的坑

 更新時間:2018年09月04日 08:27:36   作者:崔斯特的博客  
這篇文章主要介紹了使用scrapy發(fā)送post請求的坑,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

使用requests發(fā)送post請求

先來看看使用requests來發(fā)送post請求是多少好用,發(fā)送請求

Requests 簡便的 API 意味著所有 HTTP 請求類型都是顯而易見的。例如,你可以這樣發(fā)送一個 HTTP POST 請求:

>>>r = requests.post('http://httpbin.org/post', data = {'key':'value'})

使用data可以傳遞字典作為參數(shù),同時也可以傳遞元祖

>>>payload = (('key1', 'value1'), ('key1', 'value2'))
>>>r = requests.post('http://httpbin.org/post', data=payload)
>>>print(r.text)
{
 ...
 "form": {
  "key1": [
   "value1",
   "value2"
  ]
 },
 ...
}

傳遞json是這樣

>>>import json

>>>url = 'https://api.github.com/some/endpoint'
>>>payload = {'some': 'data'}

>>>r = requests.post(url, data=json.dumps(payload))

2.4.2 版的新加功能:

>>>url = 'https://api.github.com/some/endpoint'
>>>payload = {'some': 'data'}

>>>r = requests.post(url, json=payload)

也就是說,你不需要對參數(shù)做什么變化,只需要關(guān)注使用data=還是json=,其余的requests都已經(jīng)幫你做好了。

使用scrapy發(fā)送post請求

通過源碼可知scrapy默認發(fā)送的get請求,當我們需要發(fā)送攜帶參數(shù)的請求或登錄時,是需要post、請求的,以下面為例

from scrapy.spider import CrawlSpider
from scrapy.selector import Selector
import scrapy
import json
class LaGou(CrawlSpider):
  name = 'myspider'
  def start_requests(self):
    yield scrapy.FormRequest(
      url='https://www.******.com/jobs/positionAjax.json?city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false',
      formdata={
        'first': 'true',#這里不能給bool類型的True,requests模塊中可以
        'pn': '1',#這里不能給int類型的1,requests模塊中可以
        'kd': 'python'
      },這里的formdata相當于requ模塊中的data,key和value只能是鍵值對形式
      callback=self.parse
    )
  def parse(self, response):
    datas=json.loads(response.body.decode())['content']['positionResult']['result']
    for data in datas:
      print(data['companyFullName'] + str(data['positionId']))

官方推薦的 Using FormRequest to send data via HTTP POST

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

這里使用的是FormRequest,并使用formdata傳遞參數(shù),看到這里也是一個字典。

但是,超級坑的一點來了,今天折騰了一下午,使用這種方法發(fā)送請求,怎么發(fā)都會出問題,返回的數(shù)據(jù)一直都不是我想要的

return scrapy.FormRequest(url, formdata=(payload))

在網(wǎng)上找了很久,最終找到一種方法,使用scrapy.Request發(fā)送請求,就可以正常的獲取數(shù)據(jù)。

復制代碼 代碼如下:
return scrapy.Request(url, body=json.dumps(payload), method='POST', headers={'Content-Type': 'application/json'},)

參考:Send Post Request in Scrapy

my_data = {'field1': 'value1', 'field2': 'value2'}
request = scrapy.Request( url, method='POST', 
             body=json.dumps(my_data), 
             headers={'Content-Type':'application/json'} )

FormRequest 與 Request 區(qū)別

在文檔中,幾乎看不到差別,

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新增加了一個參數(shù)formdata,接受包含表單數(shù)據(jù)的字典或者可迭代的元組,并將其轉(zhuǎn)化為請求的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'}會被轉(zhuǎn)化為'key=value&k=v' 并且默認的method是POST,再來看看Request

class Request(object_ref):

  def __init__(self, url, callback=None, method='GET', headers=None, body=None,
         cookies=None, meta=None, encoding='utf-8', priority=0,
         dont_filter=False, errback=None, flags=None):

    self._encoding = encoding # this one has to be set first
    self.method = str(method).upper()

默認的方法是GET,其實并不影響。仍然可以發(fā)送post請求。這讓我想起來requests中的request用法,這是定義請求的基礎(chǔ)方法。

def request(method, url, **kwargs):
  """Constructs and sends a :class:`Request <Request>`.

  :param method: method for the new :class:`Request` object.
  :param url: URL for the new :class:`Request` object.
  :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
  :param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`.
  :param json: (optional) json data to send in the body of the :class:`Request`.
  :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
  :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
  :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
    ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
    or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
    defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
    to add for the file.
  :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
  :param timeout: (optional) How many seconds to wait for the server to send data
    before giving up, as a float, or a :ref:`(connect timeout, read
    timeout) <timeouts>` tuple.
  :type timeout: float or tuple
  :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
  :type allow_redirects: bool
  :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
  :param verify: (optional) Either a boolean, in which case it controls whether we verify
      the server's TLS certificate, or a string, in which case it must be a path
      to a CA bundle to use. Defaults to ``True``.
  :param stream: (optional) if ``False``, the response content will be immediately downloaded.
  :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
  :return: :class:`Response <Response>` object
  :rtype: requests.Response

  Usage::

   >>> import requests
   >>> req = requests.request('GET', 'http://httpbin.org/get')
   <Response [200]>
  """

  # By using the 'with' statement we are sure the session is closed, thus we
  # avoid leaving sockets open which can trigger a ResourceWarning in some
  # cases, and look like a memory leak in others.
  with sessions.Session() as session:
    return session.request(method=method, url=url, **kwargs)

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 用python3教你任意Html主內(nèi)容提取功能

    用python3教你任意Html主內(nèi)容提取功能

    這篇文章主要介紹了用python3教你任意Html主內(nèi)容提取功能,主要使用到了requests、lxml、json等模塊,文中逐一對這幾個模塊做了介紹,需要的朋友可以參考下
    2018-11-11
  • Django基礎(chǔ)知識 web框架的本質(zhì)詳解

    Django基礎(chǔ)知識 web框架的本質(zhì)詳解

    這篇文章主要介紹了Django基礎(chǔ)知識 web框架的本質(zhì)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • Python常見報錯解決之SciPy和NumPy版本沖突

    Python常見報錯解決之SciPy和NumPy版本沖突

    Scipy是基于Numpy的科學計算工具庫,方便、易于使用、專為科學和工程設(shè)計,是一個用于數(shù)學、科學、工程領(lǐng)域的常用軟件包,這篇文章主要給大家介紹了關(guān)于Python常見報錯解決之SciPy和NumPy版本沖突的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • 利用python爬取m3u8格式視頻的具體實現(xiàn)

    利用python爬取m3u8格式視頻的具體實現(xiàn)

    之前爬取的視頻都是mp4格式的,直接用requests請求就可以直接爬取,最近公司安排了一個小任務(wù),需要爬取m3u8這種格式的視頻,下面這篇文章主要給大家介紹了關(guān)于利用python爬取m3u8格式視頻的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Python-VTK隱式函數(shù)屬性選擇和剪切數(shù)據(jù)

    Python-VTK隱式函數(shù)屬性選擇和剪切數(shù)據(jù)

    這篇文章主要介紹了Python-VTK隱式函數(shù)屬性選擇和剪切數(shù)據(jù),VTK,是一個開放資源的免費軟件系統(tǒng),主要用于三維計算機圖形學、圖像處理和可視化,下面文章主題相關(guān)詳細內(nèi)容需要的小伙伴可以參考一下
    2022-04-04
  • python繪制lost損失曲線加方差范圍的操作方法

    python繪制lost損失曲線加方差范圍的操作方法

    這篇文章主要介紹了python繪制lost損失曲線加方差范圍的操作方法,首先大家需要導入必要的包及數(shù)據(jù)的獲取方法,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2021-10-10
  • python tkinter實現(xiàn)簡單計算器功能

    python tkinter實現(xiàn)簡單計算器功能

    這篇文章主要為大家詳細介紹了python tkinter實現(xiàn)簡單計算器功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 使用Django搭建一個基金模擬交易系統(tǒng)教程

    使用Django搭建一個基金模擬交易系統(tǒng)教程

    今天小編就為大家分享一篇使用Django搭建一個基金模擬交易系統(tǒng)教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • Python3.5 Pandas模塊之DataFrame用法實例分析

    Python3.5 Pandas模塊之DataFrame用法實例分析

    這篇文章主要介紹了Python3.5 Pandas模塊之DataFrame用法,結(jié)合實例形式詳細分析了Python3.5中Pandas模塊的DataFrame結(jié)構(gòu)創(chuàng)建、讀取、過濾、獲取等相關(guān)操作技巧與注意事項,需要的朋友可以參考下
    2019-04-04
  • Python如何有效地使用迭代

    Python如何有效地使用迭代

    這篇文章主要為大家詳細介紹了Python如何有效地使用迭代,文中的示例代碼講解詳細,對我們深入了解Python有一定的幫助,需要的小伙伴可以學習一下
    2023-09-09

最新評論