php - cliente - python http request
Enviar una solicitud HTTP POST desde Python(intentando convertir desde PHP) (2)
Estoy intentando convertir este fragmento de código de PHP a Python (novato en programación) y tengo dificultades para hacerlo:
El PHP que intento convertir es el siguiente:
$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);
}
El código Python correspondiente que escribí es el siguiente:
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()
Aquí, me encuentro con el siguiente 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''
Así que supongo que Python espera un diccionario para el encabezado. Pero el PHP lo envía como una cadena.
¿Puedo saber cómo resolver este problema?
Gracias por adelantado
Estás sobrecomplicando cosas, por bastante distancia. Python se encarga de la mayor parte de esto por ti. No es necesario abrir un socket usted mismo, ni necesita crear encabezados y la línea de apertura de HTTP.
Use los módulos urllib
y urllib2
para hacer el trabajo por usted:
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()
toma un segundo parámetro, los datos que se enviarán en una solicitud POST
; la biblioteca se encarga de calcular la longitud del cuerpo y establece los encabezados apropiados. Sobre todo, bajo el capó usa otra biblioteca, httplib
, para cuidar la conexión del socket y producir encabezados válidos y una línea de solicitud HTTP.
El cuerpo POST está codificado usando urllib.urlencode()
, que también se encarga de las urllib.urlencode()
correctas para usted.
También puede consultar la biblioteca de requests
externas , que proporciona una API aún más fácil de usar:
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.
tus encabezados deberían verse así
headers = { "Content-type" : "application/x-www-form-urlencoded" };