Pular para o conteúdo

Requests

Introdução

Esse módulo permite integrar os programas Python com os serviços Web, ou seja, Requests é um módulo HTTP para Python. São exemplos de métodos do Requests:

  • get() – faz requisição de uma página ao servidor;
  • post() – envia um recurso específico para o servidor;
  • put() – substitui vários recursos no servidor;
  • delete() – deleta um recurso no servidor.

Exemplos

  • Exemplo: tenta acessar um site mas recebe mensagem de erro na linha de comando, pois o site não existe. Note que a tentativa de conexão é feita usando try … except.
import requests
try:
   r = requests.get('https://www.python.org')
   print("Codigo de retorno = " + str(r.status_code))
except Exception as erro:
   print('Erro: %s' %(erro))
print("*** Fim\n")

A resposta é

Erro: HTTPSConnectionPool(host='www.python.org', port=443): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7fcaabea1b80>: Failed to establish a new connection: [Errno -2] Name or service not known'))
*** Fim
  • Exemplo: o script verifica se ocorreu um erro com o protocolo HTTP quando usa o método get().
import requests
from requests.exceptions import HTTPError
try:
   r = requests.get('https://www.python.org')
except HTTPError as erro:
   print('Erro HTTP: %s' %erro)
except Exception as erro:
   print('Outro tipo de erro: %s' %erro)
else:
   print('Página encontrada!')

A resposta mostra que o erro não é do protocolo HTTP, mas de conexão.

Outro tipo de erro: HTTPSConnectionPool(host='www.python.org', port=443): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7fce64326b80>: Failed to establish a new connection: [Errno -2] Name or service not known'))

Para mais detalhes sobre os erros que podem ocorrer, veja https://docs.python-requests.org/en/master/_modules/requests/exceptions/.

  • Exemplo: o script usa o método get() para obter a página e depois mostra o conteúdo nos formatos byte e Unicode.
import requests
resp = requests.get('https://www.python.org')
print("*** Conteúdo da página em bytes ***")
print(resp.content)
print("\n*** Conteúdo da página codificado ***")
print(resp.text)
  • Exemplo: os cabeçalhos HTTP podem fornecer informações adicionais (entre servidor e navegador) no formato de dicionário. O exemplo abaixo verifica as informações do HTTP da página oficial do Python.
import requests
resp = requests.get('https://www.python.org')
print("*** Cabeçalhos HTTP ***")
print(resp.headers)

Abaixo a resposta do servidor.

*** Cabeçalhos HTTP ***
{'Connection': 'keep-alive', 'Content-Length': '49934', 'Server': 'nginx', 'Content-Type': 'text/html; charset=utf-8', 'X-Frame-Options': 'DENY', 'Via': '1.1 vegur, 1.1 varnish, 1.1 varnish', 'Accept-Ranges': 'bytes', 'Date': 'Tue, 15 Feb 2022 17:55:15 GMT', 'Age': '795', 'X-Served-By': 'cache-iad-kiad7000075-IAD, cache-gig2250021-GIG', 'X-Cache': 'HIT, HIT', 'X-Cache-Hits': '1, 2', 'X-Timer': 'S1644947716.864574,VS0,VE0', 'Vary': 'Cookie', 'Strict-Transport-Security': 'max-age=63072000; includeSubDomains'}
  • Exemplo: o programa abaixo verifica três informações fornecidas nos cabeçalhos HTTP (horário do servidor, nome do servidor e o tipo do conteúdo na comunicação).
import requests
resp = requests.get('https://www.python.org')
print("*** Cabeçalhos HTTP ***")
print("Data: " + resp.headers['Date'])
print("Servidor: " + resp.headers['Server'])
print("Conteúdo: " + resp.headers['Content-Type'])

A resposta obtida pelo programa é

*** Cabeçalhos HTTP ***
Data: Tue, 15 Feb 2022 18:46:46 GMT
Servidor: nginx
Conteúdo: text/html; charset=utf-8
  • Exemplo: o script captura o logo da página oficial do Python e o armazena no diretório de trabalho com o nome “logo_python.png”. O comando ‘with open’ fecha o arquivo png automaticamente quando o bloco termina de ser executado e o parâmetro ‘wb’ define o modo binário para a escrita do arquivo.
import requests
arq = requests.get('https://www.python.org/static/img/python-logo.png')
with open(r'logo_python.png','wb') as imagem:
   imagem.write(arq.content)
  • Exemplo: o programa cria uma cópia da página HTML inicial do site oficial Python e a armazena no diretório de trabalho.
import requests
pagina = requests.get('https://www.python.org')
print("Página: " + pagina.url)
print("Codificação: " + pagina.encoding)
arq = open("copia.html", "w")
arq.write(pagina.text)
arq.close()
print('Arquivo ' + arq.name + ' gravado')

Na linha de comandos aparecem as seguintes mensagens:

Página: https://www.python.org/
Codificação: utf-8
Arquivo copia.html gravado
  • Exemplo: quando o parâmetro “allow_redirects” é True, o pedido pode ser redirecionado para o endereço correto. O programa abaixo usa o protocolo HTTP para acessar o GitHub, mas o correto é o protocolo HTTPS.
import requests
resp = requests.get('http://github.com/', allow_redirects=True)
print("Codigo: " + str(resp.status_code))
print("URL: " + str(resp.url))
print("History: " + str(resp.history))

