Web Scraping com Python
Web scraping é uma técnica para varrer
a web em busca de informações de seu interesse.
Esse artigo aborda o uso de Python e das bibliotecas Requests e BeautifulSoup para criar
robôs que executem esta missão.
1. Capturando conteúdo web: O primeiro passo que se deve realizar é a captura de conteúdo de uma página web, para isso criaremos uma variável com a url da página, em seguida usaremos a biblioteca Requests para obter o conteúdo HTML original. Este último passo é realizado criando uma variável e atribuindo a ela o conteúdo retornado pela chamada ao método get da biblioteca requests.
>>> url = 'https://www.crummy.com/software/BeautifulSoup/'
>>> import requests
>>> page = requests.get(url)
Para conferir o resultado, pode-se verificar o tipo da variável, confirmando que se trata de um objeto do tipo 'requests.models.Response' ou chamando a variável page diretamente no Shell que retornará a resposta Response [200] caso a captura tenha sido bem sucedida.
>>> type(page)
<class 'requesets.models.Response'>
>>> page
<Response [200]>
2. Convertendo conteúdo HTML: O conteúdo da variável page, é acessado pelo atributo content (page.content),
mas o retorno da função get é o material bruto
da página, ou seja, o texto e todos os elementos HTML da
página acessada. Isto ocorre, porque requests e suas funções não são exclusivas para web scraping, mas para acesso
a conteúdo web de diversas formas, inclusive para processamento do conteúdo completo. Mas, como material em HTML
no geral não tem utilidade para usuários finais que desejam ler o texto puro, precisamos de uma ferramenta adicional
para tornar as coisas bonitas
, para isso entra em cena a poderosa biblioteca Beautiful Soup, que faz a conversão,
também conhecida como parser, do conteúdo, gerando um objeto <class 'bs4.BeautifulSoup'>, que organiza o conteúdo
de maneira que facilmente se pode acessar tanto o conteúdo HTML quanto o conteúdo textual legível.
Nas linhas a seguir é importada a biblioteca e criada uma variável que recebe o retorno da função BeautifulSoup:
>>> from bs4 import BeautifulSoup
>>> page = BeautifulSoup(page.content, 'html.parser')
3. Capturando texto limpo: Com os dados já estruturados
no objeto BeautifulSoup criado no passo anterior
é possível acessá-los, exbí-los na tela, armazená-los em variáveis e salvá-los em arquivos ou bancos de dados, conforme
as necessidades de cada projeto.
Estas ações, quando o conteúdo original proveio de uma página HTML, são feitas a partir das referências às tags (elementos) HTML.
Por exemplo para buscar conteúdo de parágrafos usamos como referência a tag 'p', enquanto para capturar um título usamos 'h1'.
A seguir são apresentados dois exemplos simples de tratamento do conteúdo de títulos e parágrafos, respectivamente:
>>> h1 = bs.find_all('h1')
>>> h1
[<h1>Beautiful Soup</h1>]
Veja que a captura, guardada na variável h1, ainda apresenta uma visualização estranha, similar ao retorno de uma lista
tradicional de Python, mas se consultar o tipo com type(h1) perceberá que trata-se de um objeto bs4
<class 'bs4.element.ResultSet'>. Este tipo de objeto, guarda os resultados da busca por determinado
elemento, e pode ser iterado para recuperar o conteúdo textual.
As linhas a seguir cumprem este objetivo, iterando o objeto h1 e capturando o texto de cada ocorrência com o método .get_text():
>>> titulos = [h1[k].get_text() for k in range(0, len(h1))]
>>> titulos
['BeautifulSoup']
>>> print(titulos[0])
BeautifulSoup
Retornando ao objeto bs que ainda está com o conteúdo completo da varredura, vamos usar novamente o método .find_all() para capturar os parágrafos representados pelo elemento 'p' e em seguida chamamos a função len() para para a variável criada, onde podemos verificar que foram capturados 25 parágrafos na página consultada.
>>> p = bs.find_all('p')
>>> len(p)
25
Se tentar exibido o conteúdo de um item do objeto p, por exemplo usando print(p[0]) será exibido o primeiro item, mas ainda com os
elementos HTML. Para capturar os parágrafos limpos
podemos usar a mesma lógica anterior, criando um lista a partir da iteração
do conteúdo de p.
>>> paragrafos = [p[k].get_text() for k in range(0, len(p))]
>>> len(paragrafos)
25
4. Armazenando o conteúdo:Agora sim o conteúdo limpo dos parágrafos estará disponível e pode ser exibido na tela ou armazenado. Um único detalhe que pode ser tratado se for necessário é que ao capturar o texto os caracteres de quebra de linha ficam armazenados juntamente, o que pode ser visto na comparação da exibição na tela pela chamada direta de um dos itens da lista ou pela sua exibição com o comando print(), mas como esse não é um erro ou um elemento HTML esquecido, mas uma característica do texto original, sua remoção (por exemplo através do uso da função sub da biblioteca re é opcional e não está no escopo deste estudo).
>>> paragrafos[0]
"You didn't write that awful page. You're just trying to get some\ndata out of it.
Beautiful Soup is here to help. Since 2004, it's been\nsaving programmers hours or
days of work on quick-turnaround\nscreen scraping projects."
>>> print(paragrafos[0])
You didn't write that awful page. You're just trying to get some
data out of it. Beautiful Soup is here to help. Since 2004, it's been
saving programmers hours or days of work on quick-turnaround
screen scraping projects.
Com o conteúdo completo dos parágrafos na variável criada, o tratamento e armazenamento pode ser feito da maneira desejada pelo projeto específico. Para dar um exemplo de como podemos fazer isso, o código abaixo junta os parágrafos em um texto fluído e salva em um arquivo de texto.
>>> texto = '\n'.join(paragrafos[k] for k in range(0, len(paragrafos)))
>>> with open('scrap.txt', 'w') as arquivo:
print(f'Captura do site: {url}', file=arquivo)
print('=' * 100, file=arquivo)
print('Título:', file=arquivo, end='')
print(titulos[0], file=arquivo)
print('=' * 100, file=arquivo)
print('Conteúdo:', file=arquivo)
print(texto, file=arquivo)
Considerações finais: Este material apresenta apenas uma forma simplificada e direta de uso das
bibliotecas estudadas para captura de dados de páginas web. Há diversas outras ações complementares que podem
ser realizadas para expansão do conteúdo a ser pesquisado, conversão (parser) de outros formatos de conteúdo online
como XML, Java Script, imagens, PDF, etc., além da possibilidade de uso destas técnicas de maneira incorporada a
um programa com varredura programada, tratamento de erros, parametrização de tags
e outros elementos a serem
pesquisadas com base em estudo do conteúdo dos sites a serem consultados e dos objetivos do projeto específico.
Os links da documentação das bibliotecas e o material de referência indicado ao final ajudam a expansão do uso, cobrindo
estes e outros aspectos que tornam o web scraping uma poderosa ferramenta em diversos contextos.
Referências
Bibliotecas Python utilizadas:
Biblioteca | Documentação PyPi | Página Oficial |
---|---|---|
BeautifulSoup | pypi.org/project/beautifulsoup4 | www.crummy.com/software/BeautifulSoup |
Requests | pypi.org/project/requests | 2.python-requests.org |
Livros e artigos sugeridos:
- MITCHELL, Ryan. Web Scraping com Python: coletando mais dados na web moderna. 2. ed. São Paulo: Novatec, 2019