Web Scraping usando Python: guia passo a passo

A raspagem da Web é a ideia de extrair informações de um site e usá-las para um caso de uso específico.

Digamos que você esteja tentando extrair uma tabela de uma página da Web, convertê-la em um arquivo JSON e usar o arquivo JSON para criar algumas ferramentas internas. Com a ajuda da raspagem da web, você pode extrair os dados que deseja, direcionando os elementos específicos em uma página da web. A raspagem da Web usando o Python é uma escolha muito popular, pois o Python fornece várias bibliotecas, como BeautifulSoup ou Scrapy, para extrair dados com eficiência.

Ter a habilidade de extrair dados com eficiência também é muito importante como desenvolvedor ou cientista de dados. Este artigo ajudará você a entender como raspar um site de maneira eficaz e obter o conteúdo necessário para manipulá-lo de acordo com sua necessidade. Para este tutorial, usaremos o pacote BeautifulSoup. É um pacote moderno para coletar dados em Python.

Por que usar o Python para Web Scraping?

Python é a primeira escolha para muitos desenvolvedores ao criar raspadores da web. Existem muitos motivos pelos quais o Python é a primeira escolha, mas, para este artigo, vamos discutir os três principais motivos pelos quais o Python é usado para extração de dados.

Biblioteca e suporte da comunidade: Existem várias bibliotecas excelentes, como BeautifulSoup, Scrapy, Selenium, etc., que fornecem ótimas funções para raspar páginas da Web com eficiência. Ele construiu um excelente ecossistema para web scraping e também porque muitos desenvolvedores em todo o mundo já usam o Python, você pode obter ajuda rapidamente quando estiver travado.

Automação: Python é famoso por seus recursos de automação. Mais do que web scraping é necessário se você estiver tentando fazer uma ferramenta complexa que depende de scraping. Por exemplo, se você deseja criar uma ferramenta que rastreie o preço dos itens em uma loja online, precisará adicionar algum recurso de automação para que ela possa rastrear as taxas diariamente e adicioná-las ao seu banco de dados. O Python oferece a capacidade de automatizar esses processos com facilidade.

Visualização de dados: a raspagem da Web é muito usada por cientistas de dados. Os cientistas de dados geralmente precisam extrair dados de páginas da web. Com bibliotecas como Pandas, o Python simplifica a visualização de dados a partir de dados brutos.

  25 termos contábeis que você deve conhecer como iniciante

Bibliotecas para Web Scraping em Python

Existem várias bibliotecas disponíveis em Python para simplificar a raspagem da web. Vamos discutir as três bibliotecas mais populares aqui.

#1. Belasopa

Uma das bibliotecas mais populares para web scraping. BeautifulSoup tem ajudado desenvolvedores a raspar páginas da web desde 2004. Ele fornece métodos simples para navegar, pesquisar e modificar a árvore de análise. O próprio Beautifulsoup também faz a codificação dos dados de entrada e saída. É bem conservado e tem uma grande comunidade.

#2. Scrapy

Outra estrutura popular para extração de dados. Scrapy tem mais de 43.000 estrelas no GitHub. Também pode ser usado para extrair dados de APIs. Ele também possui alguns suportes integrados interessantes, como o envio de e-mails.

#3. Selênio

O Selenium não é principalmente uma biblioteca de raspagem da web. Em vez disso, é um pacote de automação do navegador. Mas podemos estender facilmente suas funcionalidades para raspar páginas da web. Ele usa o protocolo WebDriver para controlar diferentes navegadores. O selênio está no mercado há quase 20 anos. Mas usando o Selenium, você pode facilmente automatizar e extrair dados de páginas da web.

Desafios com Python Web Scraping

Pode-se enfrentar muitos desafios ao tentar extrair dados de sites. Existem problemas como redes lentas, ferramentas anti-raspagem, bloqueio baseado em IP, bloqueio de captcha, etc. Esses problemas podem causar grandes problemas ao tentar raspar um site.

Mas você pode efetivamente contornar os desafios seguindo algumas maneiras. Por exemplo, na maioria dos casos, um endereço IP é bloqueado por um site quando há mais do que uma certa quantidade de solicitações enviadas em um intervalo de tempo específico. Para evitar o bloqueio de IP, você precisará codificar seu raspador para que ele esfrie após o envio de solicitações.

Os desenvolvedores também tendem a colocar armadilhas honeypot para raspadores. Essas armadilhas geralmente são invisíveis aos olhos humanos, mas podem ser rastreadas por um raspador. Se você estiver raspando um site que coloca uma armadilha de honeypot, você precisará codificar seu raspador de acordo.

Captcha é outro problema grave com scrapers. A maioria dos sites hoje em dia usa um captcha para proteger o acesso de bots às suas páginas. Nesse caso, pode ser necessário usar um solucionador de captcha.

Raspando um site com Python

Conforme discutimos, usaremos o BeautifulSoup para descartar um site. Neste tutorial, iremos extrair os dados históricos do Ethereum da Coingecko e salvar os dados da tabela como um arquivo JSON. Vamos passar para a construção do raspador.

  Como remover o áudio de um vídeo antes de compartilhá-lo no iPhone

O primeiro passo é instalar BeautifulSoup e Requests. Para este tutorial, usarei o Pipenv. Pipenv é um gerenciador de ambiente virtual para Python. Você também pode usar o Venv se quiser, mas eu prefiro o Pipenv. Discutir o Pipenv está além do escopo deste tutorial. Mas se você quiser aprender como o Pipenv pode ser usado, siga este guia. Ou, se você quiser entender os ambientes virtuais do Python, siga este guia.