A resposta mostra que o pedido foi executado com sucesso (código 200), mas houve um único redirecionamento do pedido (código 301).

Codigo: 200
URL: https://github.com/
History: [<Response [301]>]

Se o parâmetro “allow_redirects” fosse False, o programa teria dado a resposta abaixo. O código 301 indica que o endereço foi modificado.

Codigo: 301
URL: http://github.com/
History: []

Os códigos de retorno do método get() variam de 1XX a 5XX. Abaixo um resumo dos grupos de código.

1XX - Informação
2XX - Sucesso
3XX - Redirecionar
4XX - Erro de cliente
5XX - Erro de servidor

Veja mais detalhes em https://github.com/psf/requests/blob/main/requests/status_codes.py.

  • Exemplo: é possível verificar os próximos momentos em que a Estação Espacial Internacional (ISS – International Space Station) passa em cima de um determinado local da Terra. O programa abaixo usa as coordenadas da UNIRIO para testar a API disponibilizada.
import requests
unirio = {'lat':'-22.9549', 'lon':'-43.1701'}
response = requests.get('http://api.open-notify.org/iss-
pass.json', params=unirio)
print(response.text)

Uma possível resposta é mostrada baixo.

{
  "message": "success", 
  "request": {
    "altitude": 100, 
    "datetime": 1644954991, 
    "latitude": -22.9549, 
    "longitude": -43.1701, 
    "passes": 5
  }, 
  "response": [
    {
      "duration": 649, 
      "risetime": 1644957493
    }, 
    {
      "duration": 506, 
      "risetime": 1644963382
    }, 
    {
      "duration": 541, 
      "risetime": 1644987107
    }, 
    {
      "duration": 646, 
      "risetime": 1644992867
    }, 
    {
      "duration": 615, 
      "risetime": 1645041024
    }
  ]
}

Note que os horários estão no formato timestamp. Para converter os horários em formato humano, podemos usar Python.

from datetime import datetime
timestamp = [1644957493, 1644963382, 1644987107, 1644992867, 1645041024]
for i in timestamp:
   data = datetime.fromtimestamp(i)
   print(data)

Os próximos horários em que a ISS passa sobre a UNIRIO (considerando o horário de execução do programa) são:

2022-02-15 17:38:13
2022-02-15 19:16:22
2022-02-16 01:51:47
2022-02-16 03:27:47
2022-02-16 16:50:24
  • Exemplo: é possível verificar o certificado HTTPS de um site, passando o parâmetro “verify = True” com a solicitação. Use False em vez de True para não fazer a verificação. Por padrão, temos “verify = True”.
import requests
resp = requests.get('https://www.python.org/', verify=True)
print(resp)
  • Exemplo: o método put() solicita que um determinado recurso seja armazenado no URI (Identificador de Recursos Universal) fornecido. O programa usa o site http://httpbin.org/ que permite testar pedidos e respostas do protocolo HTTP. Neste caso, dados JSON (parâmero json) são passados para o servidor que retorna esses dados na resposta.
import requests
frases = {
  "saudação":"Alô, mundo!",
  "linguagem": "Python"
}
resp = requests.put("https://httpbin.org/put", json=frases)
print(resp.json())
print(resp.json()['json']['saudação'])
print(resp.json()['json']['linguagem'])

A resposta fornecida pelo servidor é

{'args': {}, 'data': '{"sauda\\u00e7\\u00e3o": "Al\\u00f4, mundo!", "linguagem": "Python"}', 'files': {}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '65', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-620c19de-2d56b9636e84635302c79727'}, 'json': {'linguagem': 'Python', 'saudação': 'Alô, mundo!'}, 'origin': '189.60.5.132', 'url': 'https://httpbin.org/put'}
Alô, mundo!
Python

É também possível passar dados diretamente no método put() com o parâmetro “data”.

resp = requests.put("https://httpbin.org/put", data = {"saudação":"Alô, mundo!","linguagem": "Python"})

Para obter o valor da chave “saudação”, basta digitar

print(resp.json()['form']['saudação'])

No método put(), se o URI se referir a um recurso já existente, ele será modificado. Se o URI não apontar para um recurso existente, o servidor pode criar o recurso. É um método idempotente (múltiplas requisições ao mesmo recurso tem o mesmo resultado).

  • Exemplo: o método post() funciona de forma similar ao método put(). Normalmente, o put() é usado quando se quer enviar uma informação e não fazer mais nada além de armazená-la de alguma forma. O método post() é mais geral e pressupõe que a informação é apenas parte do processo. Além disso, post() não é idempotente, se uma solicitação for repetida N vezes, N recursos com N URIs diferentes serão criados no servidor.
import requests
frases = {
  "saudação":"Alô, mundo!",
  "linguagem": "Python"
}
resp = requests.post("https://httpbin.org/post", json=frases)
print(resp.json())
print(resp.json()['json']['saudação'])
print(resp.json()['json']['linguagem'])

Abaixo a resposta com o método post().

{'args': {}, 'data': '{"sauda\\u00e7\\u00e3o": "Al\\u00f4, mundo!", "linguagem": "Python"}', 'files': {}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '65', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-620c3e28-5f56829e2210a4ae3a6ab1c8'}, 'json': {'linguagem': 'Python', 'saudação': 'Alô, mundo!'}, 'origin': '189.60.5.132', 'url': 'https://httpbin.org/post'}
Alô, mundo!
Python