从Python发送HTTP POST请求(尝试从PHP转换) [英] Sending a HTTP POST request from Python (trying to convert from PHP)

查看:849
本文介绍了从Python发送HTTP POST请求(尝试从PHP转换)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将此代码段从PHP转换为Python(编程新手)并且我发现这样做有困难:

I am trying to convert this code snippet from PHP to Python (programming newbie) and am finding difficulty in doing so:

我想要转换的PHP如下:

The PHP that I am trying to convert is as follows:

$fp = fsockopen($whmcsurl, 80, $errno, $errstr, 5);
if ($fp) {
$querystring = "";
foreach ($postfields AS $k=>$v) {
$querystring .= "$k=".urlencode($v)."&";
}
$header="POST ".$whmcsurl."modules/servers/licensing/verify.php HTTP/1.0\r\n";
$header.="Host: ".$whmcsurl."\r\n";
$header.="Content-type: application/x-www-form-urlencoded\r\n";
$header.="Content-length: ".@strlen($querystring)."\r\n";
$header.="Connection: close\r\n\r\n";
$header.=$querystring;
$data="";
@stream_set_timeout($fp, 20);
@fputs($fp, $header);
$status = @socket_get_status($fp);
while (!@feof($fp)&&$status) {
$data .= @fgets($fp, 1024);
$status = @socket_get_status($fp);
}
@fclose ($fp);
}

我写的相应Python代码如下:

It corresponding Python code that I wrote is as follows:

fp = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                fp.connect(("my ip", 80))
                if (fp):
                        querystring = ""
                        #print postfields
                        for key in postfields:
                                querystring = querystring+key+"="+urllib.quote(str(postfields[key]))+"&"
                header = "POST "+whmcsurl+"modules/servers/licensing/verify.php HTTP/1.0\r\n"
                header+="Content-type: application/x-www-form-urlencoded\r\n"
                header+="Content-length: "+str(len(querystring))+"\r\n"
                header+="Connection: close\r\n\r\n"
                #header+=querystring
                data=""
                request = urllib2.Request(whmcsurl,querystring,header)
                response = urllib2.urlopen(request)
                data = response.read()

在这里,我面临着以下错误:

Here, I am faced with the following error:

request = urllib2.Request(whmcsurl,querystring,header)
  File "/usr/lib64/python2.6/urllib2.py", line 200, in __init__
    for key, value in headers.items():
AttributeError: 'str' object has no attribute 'items'

所以我猜Python正在期待标题的字典。但PHP将其作为字符串发送。

So I am guessing that Python is expecting a dictionary for the header. But the PHP sends it as a string.

我可以知道如何解决这个问题吗?

May I know how to solve this issue?

提前致谢

推荐答案

你太过复杂了。 Python会为您处理大部分内容。无需自己打开套接字,也不需要构建标头和HTTP开头行。

You are overcomplicating things, by quite some distance. Python takes care of most of this for you. There is no need to open a socket yourself, nor do you need to build headers and the HTTP opening line.

使用 urllib urllib2 模块为您完成工作:

Use the urllib and urllib2 modules to do the work for you:

from urllib import urlencode
from urllib2 import urlopen

params = urlencode(postfields)
url = whmcsurl + 'modules/servers/licensing/verify.php'
response = urlopen(url, params)
data = response.read()

urlopen()接受第二个参数,即要在 POST 请求中发送的数据;该库负责计算主体的长度,并设置适当的标题。最重要的是,它使用另一个库, httplib ,负责处理套接字连接并生成有效的标头和HTTP请求行。

urlopen() takes a second parameter, the data to be sent in a POST request; the library takes care of calculating the length of the body, and sets the appropriate headers. Most of all, under the hood it uses another library, httplib, to take care of the socket connection and producing valid headers and a HTTP request line.

POST主体使用 urllib进行编码.urlencode(),它也会为您正确报价。

The POST body is encoded using urllib.urlencode(), which also takes care of proper quoting for you.

您可能还想查看外部请求,它提供了一个更易于使用的API:

You may also want to look into the external requests library, which provides an easier-to-use API still:

import requests

response = requests.post(whmcsurl + 'modules/servers/licensing/verify.php', params=params)
data = response.content  # or response.text for decoded content, or response.json(), etc.

这篇关于从Python发送HTTP POST请求(尝试从PHP转换)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