Inicie o shell Pipenv no diretório do projeto executando o comando pipenv shell. Ele lançará um subshell em seu ambiente virtual. Agora, para instalar o BeautifulSoup, execute o seguinte comando:

pipenv install beautifulsoup4

E, para instalar os pedidos, execute o comando semelhante ao acima:

pipenv install requests

Quando a instalação estiver concluída, importe os pacotes necessários para o arquivo principal. Crie um arquivo chamado main.py e importe os pacotes conforme abaixo:

from bs4 import BeautifulSoup
import requests
import json

O próximo passo é obter o conteúdo da página de dados históricos e analisá-los usando o parser HTML disponível no BeautifulSoup.

r = requests.get('https://www.coingecko.com/en/coins/ethereum/historical_data#panel')

soup = BeautifulSoup(r.content, 'html.parser')

No código acima, a página é acessada através do método get disponível na biblioteca request. O conteúdo analisado é então armazenado em uma variável chamada sopa.

A parte de raspagem original começa agora. Primeiro, você precisará identificar a tabela corretamente no DOM. Se você abrir esta página e inspecioná-la usando as ferramentas de desenvolvedor disponíveis no navegador, verá que a tabela possui essas classes table table-striped text-sm text-lg-normal.

Tabela de dados históricos Coingecko Ethereum

Para direcionar corretamente esta tabela, você pode usar o método find.

table = soup.find('table', attrs={'class': 'table table-striped text-sm text-lg-normal'})

table_data = table.find_all('tr')

table_headings = []

for th in table_data[0].find_all('th'):
    table_headings.append(th.text)

No código acima, primeiro a tabela é encontrada usando o método soup.find, então usando o método find_all, todos os elementos tr dentro da tabela são pesquisados. Esses elementos tr são armazenados em uma variável chamada table_data. A tabela tem alguns elementos para o título. Uma nova variável chamada table_headings é inicializada para manter os títulos em uma lista.

Um loop for é então executado para a primeira linha da tabela. Nesta linha, todos os elementos com th são pesquisados ​​e seu valor de texto é adicionado à lista table_headings. O texto é extraído usando o método text. Se você imprimir a variável table_headings agora, poderá ver a seguinte saída:

['Date', 'Market Cap', 'Volume', 'Open', 'Close']

A próxima etapa é raspar o restante dos elementos, gerar um dicionário para cada linha e, em seguida, acrescentar as linhas em uma lista.

for tr in table_data:
    th = tr.find_all('th')
    td = tr.find_all('td')

    data = {}

    for i in range(len(td)):
        data.update({table_headings[0]: th[0].text})
        data.update({table_headings[i+1]: td[i].text.replace('n', '')})

    if data.__len__() > 0:
        table_details.append(data)

Esta é a parte essencial do código. Para cada tr na variável table_data, primeiro, os elementos th são pesquisados. Os elementos th são a data mostrada na tabela. Esses elementos th são armazenados dentro de uma variável th. Da mesma forma, todos os elementos td são armazenados na variável td.

  Como meu ISP pode saber que estou usando o BitTorrent?

Um dado de dicionário vazio é inicializado. Após a inicialização, percorremos o intervalo de elementos td. Para cada linha, primeiro atualizamos o primeiro campo do dicionário com o primeiro item de th. O código table_headings[0]: º[0].text atribui um par chave-valor de data e o primeiro elemento.

Depois de inicializar o primeiro elemento, os outros elementos são atribuídos usando data.update({table_headings[i+1]: td[i].text.replace(‘n’, ”)}). Aqui, o texto dos elementos td é primeiro extraído usando o método text e, em seguida, todos os n são substituídos usando o método replace. O valor é então atribuído ao i+1º elemento da lista table_headings porque o i-ésimo elemento já está atribuído.

Então, se o comprimento do dicionário de dados exceder zero, anexamos o dicionário à lista table_details. Você pode imprimir a lista table_details para verificar. Mas estaremos escrevendo os valores em um arquivo JSON. Vamos dar uma olhada no código para isso,

with open('table.json', 'w') as f:
    json.dump(table_details, f, indent=2)
    print('Data saved to json file...')

Estamos usando o método json.dump aqui para gravar os valores em um arquivo JSON chamado table.json. Assim que a gravação estiver concluída, imprimimos os dados salvos no arquivo json… no console.

Agora, execute o arquivo usando o seguinte comando,

python run main.py

Depois de algum tempo, você poderá ver o texto Dados salvos no arquivo JSON… no console. Você também verá um novo arquivo chamado table.json no diretório de arquivos de trabalho. O arquivo será semelhante ao seguinte arquivo JSON:

[
  {
    "Date": "2022-11-27",
    "Market Cap": "$145,222,050,633",
    "Volume": "$5,271,100,860",
    "Open": "$1,205.66",
    "Close": "N/A"
  },
  {
    "Date": "2022-11-26",
    "Market Cap": "$144,810,246,845",
    "Volume": "$5,823,202,533",
    "Open": "$1,198.98",
    "Close": "$1,205.66"
  },
  {
    "Date": "2022-11-25",
    "Market Cap": "$145,091,739,838",
    "Volume": "$6,955,523,718",
    "Open": "$1,204.21",
    "Close": "$1,198.98"
  },
// ...
// ... 
]

Você implementou com sucesso um web scraper usando Python. Para visualizar o código completo, você pode visitar este repositório do GitHub.

Conclusão

Este artigo discutiu como você poderia implementar um simples raspagem do Python. Discutimos como o BeautifulSoup poderia ser usado para extrair dados rapidamente do site. Também discutimos outras bibliotecas disponíveis e por que o Python é a primeira escolha para muitos desenvolvedores para raspar sites.

Você também pode olhar para essas estruturas de raspagem da web.