Voltar ao blogue
Guias
Robert SfichiLast updated on Mar 31, 20267 min read

Como criar um web scraper com Python e Selenium

Como criar um web scraper com Python e Selenium

Muitos programadores optam por criar o seu próprio scraper web em vez de utilizar produtos já disponíveis. Se perguntar à maioria deles qual a linguagem de programação que preferem, é muito provável que ouça o nome Python inúmeras vezes.

O Python tornou-se o favorito do público devido à sua sintaxe flexível e à abundância de bibliotecas que simplificam o trabalho de web scraping. Hoje, vamos falar sobre uma dessas bibliotecas.

Este guia irá abordar como começar a extrair dados com o Selenium e o Python. Iremos criar um script em Python que irá iniciar sessão num site, extrair alguns dados, formatá-los de forma organizada e armazená-los num ficheiro CSV.

Se quiser uma visão geral mais abrangente de como o Python pode ser usado na extração de dados da web, deve consultar o nosso guia definitivo para criar um scraper com Python. Depois, volte aqui para que possamos aprofundar ainda mais os detalhes!

Uma visão geral do Selenium

Tal como afirma o site oficial do Selenium, o Selenium é um conjunto de ferramentas para automatizar navegadores web que foi inicialmente introduzido como uma ferramenta para testes entre navegadores.

A API criada pela equipa do Selenium utiliza o protocolo WebDriver para assumir o controlo de um navegador web, como o Chrome ou o Firefox, e realizar diferentes tarefas, tais como:

  • Preencher formulários
  • Deslocar a página
  • Capturar imagens
  • Clicar em botões

Agora deve estar a perguntar-se como é que tudo isto se traduz em web scraping. Na verdade, é simples.

A extração de dados pode ser uma verdadeira dor de cabeça, por vezes. Atualmente, os sites estão a ser construídos como Aplicações de Página Única, mesmo quando não há necessidade disso. Estão a apresentar CAPTCHAs com mais frequência do que o necessário e até a bloquear os IPs de utilizadores regulares.

Em suma, a deteção de bots é uma funcionalidade muito frustrante que parece um bug.

O Selenium pode ajudar nestes casos, ao compreender e executar código JavaScript e automatizar muitos processos tediosos de web scraping, como percorrer a página, capturar elementos HTML ou exportar dados obtidos.

Instalação

Para mostrar o verdadeiro poder do Selenium e do Python, vamos extrair algumas informações do subreddit /r/learnprogramming. Além de extrair dados, também vou mostrar-lhe como se pode implementar o login. Agora que já compreendemos a ferramenta principal e o site que vamos utilizar, vamos ver que outros pré-requisitos precisamos de ter instalados:

1. Python. Iremos utilizar o Python 3.0. No entanto, sinta-se à vontade para utilizar o Python 2.0, fazendo pequenos ajustes. Pode descarregá-lo e instalá-lo a partir daqui.

2. Pacote Selenium. Pode instalar o pacote Selenium utilizando o seguinte comando:

pip3 install selenium

3. Pacote Pandas. Será utilizado para extrair e armazenar dados recolhidos num ficheiro .csv. Por favor, execute o seguinte comando para o instalar no seu dispositivo.

pip3 install pandas

4. Pacote BeautifulSoup. Utilizado para analisar documentos HTML e XML. Basta executar esta linha:

pip3 install beautifulsoup

5. Google Chrome. Consulte este link para saber mais sobre como o descarregar e instalar.

6. Chrome Driver. Irá ajudar-nos a configurar o web driver para o Selenium. Siga este link para descarregar e instalar a versão mais recente do Chrome Driver. Não se esqueça de guardar o caminho onde o instalou.

Iniciar o navegador

Vamos começar. Crie um novo ficheiro scraper.py e importe o pacote Selenium copiando a seguinte linha:

from selenium import webdriver

Vamos agora criar uma nova instância do Google Chrome escrevendo:

driver = webdriver.Chrome(LOCATION)

Substitua LOCATION pelo caminho onde o driver do Chrome se encontra no seu computador. Consulte a documentação do Selenium para encontrar o caminho mais preciso para o driver web, com base no sistema operativo que está a utilizar.

O passo final é aceder ao site de onde pretendemos extrair dados. No nosso caso, trata-se de https://www.reddit.com/r/learnprogramming/top/?t=month. Copie a seguinte linha no ficheiro Python recém-criado:

driver.get("https://www.reddit.com/r/learnprogramming/top/?t=month")

Executando o seguinte comando numa janela de terminal:

python3 scraper.py

Devemos agora ter uma nova instância do Google Chrome aberta que especifica «O Chrome está a ser controlado por software de teste automatizado» no topo da nossa página.

Localizar dados específicos

Como provavelmente já percebeu, neste tutorial vamos extrair dados do subreddit /r/learnprogramming. Vamos guardar o título das publicações, o autor e o número de votos positivos e armazená-los num novo ficheiro .csv. Vamos ver onde se encontram na página HTML e como podemos extraí-los.

Depois de o Google Chrome ter finalmente carregado a página, vamos clicar com o botão direito do rato em qualquer publicação e selecionar «Inspecionar». Podemos encontrar o contentor HTML da publicação sob o nome de classe _1oQyIsiPHYt6nx7VOmd1sz.

Também pode executar o Google Chrome sem uma interface gráfica de utilizador e registar o conteúdo HTML da página adicionando algumas linhas de código. Vamos definir a opção headless como true para o driver do Chrome (para remover a interface gráfica) e um tamanho de janela de 1080 píxeis (para obter o código HTML correto para o nosso caso de utilização).

As duas últimas linhas de código encerram o Chrome logo após terminar o registo do HTML da página.

