2016-10-28 62 views
3

做POST時,我有一個簡單的代碼來發布數據到遠程服務器:怪異的行爲由PyCurl

def main(): 
    headers = {} 
    headers['Content-Type'] = 'application/json' 

    target_url = r'the_url' 

    data = {"bodyTextPlain": "O estimulante concorrente dos azulzinhos\r\nConhe\u00e7a a nova tend\u00eancia em estimulante masculino e feminino\r\n\r\nEste estimulante ficou conhecido por seus efeitos similares as p\u00edlulas\r\nazuis,\r\ndestacando-se por n\u00e3o possuir contraindica\u00e7\u00e3o ou efeito colateral.\r\n\r\nSucesso de vendas e principal concorrente natural dos azulzinhos,\r\nsua f\u00f3rmula \u00e9 totalmente natural e livre de qu\u00edmicos.\r\n\r\nPossuindo registro no Minist\u00e9rio da Sa\u00fade (ANVISA) e atestado de\r\nautenticidade.\r\n\r\nSaiba mais http://www5.somenteagora.com.br/maca\r\nAdquirindo 3 frascos voc\u00ea ganha +1 de brinde. Somente esta semana!\r\n\r\n\r\n\r\n\r\nPare de receber\r\nhttp://www5.somenteagora.com.br/app/sair/3056321/1\r\n\r\n"} 

    buffer = StringIO() 
    curl = pycurl.Curl() 
    curl.setopt(curl.URL, target_url) 
    curl.setopt(pycurl.HTTPHEADER, ['%s: %s' % (k, v) for k, v in headers.items()]) 

    # this line causes the problem 
    curl.setopt(curl.POSTFIELDS, json.dumps(data)) 

    curl.setopt(pycurl.SSL_VERIFYPEER, False) 
    curl.setopt(pycurl.SSL_VERIFYHOST, False) 
    curl.setopt(pycurl.WRITEFUNCTION, buffer.write) 
    curl.perform() 

    response = buffer.getvalue() 

    print curl.getinfo(pycurl.HTTP_CODE) 
    print response 

遠程服務器有錯誤解析JSON字符串我送:

500 { "status" : "Error", "message" : "Unexpected IOException (of type java.io.CharConversionException): Invalid UTF-32 character 0x3081a901(above 10ffff) at char #7, byte #31)" }

然而如果我從json.dumps後的數據保存到一個變量,然後做後期:

#curl.setopt(curl.POSTFIELDS, json.dumps(data)) 

    data_s = json.dumps(data) 
    curl.setopt(curl.POSTFIELDS, data_s) 

那麼有沒有錯誤:

200

這兩種情況有什麼區別嗎?

謝謝。

+0

你使用pycurl而不是請求的任何原因? – maxymoo

+0

沒有特別的要求。只是因爲[性能](http://example.com)看起來不錯,所以我嘗試使用它,並得到這個問題。 – pppk520

+0

@ pppk520你可能會對這個問題感興趣:https://stackoverflow.com/questions/15461995/python-requests-vs-pycurl-performance – augurar

回答

3

這是一個奇妙的微妙問題。答案就在此警告在documentation for Curl.setopt_string(option, value)

Warning: No checking is performed that option does, in fact, expect a string value. Using this method incorrectly can crash the program and may lead to a security vulnerability. Furthermore, it is on the application to ensure that the value object does not get garbage collected while libcurl is using it. libcurl copies most string options but not all; one option whose value is not copied by libcurl is CURLOPT_POSTFIELDS .

當你使用一個變量,這將創建這個字符串的引用,以便它不會被垃圾收集。在內聯表達式時,該字符串在libcurl完成使用之前解除分配,結果不可預知。

爲了避免擔心物體的壽命,可以使用CURLOPT_COPYPOSTFIELDS來代替。

+0

完美!謝謝@augurar :-) – pppk520