¿Cómo leo una respuesta de las solicitudes de Python?

83

Tengo dos scripts de Python. Uno usa la biblioteca Urllib2 y el otro usa la biblioteca Requests .

He encontrado que las solicitudes son más fáciles de implementar, pero no puedo encontrar un equivalente para la read()función de urlib2 . Por ejemplo:

...
response = url.urlopen(req)
print response.geturl()
print response.getcode()
data = response.read()
print data

Una vez que he creado mi URL de publicación, data = response.read()me proporciona el contenido: estoy tratando de conectarme a una instancia de la API de vcloud director y la respuesta muestra los puntos finales a los que tengo acceso. Sin embargo, si uso la biblioteca de solicitudes de la siguiente manera ...

....

def post_call(username, org, password, key, secret):

    endpoint = '<URL ENDPOINT>'
    post_url = endpoint + 'sessions'
    get_url = endpoint + 'org'
    headers = {'Accept':'application/*+xml;version=5.1', \
               'Authorization':'Basic  '+ base64.b64encode(username + "@" + org + ":" + password), \
               'x-id-sec':base64.b64encode(key + ":" + secret)}
    print headers
    post_call = requests.post(post_url, data=None, headers = headers)
    print post_call, "POST call"
    print post_call.text, "TEXT"
    print post_call.content, "CONTENT"
    post_call.status_code, "STATUS CODE"

....

.... the print post_call.texty print post_call.contentno devuelve nada, aunque el código de estado sea igual a 200 en las solicitudes posteriores a la llamada.

¿Por qué mi respuesta de Solicitudes no devuelve ningún texto o contenido?

Oli
fuente
1
¿Conoce el tipo de respuesta que debe obtener de la URL? Json, xml, etc.? ¿Cuál es la respuesta que obtiene de urllib2?
shshank
La solicitud POST puede estar devolviendo una respuesta de redireccionamiento. Compruebe los encabezados de respuesta:post_call.headers
John Keyes

Respuestas:

134

Las solicitudes no tienen un equivalente a las de Urlib2 read().

>>> import requests
>>> response = requests.get("http://www.google.com")
>>> print response.content
'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage"><head>....'
>>> print response.content == response.text
True

Parece que la solicitud POST que está realizando no devuelve contenido. Que suele ser el caso de una solicitud POST. ¿Quizás puso una galleta? El código de estado le dice que el POST se realizó correctamente después de todo.

aychedee
fuente
3
OK gracias. Tal vez me esté confundiendo en alguna parte. urllib2 me muestra contenido, así que necesito entender qué estoy haciendo mal y las diferentes llamadas entre las 2 bibliotecas.
Oli
En un cierto punto final, quiero leer la solicitud pero no puedo usar request.get ("url"). Además, su ejecución lleva un tiempo excesivo. No dar argumentos también arroja un error que dice que se necesita 1 argumento.
Eswar
Verifique el código de respuesta. Probablemente esté obteniendo un tiempo de espera en lugar de una respuesta 2XX. Eso explicaría también por qué lleva tanto tiempo.
aychedee
Solución perfecta. Me salvaste el tiempo. Gracias
Soham Navadiya
1
En Python 3, response.contentes una Bytesinstancia, y lo response.textes str, por lo que ya no compararán iguales directamente (pero la decodificación response.contentcon la codificación correcta debería regresar)response.text
snakecharmerb
26

Si la respuesta está en json, podría hacer algo como (python3):

import json
import requests as reqs

# Make the HTTP request.
response = reqs.get('http://demo.ckan.org/api/3/action/group_list')

# Use the json module to load CKAN's response into a dictionary.
response_dict = json.loads(response.text)

for i in response_dict:
    print("key: ", i, "val: ", response_dict[i])

Para ver todo en la respuesta, puede usar .__dict__:

print(response.__dict__)
Jortega
fuente
1

Si envía, por ejemplo, una imagen a alguna API y desea que la dirección de resultado (respuesta) vuelva, puede hacer:

import requests
url = 'https://uguu.se/api.php?d=upload-tool'
data = {"name": filename}
files = {'file': open(full_file_path, 'rb')}
response = requests.post(url, data=data, files=files)
current_url = response.text
print(response.text)
Martín Nikolov
fuente