2015-04-23 54 views
1

我需要使用grequests進行異步POST請求。使用grequests發佈json數據?

我的身體後(以JSON),是這樣的:

[{'params': {'source': 'widget', 
    'id': 'http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif', 
    'groupId': '@self', 
    'nolog': 'true', 
    'userId': '@viewer'}, 
    'method': 'pos.plusones.get', 
    'id': 'p', 
    'jsonrpc': '2.0', 
    'apiVersion': 'v1', 
    'key': 'p'}] 

我需要[0]['params']['id']鍵的值更改爲不同的URL的很多帖子,我會做。

所以我做:

myrequests = (grequests.post(POST_URL, data=fgp(a_url) for a_url in all_urls)

在我的理解產生的fgp()方法是改變[0]['params']['id']a_url傳遞給它,在POST身體我送的方法。

當我映射請求的響應:

myresponses = grequests.map(myrequests)

這是我得到的,因爲很多時候,因爲有請求(明顯)。

Traceback (most recent call last): 
    File "/home/ashk/.virtualenvs/cosignp3/src/gevent/gevent/greenlet.py", line 340, in run 
    result = self._run(*self.args, **self.kwargs) 
    File "/home/ashk/.virtualenvs/cosignp3/lib/python3.4/site-packages/grequests.py", line 71, in send 
    self.url, **merged_kwargs) 
    File "/home/ashk/.virtualenvs/cosignp3/lib/python3.4/site-packages/requests/sessions.py", line 451, in request 
    prep = self.prepare_request(req) 
    File "/home/ashk/.virtualenvs/cosignp3/lib/python3.4/site-packages/requests/sessions.py", line 382, in prepare_request 
    hooks=merge_hooks(request.hooks, self.hooks), 
    File "/home/ashk/.virtualenvs/cosignp3/lib/python3.4/site-packages/requests/models.py", line 307, in prepare 
    self.prepare_body(data, files, json) 
    File "/home/ashk/.virtualenvs/cosignp3/lib/python3.4/site-packages/requests/models.py", line 456, in prepare_body 
    body = self._encode_params(data) 
    File "/home/ashk/.virtualenvs/cosignp3/lib/python3.4/site-packages/requests/models.py", line 89, in _encode_params 
    for k, vs in to_key_val_list(data): 
ValueError: too many values to unpack (expected 2) 
<Greenlet at 0x7f0f7cbf33d8: <bound method AsyncRequest.send of <grequests.AsyncRequest object at 0x7f0f7c90d080>>(stream=False)> failed with ValueError 

編輯:問題解決: -

我得打轉轉,並放在頭就像你的requests模塊中。

我設置標題kwarg參數進行編碼沒有,內容類型:

(grequests.post(POST_URL, data=fgp(a_url, j=True), headers={'Accept-Encoding':'none', 'Content-Type':'application/json'}) for a_url in urls) 

現在我得到正確的輸出:

In [64]: resps[0].json() 
Out[64]: 
{'result': {'isSetByViewer': False, 
    'kind': 'pos#plusones', 
    'metadata': {'type': 'URL', 'globalCounts': {'count': 0.0 }}, 
    'id': 'http://example.com/dfg', 
    'abtk': 'xxxxxxxxxxxxxxx'}, 
'id': 'p'} 

注:輸出編輯一點點隱藏一些數據。

+1

那麼,你的數據進行編碼,以JSON? –

+0

@MartijnPieters哦,是的。謝謝。那就是問題所在。但現在我的問題是,我得到了像'07 \ x04 \ xc3'pO \ x01 \ x00 \ x00''這樣的字節響應體。我如何將Content-Type頭設置爲'application/json'來獲得正確的響應? –

+0

聽起來像服務器正在給你一個不好的迴應;壓縮但沒有標題告訴你。您可以在會話中設置額外的「Accept-Encoding」標頭。 –

回答

4

您錯過了您已經顯示的grequests.post那一行中的一個近似斜線。但是,假設它實際上有在該行的末尾:

myrequests = (grequests.post(POST_URL, data=fgp(a_url) for a_url in all_urls)) 

這意味着你只生成一個post呼叫,但與data多個值。我想你的意思,而不是爲:

myrequests = (grequests.post(POST_URL, data=fgp(a_url)) for a_url in all_urls) 
+0

不錯,很好看! –

+0

@MartijnPieters謝謝 - 祝賀鑽石! –

3

您要發送JSON數據;有requests編碼這件事情(和設置正確的內容類型),通過使用json參數,而不是data

myrequests = (grequests.post(POST_URL, json=fgp(a_url)) for a_url in all_urls) 
+0

沒有。得到這個:'b'\ x1f \ x8b \ x08 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00} x8c1 \ x0e \ xc3 \ x14C \ xafRy \ xce \ xc0 \ x90 \ x89 \ x1bt \ xeb \ x1eep \ xcbW \ x84 \ x04 \ xf9 \ xca \ x87fA \ xdc \ xbdD \ xd9; \ xda \ xcf \ xcf \ rb \ xa6 \ x06 \ xdf \ xf0 \ xd1 \ xf0 \ xb3s \ x13 \ xb2 \ x94 \ xc2m $ <\ XF7 \ X93)\ 86 \的x87 \ xc9 \ XF1 \ x95R1!\ XB0 \ X12〜I \ X08 \ x9a \ X19 \ XF7 \ XB1 \ xd9 \ X92 \ XBE \ X99 \ x062a \ XD1 \ XAB \ X89 \ xb7 \ xf5 \ xa3K \ x15 \ xc3 \ xbf \ xcb \ xbe \ xf6 \ xfe \ x03X \ x97 \ xb8 \ xf1 \ x87 \ x00 \ x00 \ x00'' –

+0

我檢查了響應'requests.headers',我看到這個:'Accept-Encoding':'gzip,deflate'。我沒有要求。知道如何改變它?我將在grequests.post方法調用中嘗試幾件事情。 –

+0

@bad_keypoints:看起來像壓縮數據;是使用'Accept *'標頭的服務器,告訴客戶端發送壓縮的物體? –