O novo ficheiro scraper.py ficará assim:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome("./chromedriver")
driver.get("https://www.reddit.com/r/learnprogramming/top/?t=month")

print(driver.page_source)
driver.quit()

WebElement

Um WebElement é um objeto Selenium que representa um elemento HTML. Como verá no tutorial seguinte, podemos realizar muitas ações nestes elementos. Algumas delas são:

  • Clicar nele utilizando o método .click()
  • Introduzir texto num elemento de entrada específico chamando o método .send_keys()
  • Ler o texto de um elemento utilizando element.text
  • Verificar se um elemento está visível na página chamando .is_displayed() sobre ele

Um exemplo do Selenium em ação

Agora que temos o nosso projeto configurado, podemos finalmente começar a fazer o scraping.

Iniciar sessão

Vamos demonstrar o poder do Selenium fazendo login na nossa conta do Reddit e extraindo os dados apresentados anteriormente. Comecemos por fazer com que o Selenium clique no botão de login na parte superior da página. Depois de inspecionar o HTML da página, podemos ver que o nome da classe do botão de login é _2tU8R9NTqhvBrhoNAXWWcP.

login_button = driver.find_element_by_class_name('_2tU8R9NTqhvBrhoNAXWWcP')
login_button.click()

Isto irá abrir o modal de login, onde podemos ver os campos de utilizador e palavra-passe que temos de preencher. Vamos continuar com as seguintes linhas:

driver.switch_to_frame(driver.find_element_by_class_name('_25r3t_lrPF3M6zD2YkWvZU'))

driver.find_element_by_id("loginUsername").send_keys('USERNAME')
driver.find_element_by_id("loginPassword").send_keys('PASSWORD')

driver.find_element_by_xpath("//button[@type='submit']").click()

Se inspecionarmos o elemento modal, podemos ver que o seu contentor é um iframe. É por isso que temos de mudar para frame na primeira parte do código, pois selecionar os campos de entrada sem ele resultará num erro.

Em seguida, obtemos os elementos de entrada e fornecemos-lhes as credenciais adequadas antes de clicar no botão de envio. Isto irá levar-nos de volta à página /r/learnprogramming, mas agora estamos conectados e prontos para votar!

Fazer uma captura de ecrã

Fazer uma captura de ecrã usando o Selenium e o Python é bastante fácil. Basta escrever o seguinte comando no ficheiro scraper.py após declarar o web driver.

driver.save_screenshot('screenshot.png')

É útil saber que pode definir o tamanho da janela do Google Chrome adicionando as seguintes linhas de código:

from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--window-size=1920,1080")

É assim que a captura de ecrã ficará no nosso caso:

Extrair dados

Como já referimos anteriormente, precisamos de obter o título das publicações, o autor e o número de votos positivos. Comecemos por importar os pacotes BeautifulSoup e Pandas e criar três matrizes vazias para cada tipo de informação de que precisamos.

from bs4 import BeautifulSoup
import pandas as pd

titles = []
upvotes=[]
authors = []

Vamos usar o BeautifulSoup para analisar o documento HTML escrevendo as seguintes linhas:

content = driver.page_source
soup = BeautifulSoup(content, features="html.parser")

Depois de inspecionar com sucesso o documento HTML e escolher os seletores certos, vamos agora buscar os títulos, votos positivos e autores e atribuí-los à matriz correta:

for element in soup.findAll('div', attrs={'class': '_1oQyIsiPHYt6nx7VOmd1sz'}):
   title = element.find('h3', attrs={'class': '_eYtD2XCVieq6emjKBH3m'})
   upvote = element.find('div', attrs={'class': '_3a2ZHWaih05DgAOtvu6cIo'})
   author = element.find('a', attrs={'class': '_23wugcdiaj44hdfugIAlnX'})
   titles.append(title.text)
   upvotes.append(upvote.text)
   authors.append(author.text)

Por fim, vamos armazenar a informação num ficheiro CSV utilizando o pacote Pandas que importámos anteriormente.

df = pd.DataFrame({'Post title': titles, 'Author': authors, 'Number of upvotes': upvotes})
df.to_csv('posts.csv', index=False, encoding='utf-8')

E pronto! Vamos dar uma olhadela no ficheiro exportado:

Parece ter toda a informação de que precisamos.

Dica extra: Por vezes, precisamos de mais dados do que os que o site fornece na primeira carga. Na maioria das vezes, a ação de recolha de dados é acionada quando o utilizador faz scroll para baixo. Se precisar de fazer scroll para baixo para obter mais dados, pode usar o método .execute_script() da seguinte forma:

scrollDown = "window.scrollBy(0,2000);"
driver.execute_script(scrollDown)

Considerações finais

Espero que tenha gostado de criar o web scraper tanto quanto eu. Programar nem sempre é divertido, mas construir pequenos scripts como este lembra-me de quando estava a começar e torna o processo muito mais interessante.

Ainda assim, o script que conseguimos criar neste tutorial não consegue fazer muito trabalho pesado. Faltam-lhe algumas funcionalidades essenciais que tornam o web scraping perfeito. Ligar-se usando proxies móveis ou residenciais e resolver CAPTCHAs são apenas algumas delas.

Se procura uma forma mais profissional de extrair dados, veja o que a WebScrapingAPI pode fazer e comprove por si mesmo se é o que procura. Existe um pacote gratuito, pelo que o único investimento é 30 minutos do seu tempo.

Obrigado por ter dedicado o seu tempo a ler isto. Boa extração!

Sobre o autor
Robert Sfichi, Desenvolvedor Full-Stack @ WebScrapingAPI
Robert SfichiDesenvolvedor Full-Stack

Robert Sfichi é membro da equipa da WebScrapingAPI, contribuindo para o produto e ajudando a criar soluções fiáveis que apoiam a plataforma e os seus utilizadores.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.