2016-10-28 8 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