Buscar

Parser HTML

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 24 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 24 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 24 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

WEB SCRAPING
Introdução
Pré-requisitos
Case para uso de um parser HTML
Começando a brincar - Coleta de dados do IBGE
O que é um parser?
Iniciando a coleta
Primeiros passos - Navegando nos links
Entendendo o que foi feito e usado
Urllib2
BeautifulSoap
Manipulando pagina HTML e pegando o resultado
Gravando dados em um arquivo CSV
Coleta e parser sistema Itaú Unibanco
Preparando para a coleta
Introdução
De acordo com uma necessidade que eu tive, eu precisei estudar métodos para realizar uma consulta em uma pagina HTML e retornar valores contidos nela de forma automática para inserção em um banco de dados, preencher formulários online e até mesmo realizar trabalhos de web spider coletando conteúdos relacionados nas páginas. Nessas pesquisas e estudos eu acabei achando métodos para as linguagens JAVA, PERL, PYTHON e PHP. Com elas eu consegui desenvolver e trabalhar as paginas HTML, eu vou mostrar aqui códigos de exemplos em Python para coletar conteúdos. Todos os exemplos descritos nesse paper são cases reais de uso, todos foram usados em alguma parte dos meus projetos.[0: Web crawler, em português rastreador web, é um programa de computador que navega pela World Wide Web de uma forma metódica e automatizada. Outros termos para Web crawlers são indexadores automáticos, bots, web spiders, Web robot, ou Web scutter.(Wikipédia)]
Pré-requisitos
Acredito que você que esteja lendo, já tenha um conhecimento de lógica de programação e já programa em alguma linguagem, caso contrário esse conteúdo pode ser um pouco confuso para você. 
Todo o conteúdo foi feito utilizando o sistema operacional Debian 7, então utilizarei apenas o Linux e não o Windows.
É preciso também um conhecimento básico em Python.
Case para uso de um parser HTML
Como disse, vou basear esse paper em cases reais de uso, assim acho que o entendimento fica mais simplificado. Digamos que você precise saber alguns dados dos municípios do Brasil para elaborar estratégias para sua empresa, tais como:
População estimada 2014 
População 2010
Área da unidade territorial (km²)
Densidade demográfica (hab/km²)
Código do Município
Gentílico
Prefeito
O que vamos fazer é criar um script em Python para acessar a pagina do IBGE onde contém essas informações e armazenar em um arquivo CSV.
Então a missão é escrever um script no qual vai acessar a pagina do IBGE (http://cidades.ibge.gov.br/xtras/home.php) e armazenar as informações de cada município para uma eventual estratégia.
Esse é apenas um exemplo de uso que vou abordar aqui para vocês, mas temos inúmeras utilidades para se usar um parser ou scrapper como preferirem chamar.
Começando a brincar - Coleta de dados do IBGE
Antes de começarmos a fazer o código, vamos entender como funciona e o que vamos usar.
O que é um parser?
“Em ciência da computação e linguística, análise sintática (também conhecida pelo termo em inglês parsing) é o processo de analisar uma sequência de entrada (lida de um arquivo de computador ou do teclado, por exemplo) para determinar sua estrutura gramatical segundo uma determinada gramática formal. Essa análise faz parte de um compilador, junto com a análise léxica e análise semântica.
A análise sintática transforma um texto na entrada em uma estrutura de dados, em geral uma árvore, o que é conveniente para processamento posterior e captura a hierarquia implícita desta entrada.” (Wikipédia)
Em resumo ao descritivo acima, parsear uma pagina HTML nada mais é que você analisar os código da pagina e transcrever o conteúdo dela de uma forma que vire uma informação para você.
Iniciando a coleta
Primeiros passos - Navegando nos links
Antes de mais nada, precisamos saber o que vamos coletar, então, como disse acima, vamos coletar dados dos municípios do Brasil, tais como:
População estimada 2014 
População 2010
Área da unidade territorial (km²)
Densidade demográfica (hab/km²)
Código do Município
Gentílico
Prefeito
Certo, agora temos que descobrir onde essas informações são encontradas.
A estrutura do site para se chegar a essas informações são:
http://cidades.ibge.gov.br/xtras/home.php
http://cidades.ibge.gov.br/xtras/uf.php?lang=&coduf=<NUM_ESTADO>&search=<ESTADO>
http://cidades.ibge.gov.br/xtras/perfil.php?lang=&codmun=<COD_MUNICIPIO>&search=<ESTADO>|<MUNICIPIO>
Certo, sabendo que temos 3 tipos de links para obter o conteúdo, já temos uma base para pensar em como desenvolver o código. 
Pensando nisso eu comecei com uma estrutura básica do código, nela vamos usar o BeautifulSoup e urllibs2.[1: http://www.crummy.com/software/BeautifulSoup/][2: https://docs.python.org/2/library/urllib2.html]
#!/usr/bin/python
import urllib2
from bs4 import BeautifulSoup
 
# Abre a pagina principal do IBGE onde contem os links para os estados.
html = urllib2.urlopen('http://cidades.ibge.gov.br/xtras/home.php').read()
 
# Pega o conteudo da pagina em HTML e joga para o BeautifulSoup mapear as tags
soup = BeautifulSoup(html)
 
# Apenas um contador para verificar se o loop esta correto e pegando os 27 estados do pais
a = 1
 
# For, pegando os links. Ele busca no codigo HTML todas as tags que começam com "<a"
# exemplo: <a href="../xtras/uf.php?lang=&coduf=12&search=acre" title="Acre">AC</a></li>
# Ele vai buscar todo o conteudo de tags de links
for link in soup.find_all('a'):
 # Aqui podemos ver também que ele faz um get para pegar o conteúdo da href
 # ou seja, o que estiver entre aspas em href ele vai trazer como texto.
 # no caso do exemplo acima, ele vai trazer ../xtras/uf.php?lang=&coduf=12&search=acre
 pagina = link.get('href')
 
 # Eu coloquei esse IF para distinguir as URLs, assim ele me traz apenas as URLs
 # que contem uf.php que é o que nos interessa para pegar os estados.
 if "uf.php" in pagina:
 
 # Aqui foi feito um "pulo do gato" para conseguir extrair o conteudo e fazer uma juncao
 # com a pagina principal para acessar o link, note que ele traz "../xtras/uf.php?lang=&coduf=12&search=acre"
 # o que eu fiz foi fazer um split para separar em um vetor tudo que vem antes de "xtras/" e depois dele.
 # Assim pegamos apenas o final e concatenamos com o link certo da pagina.
 pagina = pagina.split('xtras/')[1]
 
 # Na variavel abaixo é feita a concatenacao.
 url = "http://cidades.ibge.gov.br/xtras/"+pagina
 
 # Aqui nos abrimos uma nova pagina com o conteudo coletado, assim fica automatico
 # a navegacao nos links de estados.
 html = urllib2.urlopen(url).read()
 print a
 a+=1
Source: https://gist.github.com/danilovazb/03fae9a7c4900fa245a3
No source acima, podemos ver que ele faz a navegação nos links a partir do principal que é http://cidades.ibge.gov.br/xtras/home.php
Agora vamos começar a trabalhar isso, o código acima ele apenas mostra no output a contagem dos estados, vamos pega o conteúdo da pagina e começar a tratar agora, ainda temos que acessar os links dos municípios de cada estado.
Acesse uma pagina de algum estado e usando o Google Chrome(Ou qualquer outro de sua preferencia) e clique com o botão direito do mouse a fim de inspecionar elemento, procure pelos municípios e veja o conteúdo do href que eles lhe oferecem, assim vamos conseguir montar a próxima parte do código. Veja na imagem abaixo:
Como podemos ver, eu selecionei o link de Acrelandia(O Acre existe?!?!) e obtemos parte do link que vai nos ajudar a montar a proxima parte do código.
href="perfil.php?lang=&codmun=120001&search=acre|acrelandia"
Depois que achamos algo que nos leve ao link unico, montamos o código, veja abaixo:
#!/usr/bin/python
 
import urllib2
from bs4 import BeautifulSoup
# Abre a pagina principal do IBGE onde contem os links para os estados.
html = urllib2.urlopen('http://cidades.ibge.gov.br/xtras/home.php').read()# Pega o conteudo da pagina em HTML e joga para o BeautifulSoup mapear as tags
soup = BeautifulSoup(html)
# Apenas um contador para verificar se o loop esta correto e pegando os 27 estados do pais
a = 1
# For, pegando os links. Ele busca no codigo HTML todas as tags que começam com "<a"
# exemplo: <a href="../xtras/uf.php?lang=&coduf=12&search=acre" title="Acre">AC</a></li>
# Ele vai buscar todo o conteudo de tags de links
for link in soup.find_all('a'):
 # Aqui podemos ver também que ele faz um get para pegar o conteúdo da href
 # ou seja, o que estiver entre aspas em href ele vai trazer como texto.
 # no caso do exemplo acima, ele vai trazer ../xtras/uf.php?lang=&coduf=12&search=acre
 pagina = link.get('href')
 # Eu coloquei esse IF para distinguir as URLs, assim ele me traz apenas as URLs
 # que contem uf.php que é o que nos interessa para pegar os estados.
 if "uf.php" in pagina:
 # Aqui foi feito um "pulo do gato" para conseguir extrair o conteudo e fazer uma juncao
 # com a pagina principal para acessar o link, note que ele traz "../xtras/uf.php?lang=&coduf=12&search=acre"
 # o que eu fiz foi fazer um split para separar em um vetor tudo que vem antes de "xtras/" e depois dele.
 # Assim pegamos apenas o final e concatenamos com o link certo da pagina.
 pagina = pagina.split('xtras/')[1]
 
 # Na variavel abaixo é feita a concatenacao.
 url = "http://cidades.ibge.gov.br/xtras/"+pagina
 # Aqui nos abrimos uma nova pagina com o conteudo coletado, assim fica automatico
 # a navegacao nos links de estados.
 html = urllib2.urlopen(url).read()
 
 # Agora, fiz basicamente o que está lá em cima no código.
 # eu estou filtrando novamente os links, mas agora das paginas dos estados
 soup = BeautifulSoup(html)
 for link in soup.find_all('a'):
 pagina = link.get('href')
 
 # Um novo IF, agora ele verifica se perfil.php contem no link da pagina, exatamente como o acima.
 # Lembra que visualizamos na pagina dos estados com o "Inspecionar Elemento" para ver
 # algo que pudesse fazer a distinção de links, então, achei o "perfil.php"
 if "perfil.php" in pagina:
 print a
 a+=1
Source: https://gist.github.com/danilovazb/a3736881b82bacee87a7
Entendendo o que foi feito e usado
Bom, até agora apenas navegamos nos links, vou aprofundar mais em detalhes já que a intenção é entender o que estamos fazendo.
O que usamos até agora foram duas libs, como havia dito acima, usamos o urllib2 e o BeautifulSoup.
Urllib2
O urllib2 é um módulo do Python que define funções e classes(Objetos) que manipulam URL(s), seja ela uma URL simples baseado no protocolo HTTP, autenticação Digest, envio de dados GET e POST download de arquivos, cookies, sessão etc. (Fonte: http://www.nacaolivre.com.br/python/python-usando-urllib2/) 
Achei uma boa explicação a da galera do nacaolivre.com.br e nem precisa falar muito, mas o que basicamente o urllib2 faz é uma manipulação de URL, um bom exemplo de uso dele você pode encontrar no link da matéria acima, no github do Fernando Massanori (https://gist.github.com/fmasanori) ou na pagina de documentação (http://kodumaro.blogspot.com.br/2007/04/beautiful-soup-e-html-scrapping-em.html). 
BeautifulSoap
O Beautiful Soup é um parser de HTML/XML para Python que pode transformar até mesmo marcação inválida em uma árvore analítica. Ele provê um modo idiomático de navegar, procurar e modificar a árvore de elementos. (Fonte: http://kodumaro.blogspot.com.br/2007/04/beautiful-soup-e-html-scrapping-em.html)
Como já disse acima, o parser nada mais é que você transformar marcações/tags em um forma legível, o BeautifulSoap pega o conteúdo HTML e faz uma árvore analítica a fim de separar, organizar e disponibilizar o conteúdo de forma que possamos manipular. 
Basicamente o que fizemos foi, usar o urllib2 para acessar a pagina principal do IBGE, em seguida manipulamos o resultado HTML com BeautifulSoap a fim de encontrar os links para as paginas de municípios. No nosso código foi feito meio que manual o processo de encontrar os links, afinal, o interesse real é pegar os dados de todos os municípios do Brasil, mas o interessante é que podemos usar desses truques acima para brincar com os links das paginas e fazer igual o Google, ir de link em link, acessando e visualizando as paginas. É dessa forma que o robô do Google faz para maperar as paginas. Claro que com um processamento terrivelmente maior(rsrsrs).
Manipulando pagina HTML e pegando o resultado
Depois que entendemos como navegar nos links, vamos agora partir para o get dos dados que queremos, vamos continuar com o código feito acima, apenas vamos mudar o final dele, deixando ele de um modo que pegue o resultado das tags que queremos.
Antes de escrever nosso código, vamos analisar o modelo da pagina que vamos fazer o get das informações que queremos.
Como exemplo, eu vou acessar a pagina de Acrelandia, assim podemos ter uma ideia do que pegar.
http://cidades.ibge.gov.br/xtras/perfil.php?lang=&codmun=120001&search=acre|acrelandia
A imagem acima, podemos ver na análise de elementos que os dados que queremos está abaixo das tags <table>, <tbody>, <tr> e dentro da <td>
Certo, primeira parte já temos. Vamos montar um esboço de código para trazer esse resultado. Sabemos as tags que eles se encontram, agora é só selecionar ele com o código, não se preocupe com o código, vou explicar ele detalhado mais pra frente.
#!/usr/bin/python
import urllib2
from bs4 import BeautifulSoup
 
# Abre a pagina principal do IBGE onde contem os links para os estados.
html = urllib2.urlopen('http://cidades.ibge.gov.br/xtras/home.php').read()
 
# Pega o conteudo da pagina em HTML e joga para o BeautifulSoup mapear as tags
soup = BeautifulSoup(html)
 
# Apenas um contador para verificar se o loop esta correto e pegando os 27 estados do pais
a = 1
 
# For, pegando os links. Ele busca no codigo HTML todas as tags que comecam com "<a"
# exemplo: <a href="../xtras/uf.php?lang=&coduf=12&search=acre" title="Acre">AC</a></li>
# Ele vai buscar todo o conteudo de tags de links
for link in soup.find_all('a'):
 # Aqui podemos ver tambem que ele faz um get para pegar o conteudo da href
 # ou seja, o que estiver entre aspas em href ele vai trazer como texto.
 # no caso do exemplo acima, ele vai trazer ../xtras/uf.php?lang=&coduf=12&search=acre
 pagina = link.get('href')
 
 # Eu coloquei esse IF para distinguir as URLs, assim ele me traz apenas as URLs
 # que contem uf.php que eh o que nos interessa para pegar os estados.
 if "uf.php" in pagina:
 
 # Aqui foi feito um "pulo do gato" para conseguir extrair o conteudo e fazer uma juncao
 # com a pagina principal para acessar o link, note que ele traz "../xtras/uf.php?lang=&coduf=12&search=acre"
 # o que eu fiz foi fazer um split para separar em um vetor tudo que vem antes de "xtras/" e depois dele.
 # Assim pegamos apenas o final e concatenamos com o link certo da pagina.
 paginaUF = pagina.split('xtras/')[1]
 
 # Na variavel abaixo e feita a concatenacao.
 urlUF = "http://cidades.ibge.gov.br/xtras/"+paginaUF
 
 # Aqui nos abrimos uma nova pagina com o conteudo coletado, assim fica automatico
 # a navegacao nos links de estados.
 htmlUF = urllib2.urlopen(urlUF).read()
 
 # Agora, fiz basicamente o que esta la em cima no codigo.
 # eu estou filtrandonovamente os links, mas agora das paginas dos estados
 soupUF = BeautifulSoup(htmlUF)
 print urlUF
 for link in soupUF.find_all('a'):
 paginaMun = link.get('href')
 
 # Adicionei o TRY para tratar os erros que podem dar, assim ele nao para o programa em tempo de execucao
 try:
 # Um novo IF, agora ele verifica se perfil.php contem no link da pagina, exatamente como o acima.
 # Lembra que visualizamos na pagina dos estados com o "Inspecionar Elemento" para ver
 # algo que pudesse fazer a distincao de links, entao, achei o "perfil.php"
 if "perfil.php" in paginaMun and "/estadosat/" not in paginaMun:
 
 # As 3 variaveis abaixo, sao basicamente o que fiz acima, eu seleciono a pagina
 # e faco o request no urllib2 e trato com o beautifulsoap
 urlMun = "http://cidades.ibge.gov.br/xtras/"+paginaMun
 htmlMun = urllib2.urlopen(urlMun).read()
 soupMun = BeautifulSoup(htmlMun)
 
 # As variaveis abaixo, sao os dados que queriamos pegar
 # com calma vou explicar o que cada funcao do BeautifulSoap que usei faz
 # mas a principio, podemos ver que ela cria um vetor com o conteudo
 # puxando o resultado.
 popu_estimada2014 = soupMun.find_all('td',{'class': 'desc'})[0].get_text()
 val_popu_estimada2014 = soupMun.find_all('td',{'class': 'valor'})[0].get_text()
 
 popu_estimada2010 = soupMun.find_all('td',{'class': 'desc'})[1].get_text()
 val_popu_estimada2010 = soupMun.find_all('td',{'class': 'valor'})[1].get_text()
 
 uni_territorial = soupMun.find_all('td',{'class': 'desc'})[2].get_text().strip()
 val_uni_territorial = soupMun.find_all('td',{'class': 'valor'})[2].get_text()
 
 dens_demografica = soupMun.find_all('td',{'class': 'desc'})[3].get_text()
 val_dens_demografica = soupMun.find_all('td',{'class': 'valor'})[3].get_text()
 
 cod_municipio = soupMun.find_all('td',{'class': 'desc'})[4].get_text()
 val_cod_municipio = soupMun.find_all('td',{'class': 'valor'})[4].get_text()
 
 gentilico = soupMun.find_all('td',{'class': 'desc'})[5].get_text()
 val_gentilico = soupMun.find_all('td',{'class': 'valor'})[5].get_text()
 
 prefeito = soupMun.find_all('td',{'class': 'desc'})[6].get_text()
 val_prefeito = soupMun.find_all('td',{'class': 'valor'})[6].get_text()
 
 mun = soupMun.find('title').get_text().split("|")[3].strip()
 
 # Apenas um print para demonstrar como estao saindo as informacoes
 # antes de colocar elas em um banco de dados.
 print mun + "\n" +\
 popu_estimada2014 + ": " + val_popu_estimada2014 + "\n" +\
 popu_estimada2010 + ": " + val_popu_estimada2010 + "\n" +\
 uni_territorial + ": " + val_uni_territorial + "\n" +\
 dens_demografica + ": " + val_dens_demografica + "\n" +\
 cod_municipio + ": " + val_cod_municipio + "\n" +\
 gentilico + ": " + val_gentilico + "\n" +\
 prefeito + ": " + val_prefeito + "\n"
 
 # Uma excessao para caso de erro o programa nao parar. 
 except Exception:
 pass
Source: https://gist.github.com/danilovazb/e768c094235c3a0ebbbe
Vamos entender o ultimo código e o que foi feito nele, nesse ultimo eu trabalhei bem com o BeautifulSoap, o urllib2 fez o mesmo trabalho de antes, apenas serviu como um request na página.
Certo, agora vamos detalhar a fim de entender o BeatifulSoap, para ele interpretar a pagina HTML. O que eu fiz foi, quando eu usei o urllib2 para dar o request na pagina (Ex: Linha 6) eu “falei” para o ele o seguinte:
html = urllib2.urlopen(“http://site.com.br”).read() 
Certo, até ai, temos dentro da variável “html” a pagina toda como ela é, ou seja, está o HTML dela lá sem tratar. Agora entra o nosso amigo BeautifulSoap para trabalhar a pagina a fim de extrair as informações que precisamos.
Vamos usar a variável html com a página salva em HTML no BeautifulSoap da seguinte forma(Ex: Linha 9):
soup = BeautifulSoup(html)
No comando acima eu estou carregando o BeautifulSoup com a variável html dentro de uma nova variável chamada soup.
Agora temos a variável soup com o conteúdo da variável html pronto para ser tratado. Vamos percorrer todos os links da página que está salva na variável soup onde já está mapeada pelo nosso amigo BeautifulSoap, para fazer isso, vamos usar um laço condicional FOR (Ex: Linha 17), mas antes, sabemos que a tag que contém hyperlinks no HTML é a <a>, então, vamos forçar o BeautifulSoap a pesquisar em todo o código pelas tags <a> da seguinte maneira:
for link in soup.find_all('a'):
Assim ele vai preencher a variável link a cada ciclo com o conteúdo da tag <a>, mas ainda assim nós precisamos pegar o link que fica na propriedade href da tag <a>. Se dermos um print da variável link ele vai nos retornar esse output:
Para pegar o conteúdo da propriedade href, faremos da seguinte forma(Ex: Linha 21):
pagina = link.get('href')
O que estamos dizendo acima é, pegue o conteúdo do href contido na variável link e jogue para a variável pagina. Agora sim nós temos o conteúdo da propriedade href, ela está armazenada na variável pagina. Mesmo assim, eu tive algumas complicações, pois ele estava pegando todas as tags <a> de hiperlinks e eu queria apenas as que me levassem ao meu objetivo, foi então que precisei entender os links e filtrar. Lembra que na pagina 8 deste paper eu pedi que reparassem no link? Enfim, justamente para notar com detalhe se havia algo que pudéssemos usar em um IF afim de separar somente os links que gostaríamos que o scrapper visitasse.
Veja na linha 25 como fiz isso:
if "uf.php" in pagina:
O que a linha acima vai fazer, eu disse ao programa o seguinte: Se o resultado da variável pagina contiver uf.php então continue executando o código. Assim eu consigo filtrar o resultado e fazer com que ele acesse os links corretos. Logo abaixo desse IF eu coloquei um “pulo do gato” para montar a URL de acesso aos municípios para conseguir extrair o conteúdo do href e fazer uma junção com a pagina principal para acessar o link, note que ele traz dentro do href o conteúdo "../xtras/uf.php?lang=&coduf=12&search=acre",o que eu fiz foi fazer um split para separar em um vetor tudo que vem antes de "xtras/" e depois dele. Assim pegamos apenas o final e concatenamos com o link certo da pagina. (Ex: Linha 31 e Linha 34)[3: https://docs.python.org/2/library/stdtypes.html#str.split]
paginaUF = pagina.split('xtras/')[1]
urlUF = "http://cidades.ibge.gov.br/xtras/"+paginaUF
Certo, após isso, foi basicamente CTRL+C e CTRL+V da linha 52 a linha 58. Única diferença fica por conta do IF da linha 52 que coloquei um E(and) condicional para dizer ao IF que eu queria apenas o resultado que tivesse “perfil.php” e rejeitasse tudo que tivesse "/estadosat/" na variável paginaMun.
Logo abaixo, da linha 64 a 83 eu criei as variáveis para pegar os dados que queremos, nele eu faço um filtro nas tags da página com o método “find_all” do BeautifulSoap, veja no exemplo abaixo como faço a separação das tags e pego o texto delas.
popu_estimada2014 = soupMun.find_all('td',{'class': 'desc'})[0].get_text()
Repare que pedi ao BeautifullSoap para procurar em todo o código da pagina por uma tag que contivesse a estrutura acima, veja no código abaixo.
Pedi para ele procurar a tag TD que tivesse a CLASS chamada DESC, mas ele vai trazer todas as tags que contenham as informações que passei dentro de um vetor, sendo assim, vamos identificar nossas informações dentro do vetor, depois que achar o que precisamos, vamos acessar e colocar em variáveis.
popu_estimada2014 = soupMun.find_all('td',{'class': 'desc'})[0].get_text()
val_popu_estimada2014 = soupMun.find_all('td',{'class': 'valor'})[0].get_text()
					
popu_estimada2010 = soupMun.find_all('td',{'class': 'desc'})[1].get_text()
val_popu_estimada2010 = soupMun.find_all('td',{'class': 'valor'})[1].get_text()
					
uni_territorial = soupMun.find_all('td',{'class': 'desc'})[2].get_text().strip()
val_uni_territorial = soupMun.find_all('td',{'class': 'valor'})[2].get_text()
					
dens_demografica = soupMun.find_all('td',{'class': 'desc'})[3].get_text()
val_dens_demografica = soupMun.find_all('td',{'class': 'valor'})[3].get_text()
			
cod_municipio = soupMun.find_all('td',{'class': 'desc'})[4].get_text()
val_cod_municipio = soupMun.find_all('td',{'class': 'valor'})[4].get_text()
					
gentilico = soupMun.find_all('td',{'class': 'desc'})[5].get_text()
val_gentilico = soupMun.find_all('td',{'class': 'valor'})[5].get_text()
					
prefeito = soupMun.find_all('td',{'class': 'desc'})[6].get_text()
val_prefeito = soupMun.find_all('td',{'class': 'valor'})[6].get_text()
Gravando dados em um arquivo CSV
Depois que fiz isso, apenas fiz um print das informações como podemos ver da linha 89 a linha 96.
Agora que temos todas as informações sendo apresentadas na tela, vamos gravar em um arquivo CSV.
Para gravar o conteúdo em um arquivo, vamos mudar um pouco as linhas de 89 a 96 para o código abaixo:
from datetime import datetime #####>>>>> Adicionar no INICIO do script
arquivoIBGE = "ResultadoIBGE" + "-" + str(now.day) + str(now.month) + str(now.year) + ".csv"
arquivoGrava = open(arquivoIBGE,'a')
arquivoGrava.write("%s,%s,%s,%s,%s,%s,%s,%s" % \
(mun.strip(),val_popu_estimada2014.strip(),val_popu_estimada2010.strip(),val_uni_territorial.strip(),\
val_dens_demografica.strip(),val_cod_municipio.strip(),val_gentilico.strip(),val_prefeito.strip()+"\n")
Com essas 6 linhas acima, vamos gravar um arquivo chamado ResultadoIBGE-DIAMESANO.csv com os dados que obtivemos do IBGE.
Coleta e parser sistema Itaú Unibanco
Como vimos anteriormente, é bem útil você fazer parser de paginas HTML para adquirir dados e até mesmo elaborar uma estratégia. Dessa vez eu precisei pegar alguns dados do site do Itaú, mas tive problemas com o javascript deles, então, eu dei um “jeitinho brasileiro” para conseguir os dados. Vamos acompanhar abaixo:
O site que gostaria de acessar é o https://www.itau.com.br/pague-aqui/ e coletar os dados de lojas onde possa fazer pagamentos, a missão que foi dada pra mim era coletar esses dados e popular nossa base de dados para ter isso interno na empresa, enfim, fui atrás, missão dada parceiro, é missão cumprida.
Preparando para a coleta
Para ter uma ideia gráfica do que estou falando, veja a imagem abaixo, eu preciso “selecionar” estado por estado, cidade por cidade, bairro por bairro para que eu possa coletar TODAS as lojas que façam os tipos de “Recebimento e pagamentos por convênios” e de “Produtos e serviços atrelados ao cartão de crédito”.
Mas analisando o código da pagina, ela fica atrás de javascript, o que eu fiz para coletar, eu achei os links que geram as informações dessa pagina em JSON, veja abaixo o trecho do código da pagina do Itaú.
Vendo o que eu tinha para acessar era javascript eu realizei novamente a pesquisa e analisei na aba “Network” as conexões que ele faz com o servidor, consegui pegar ali o link correto para conseguir ver o resultado em JSON.
Só que se você reparar no link que obtive, alguns dados são substituídos por códigos numéricos.
https://ww18.itau.com.br/wsinvestnet/Corban.asmx/BuscarCorrespondenteBancario?cidade=197921&estado=AC&servico=3&segmento=8&bairro=1330426&nomeFantasiaCorrespondente=&callback=_jqjsp&_1420543918772=
Eu pintei de vermelho os códigos que obtive no link acima, veja que não tem nem como fazer um “brute-force” para descobrir a numeração, é muito número. O que eu fiz, a cada combo-box que selecionava ele me dava o link para o JSON correspondente. 
Como assim?!?! 
Certo, deixa explicar melhor, toda vez que eu selecionava uma opção ele me dava um link para o JSON daquele combo-box, eu atualizer a pagina para limpar as conexões e depois que atualizei eu abri novamente a guia de desenvolvedor e abri a aba network novamente, assim ele “limpa” as conexões, agora, selecionei apenas um combo-box para obter o link, veja na imagem abaixo.
Certo, agora vamos abrir o link do JSON e descobrir o que temos nele, mas antes, eu selecionei os 2 primeiros campos que pra mim não vão alterar em nada, logo em seguida eu selecionei o campo estado para pegar o link do JSON com todos os estados, veja a imagem abaixo.
https://ww18.itau.com.br/wsinvestnet/Corban.asmx/MontarCombosCorbanCidade?estado=AC&servico=3&segmento=8&callback=_jqjsp&_1420545033151=
Certo, entendendo o link acima. Esse link é o de listagem de cidades, podemos ver que temos uma propriedade passando no link chamada “estado”, como sabemos todas as siglas dos estados, nós conseguimos montar um script simples para conseguir coletar as cidades, me adiantando um pouco, o que eu fiz, eu olhei da mesma maneira o link para coletar os bairros, assim montei o script abaixo para coletar os dados.
import urllib2
import json
 
UF =['AC','AL','AM','AP','BA','CE','DF','ES','GO','MA','MG','MS','MT','PA','PB','PE','PI','PR','RJ','RN','RO','RR','RS','SC','SE','SP','TO']
#UF = ['AC','AL','AM','AP','BA','CE']
 
for estado in UF:
 #print estado
 urlCidade = 'https://ww18.itau.com.br/wsinvestnet/Corban.asmx/MontarCombosCorbanCidade?estado=' + estado +'&servico=3&segmento=8&callback=_jqjsp&_1412367567213='
 
 resp = urllib2.urlopen(urlCidade).read()
 resp = resp.replace('_jqjsp({"d":"{\\"?xml\\":{\\"@version\\":\\"1.0\\",\\"@encoding\\":\\"utf-8\\"},\\"root\\":{\\"listaCidade\\":{\\"row\\":','[')
 resp = resp.replace('}}}"});',']')
 resp = resp.replace('\\','')
 resp = resp.replace('[[{"','[{"')
 resp = resp.replace('"}]]','"}]')
 
 for mun in json.loads(resp.decode('utf-8')):
 #print estado + " - " + mun['DescricaoMunicipio'].strip() + " - " + mun['CodigoMunicipio']
 codMun = mun['CodigoMunicipio']
 municip = mun['DescricaoMunicipio'].strip()
 urlCidade = 'https://ww18.itau.com.br/wsinvestnet/Corban.asmx/MontarCombosCorbanBairro?codCidade=' + codMun +'&estado=' + estado + '&servico=3&segmento=8&callback=_jqjsp&_1412624740327='
 respA = urllib2.urlopen(urlCidade).read()respA = respA.replace('_jqjsp({"d":"{\\"?xml\\":{\\"@version\\":\\"1.0\\",\\"@encoding\\":\\"utf-8\\"},\\"root\\":{\\"listaBairro\\":{\\"row\\":','[')
 respA = respA.replace('}}}"});',']')
 respA = respA.replace('\\','')
 respA = respA.replace('[[{"','[{"')
 respA = respA.replace('"}]]','"}]')
 
 #print respA
 try:
 if 'null' in respA:
 urlCorrespondente ='https://ww18.itau.com.br/wsinvestnet/Corban.asmx/BuscarCorrespondenteBancario?cidade=' + codMun + '&estado=' + estado +'&servico=3&segmento=8&bairro=Bairro&nomeFantasiaCorrespondente=&callback=_jqjsp&_1412625558140='
 respB = urllib2.urlopen(urlCorrespondente).read()
 respB = respB.replace('_jqjsp({"d":"{\\"?xml\\":{\\"@version\\":\\"1.0\\",\\"@encoding\\":\\"utf-8\\"},\\"root\\":{\\"listaCorrespondente\\":{\\"row\\":','[')
 respB = respB.replace('}}}"});',']')
 respB = respB.replace('\\','')
 respB = respB.replace('[[{"','[{"')
 respB = respB.replace('"}]]','"}]')
 respB = respB.replace('{"@xml:space":"preserve","#significant-whitespace":" "}','" "')
 #print respB
 for correspondente in json.loads(respB.decode('utf-8')):
 print estado + " - " + municip + " - " + codMun + " - " + bairro['DescricaoBairro'].strip() + " - " + bairro['CodigoBairro'] + " - " + correspondente['NomeFantasiaCorrespondente'].strip()+ " - " + correspondente['CnpjCorrespondente'] + " - " + correspondente['DescricaoEnderecoCorrespondente'].strip()
 else: 
 for bairro in json.loads(respA.decode('utf-8')):
 codBairro = bairro['CodigoBairro']
 urlCorrespondente ='https://ww18.itau.com.br/wsinvestnet/Corban.asmx/BuscarCorrespondenteBancario?cidade=' + codMun + '&estado=' + estado +'&servico=3&segmento=8&bairro=' + codBairro + '&nomeFantasiaCorrespondente=&callback=_jqjsp&_1412625558140='
 respB = urllib2.urlopen(urlCorrespondente).read()
 respB = respB.replace('_jqjsp({"d":"{\\"?xml\\":{\\"@version\\":\\"1.0\\",\\"@encoding\\":\\"utf-8\\"},\\"root\\":{\\"listaCorrespondente\\":{\\"row\\":','[')
 respB = respB.replace('}}}"});',']')
 respB = respB.replace('\\','')
 respB = respB.replace('[[{"','[{"')
 respB = respB.replace('"}]]','"}]')
 respB = respB.replace('{"@xml:space":"preserve","#significant-whitespace":" "}','" "')
 respB = respB.replace(', ',' ')
 # print respB
 for correspondente in json.loads(respB.decode('utf-8')):
 print estado + " - " + municip + " - " + codMun + " - " + bairro['DescricaoBairro'].strip() + " - " + bairro['CodigoBairro'] + " - " + correspondente['NomeFantasiaCorrespondente'].strip()+ " - " + correspondente['CnpjCorrespondente'] + " - " + correspondente['DescricaoEnderecoCorrespondente'].strip()
 except Exception:
 print"_______________________________________________________________________________________________________________"
 pass
Source: https://gist.github.com/danilovazb/4fc06732cd7b0a40c315
Outra coisa muito importante, o formato que o banco adotou foi o JSONP, o que eu fiz para facilitar minha vida foi remover as tags que são parte do JSONP e deixei ele no formato do JSON para o parser ser efetivo.
Danilo Vaz
São Paulo, 05/01/2015

Outros materiais