【问题标题】:Weird behavior when doing POST by PyCurl通过 PyCurl 进行 POST 时的奇怪行为
【发布时间】:2017-03-10 21:57:40
【问题描述】:

我有一个将数据发布到远程服务器的简单代码:

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 { “状态”:“错误”, “消息”:“意外的 IOException(java.io.CharConversionException 类型):字符 #7 字节 #31 处的 UTF-32 字符 0x3081a901(10ffff 以上)无效)” }

但是,如果我将 json.dumps 中的发布数据保存到变量中,然后进行发布:

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

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

那么就没有错误了:

200

这两种情况有什么区别吗?

谢谢。

【问题讨论】:

  • 您使用 pycurl 而不是请求的任何原因?
  • 无特殊原因。只是因为performance看起来不错,所以我尝试使用它,并遇到了这个问题。
  • @pppk520 您可能对这个问题感兴趣:stackoverflow.com/questions/15461995/…
  • 糟糕,我确实想将此超链接附加到性能一词。好像我从提示复制后忘记更改链接哈哈。

标签: python json pycurl


【解决方案1】:

这是一个非常微妙的问题。答案就在documentation for Curl.setopt_string(option, value)中的这个警告中:

警告:不检查 option 实际上是否需要一个字符串值。错误地使用此方法可能会使程序崩溃,并可能导致安全漏洞。此外,在应用程序上确保 value 对象在 libcurl 使用它时不会被垃圾收集。 libcurl 复制大多数字符串选项,但不是全部; libcurl 不复制其值的一个选项是CURLOPT_POSTFIELDS

当您使用变量时,这会创建对字符串的引用,因此不会被垃圾收集。当你内联表达式时,字符串在 libcurl 完成使用它之前被释放,结果不可预知。

为避免担心对象的生命周期,您可以改用CURLOPT_COPYPOSTFIELDS

【讨论】:

  • 完美!谢谢@augurar :-)
猜你喜欢
  • 1970-01-01
  • 2021-02-11
  • 2015-03-06
  • 1970-01-01
  • 2011-01-09
  • 2012-06-05
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
相关资源
最近更新 更多