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