Consultando CEP via Web Service com Python

Neste artigo você será introduzido a duas formas de consultar endereços de CEPs via web service utilizando a linguagem de programação Python. O objetivo deste artigo é demonstrar de maneira simples como esse processo pode ser efetuado.

Consultando CEPs via WS com Python, adaptado de
(Ilustração: Freepik)

O CEP — Código de Endereço Postal — criado pela Empresa Brasileira de Correios e Telégrafos, em maio de 1971, tem por objetivo simplificar as fases que envolvem o processo de entrega de correspondência (triagem, encaminhamento e distribuição).

Quando foi divulgado ao público em geral, através do Guia Postal Brasileiro, sua estrutura consistia em 5 dígitos.

Primeiro CEP brasileiro
(Foto: Mrzero / Wikimedia Commons) Domínio Público

O primeiro CEP brasileiro é atribuído a Praça da Sé (CEP 01001-000). E com o aumento populacional, chegamos a este formato que utilizamos hoje, que consiste em 8 dígitos no formato XXXXX-XXX onde cada dígito possui um significado lógico.

ViaCEP Web Sevice

O ViaCEP é um web service gratuito para consultar CEPs. É muito utilizado porque permite receber a resposta em JSON e também em XML, além de outros formatos. Mas o site não deixa explícito onde recolhe essa base de dados; o que implica em atenção, caso utilize esse web service para uso profissional e dependa exclusivamente dele.

Consultando CEPs usando urllib.request

Você pode usar o módulo requests ou urllib.request. Vejamos um exemplo simples, utilizando urllib.request com Python 3:
#!/usr/bin/env python3
import urllib.request

cep = '01001000'
url = 'https://viacep.com.br/ws/%s/json/' % cep
headers = {'User-Agent': 'Autociencia/1.0'}
requisicao = urllib.request.Request(url, headers=headers, method='GET')
cliente = urllib.request.urlopen(requisicao)
conteudo = cliente.read().decode('utf-8')
cliente.close()
print(conteudo)

Explicando o que foi feito acima:
  • A variável headers recebe um dicionário que contém a identificação do programa que está realizando a requisição. No nosso caso, o Autociencia versão 1.0.
  • À classe Request é passado três argumentos: a URL da requisição, o cabeçalho e o método de acesso (ex.: GET, POST, DELETE etc.)
  • A função urlopen() estabelece a conexão com o site, enviando nossa requisição, e retorna uma resposta (um objeto http.client.HTTPResponse, neste caso).

É possível verificar o status da conexão. Se cliente.msg == 'OK' ou cliente.code == 200, então a conexão foi estabelecida com sucesso. O conteúdo da resposta pode ser lido através do método read() e decodificado para o formato UTF-8. Um detalhe importante: não esquecer de fechar a conexão após o uso.

Consultando CEPs usando requests

Um pouco trabalhoso o uso do urllib.request, não? Com o módulo requests as coisas ficam mais simples. Caso você esteja utilizando a versão 3.6 ou superior do Python, pode formatar a URL como é exibido a seguir.

#!/usr/bin/env python3
import requests

cep = '01001000'
url = f'https://viacep.com.br/ws/{cep}/json/'
headers = {'User-Agent': 'Autociencia/1.0'}
resposta = requests.request('GET', url, headers=headers)
conteudo = resposta.content.decode('utf-8')
resposta.close()
print(conteudo)
A função request, do módulo requests, retorna um objeto do tipo Response. Essa resposta tem métodos semelhantes ao HTTPResponse, que podem ser visualizados por meio da função dir(resposta). Note que a posição dos parâmetros muda em relação ao Request, do módulo urllib.request, e são objetos diferentes que são manipulados por esses módulos. A resposta retornada por ambos será a seguinte:
{
  "cep": "01001-000",
  "logradouro": "Praça da Sé",
  "complemento": "lado ímpar",
  "bairro": "Sé",
  "localidade": "São Paulo",
  "uf": "SP",
  "unidade": "",
  "ibge": "3550308",
  "gia": "1004"
}
Importando a biblioteca json você pode converter a string "conteudo" em um dicionário — através da função json.loads(conteudo) — e trabalhar com as informações de forma mais simples. Veja:

# ... Código anterior ...
import json
endereco = json.loads(conteudo)
print('Logradouro: ', endereco['logradouro'])
Saída:
Logradouro:  Praça da Sé

Consulta Completa

Os programas anteriores não são nada interativos. Você pode solicitar ao usuário um CEP e trazer as informações da consulta. Para validar a entrada do usuário, você pode utilizar expressões regulares, já que sabe como é o formato de um CEP, conforme explicado no início do artigo.
#!/usr/bin/env python3
import json
import re
import requests

def consulta(cep):
    cep = cep.replace('-', '')
    url = f'https://viacep.com.br/ws/{cep}/json/'
    headers = {'User-Agent': 'Autociencia/1.0'}
    resposta = requests.request('GET', url, headers=headers)
    conteudo = resposta.content.decode('utf-8')
    resposta.close()
    endereco = json.loads(conteudo)

    return endereco


def cep_valido(cep):
    return True if re.search(r'^(\d{5}-\d{3}|\d{8})$', cep) else False


def main():
    cep = ''

    while cep != 'sair':
        cep = input('CEP: ')

        if cep_valido(cep):
            endereco = consulta(cep)

            if not endereco.get('erro'):
                print('Cidade: %s - %s' % (endereco['localidade'], endereco['uf']) )
                print('Bairro:', endereco['bairro'])
                print('Logradouro:', endereco['logradouro'])
                print('CEP:', endereco['cep'])
                print('\n\n')


if __name__ == '__main__':
    main()


Inserindo o CEP 01037-010, do Theatro Municipal de São Paulo, a saída será a seguinte:
Cidade: São Paulo - SP
Bairro: República
Logradouro: Praça Ramos de Azevedo
CEP: 01037-010

O que você aprendeu

Você aprendeu duas formas distintas de consultar CEPs, com o uso do web service gratuito viaCEP, utilizando tanto o módulos requests quanto urllib.request. Aprendeu, também, como trabalhar com essas informações e validar o formato de um CEP com expressão regular (regex). Validações mais complexas ficam a critério do leitor.

Referência Bibliográfica
CORREIOS. O que é CEP. Disponível em <https://www.correios.com.br/precisa-de-ajuda/o-que-e-cep-e-por-que-usa-lo>. Acesso em 1 jul. 2018.

VIACEP. Webservice CEP e IBGE Gratuito. Disponível em <https://viacep.com.br/>. Acesso em 1 jul. 2018.

PYTHON DOCUMENTATION. Python 3.7.0 documentation. Disponível em <https://docs.python.org/3/index.html>. Acesso em 1 jul. 2018.



Para citar esse artigo:

Comentários

  1. Clederson,

    Mas e a limitação máxima de Requests que existe neste webservice ? (Você não citou.)

    ResponderExcluir
    Respostas
    1. Olá Luciano, tudo bem? Obrigado pela pergunta. Inclusive ela é de extrema importância. A única informação visivelmente fornecida pelo site é um aviso que "ao constatar o uso de scripts de acesso massivo, seu IP será automaticamente bloqueado por tempo indeterminado".

      Excluir
  2. boa noite, professor !
    uma forma de passar disso seria usando listas de proxys correto ?

    ResponderExcluir
    Respostas
    1. Oi, tudo bem? Muito obrigado pelo comentário, mas eu não entendi muito bem. Poderia reformulá-lo?

      Excluir
  3. Como eu faria com esse código para ele salvar as consultas numa planilha excel? Ou em txt?

    ResponderExcluir
    Respostas
    1. Oi André, questionamento interessante! Existe nativamente uma biblioteca para ler e gravar arquivos CSV. Podemos criar uma postagem ensinando sobre.

      Excluir
  4. Teria como consultar uma lista de CEPs? Tentei reproduzir e não consegui.

    ResponderExcluir
    Respostas
    1. Sim. Precisa modificar o código para iterar sobre a lista, em vez de solicitar unitariamente ao usuário.

      Excluir

Postar um comentário