Como executar um navegador sem cabeça com Python para Web Scraping: Dicas e Truques

Mihnea-Octavian Manolache em Feb 03 2023

imagem do blogue

Usar um navegador Python headless com Selenium é quase a norma em web scraping. Mas o que é realmente um headless browser? E qual é o melhor headless browser para Selenium? E por que usar um headless browser em Python quando se tem `requests`? Bem, existem muitas perguntas sobre esse tópico. O que significa que nós temos muitas respostas para descobrir juntos. Mas antes de nos aprofundarmos, vamos traçar alguns objetivos de aprendizado. Ao final deste artigo, você deverá ser capaz de:

  • Compreender o que é um browser sem cabeça e os seus casos de utilização
  • Saber como abrir um browser sem cabeça em Python
  • Criar um web scraper com Python e Selenium

E, finalmente, também falaremos sobre alternativas aos navegadores sem cabeça Python. Apesar de o foco ser Python, o meu objetivo é descobrir a melhor solução de scraping. E isso leva em conta o tempo de resposta, os recursos utilizados, etc. Então, sem mais delongas, vamos ao assunto!

O que significa Python headless browser?

Em termos gerais, um browser é um programa de computador que permite aos utilizadores navegar e interagir com uma página Web. Um navegador sem cabeça é exatamente isso, mas sem uma interface gráfica com o usuário. Isso significa que um navegador Python headless é um programa que pode:

  • Navegar para qualquer sítio Web na Internet
  • Renderizar ficheiros JavaScript fornecidos pelo sítio Web
  • Interagir com os componentes dessa página Web

O facto de não existir uma interface gráfica associada levanta algumas questões sobre a interação. No entanto, a resposta é bastante simples. Uma vez que não existe GUI, os seres humanos não podem interagir diretamente com a página. E é aí que entram em ação os controladores Web. Um web driver é uma interface que permite a introspeção e o controlo. Em termos simples, os controladores Web são estruturas que nos permitem controlar programaticamente vários navegadores Web.

Existem alguns frameworks que permitem a automação de navegadores em Python. Mas o principal deles é o Selenium. O Selenium é um conjunto de ferramentas construído principalmente para testes automatizados. Mas na prática, ele é amplamente utilizado para web scraping também.

Por que usar um navegador sem cabeça em Python?

De acordo com o cabeçalho da página inicial do Selenium:

"O Selenium automatiza os navegadores. É só isso! O que faz com esse poder depende inteiramente de si."

Isto leva-nos a crer que os browsers automatizados têm vários casos de utilização. Mas porquê executá-los em modo headless? Bem, a resposta é mais uma vez simples. Um navegador Python headless usa menos recursos (CPU e memória) em comparação com um navegador headful. E isso acontece principalmente porque não há elementos gráficos a serem desenhados.

Mais uma vez, menos ainda é mais quando comparado a um cliente HTTP básico como o `requests` do Python, por exemplo. E isso é porque o navegador headless ainda abre muitos processos para interagir com a página e renderizar arquivos JavaScript. Como você sabe, o `requests` não é capaz de renderizar JavaScript. Você só pode buscar HTML puro usando ele. E, nos dias de hoje, isso não é nem de perto suficiente para o web scraping. A maioria das plataformas web modernas dependem muito do JavaScript para preencher o DOM. Por exemplo, se você tentar `curlar` um aplicativo React, você receberá uma página web vazia que pede para você 'habilitar o JavaScript':

<!doctype html>

<html lang="en">

<head>

...

</head>

<body>

<noscript> You need to enable JavaScript to run this app. </noscript>

<div id="root"></div>

</body>

</html>

Embora não seja possível fazer isso com `requests`, é possível fazer isso com um navegador headless. E isso responde a uma das nossas perguntas iniciais. Os web scrapers modernos usam navegadores sem cabeça em vez de pedidos porque, caso contrário, a resposta seria inconclusiva.

Quais são as desvantagens de um browser sem cabeça?

A principal desvantagem de um browser sem cabeça Python (e de todos os browsers automatizados) é a sua impressão digital. Se segues os meus artigos, sabes que por vezes falo de furtividade. Essa é a capacidade de um navegador automatizado não ser detectado.

E em Python, navegadores sem cabeça são facilmente distinguíveis. Para começar, verificar uma propriedade simples do navegador, como `navigator.webdriver `, é uma maneira instantânea de saber se um navegador é controlado por um driver web. No web scraping, um dos principais desafios é encontrar formas de evitar a deteção. Chamamos a estes métodos ou técnicas de evasão. Pode ler mais sobre isso aqui.

Na Web Scraping API, por exemplo, temos uma equipa dedicada a trabalhar constantemente no nosso Stealth Mode. Isto é para garantir que a impressão digital do nosso browser é única e indetetável em cada pedido.

Navegadores sem cabeça disponíveis com Python Selenium

Antes de tudo, saiba que o Selenium é muito poderoso. E nem sequer está limitado ao Python. Existem clientes Selenium e web drivers para C#, Ruby, Java, Python e até JavaScript. E o suporte do Selenium web driver é ainda mais impressionante. Ele suporta todos os principais navegadores:

No mundo do web scraping, os browsers Python headless mais utilizados são o Chrome e o Firefox. Penso que isso se deve principalmente ao facto de estes dois navegadores terem desempenho e serem multiplataforma. Pode, por exemplo, desenvolver o seu projeto de web scraping num ambiente MacOS e depois implementá-lo facilmente no Linux.

Como abrir um navegador sem cabeça em Python

Agora que cobrimos alguns conceitos teóricos, acho que é seguro ir em frente e explorar a parte prática. Nesta secção, vou mostrar como construir um web scraper com Selenium. Para este projeto, certifique-se de que a sua máquina está equipada com python e Chrome.

#1: Configurar o ambiente

Como de costume, em Python devemos encapsular tudo dentro de um ambiente virtual. Se não estás familiarizado com ambientes virtuais, lê isto primeiro. Agora vamos abrir uma nova janela de terminal e vamos:

  • Criar uma nova pasta
  • Navegar para a pasta
  • Criar um novo ambiente virtual
  • Ativar o ambiente virtual
~ mkdir headless_scraper

~ cd headless_scraper

~ python3 -m venv env

~ source env/bin/activate

#2: Instalar dependências

É bastante simples que precisamos do Selenium e de um driver web para o nosso projeto. Felizmente, podemos instalar ambos usando o gerenciador de pacotes do Pyhton, `pip`. Dentro da mesma janela de terminal, digite o seguinte comando:

~ pip install selenium webdriver-manager

Agora está tudo pronto para o sucesso! Podemos passar para a codificação propriamente dita. Aviso rápido: este artigo concentra-se na interação com um browser sem cabeça. Uma solução completa de web scraping requer muito mais esforço. Mas tenho certeza de que, se você seguir os posts do nosso blog, conseguirá fazer isso em pouco ou nenhum tempo.

#3: Abrir um browser automatizado

Até agora, temos o projeto, mas não há nenhum arquivo que possamos executar. Vamos criar um novo arquivo `.py` e abri-lo em nosso IDE:

~ touch headles_scraper.py

~ code .

Agora você deve estar dentro do Visual Studio Code ou do seu IDE. Você pode começar importando os pacotes necessários dentro do `handle_scraper.py`:

from selenium import webdriver

from webdriver_manager.chrome import ChromeDriverManager

Este último é um pacote que o ajuda a gerir facilmente os controladores Web para os diferentes navegadores suportados pelo Selenium. Você pode ler mais sobre ele aqui. Em seguida, queremos criar um novo navegador com o selenium e abrir um site:

driver = webdriver.Chrome(ChromeDriverManager().install())

driver.get('https://webscrapingapi.com')

Execute este arquivo agora e você verá que ele funciona. Mas em vez de usar um navegador sem cabeça Python, ele abre uma janela cheia de cabeça do Chrome:

imagem do blogue

#4: Tornar sem cabeça

Preparámo-nos para construir um raspador da Web de fácil utilização. Então, idealmente, queremos abrir um navegador sem cabeça com o Selenium. Felizmente, há um método fácil que podemos usar para mudar o Selenium de headful para headless. Nós só precisamos fazer uso das opções do driver web do Chrome. Então vamos importar `Options` e adicionar mais duas linhas de código:

...

from selenium.webdriver.chrome.options import Options

...

options = Options()

options.headless = True

driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)

driver.get('https://webscrapingapi.com')

Execute o script novamente. Como pode ver, desta vez não aparece nenhuma janela. Mas será que ele está realmente funcionando em segundo plano? Uma maneira rápida de visualizar e verificar isso é fazer uma captura de tela usando o Selenium. Basta adicionar esta linha no final do seu script:

driver.get_screenshot_as_file('headless.png')

Se tudo correu bem, deve ter a mesma imagem que eu:

imagem do blogue

#5: Adicionar capacidades de raspagem

O que é um Web scraper? Bem, na sua essência, um web scraper é um programa que chama um endpoint para um servidor e recolhe dados do mesmo. Nos sítios Web, estes dados consistem normalmente em ficheiros HTML. Mas, atualmente, alguns servidores também servem objectos JSON. Por isso, vamos cingir-nos a este termo: dados. Na secção seguinte, vamos elevar os nossos objectivos. Vamos utilizar um pouco de programação orientada para objectos! Os nossos objectivos são:

  • Criar uma classe Scraper
  • Adicionar um método para extrair dados em bruto
  • Adicionar um método para extrair dados de um único elemento
  • Adicionar um método para extrair dados de elementos da mesma classe

Portanto, temos três métodos básicos que queremos construir. No entanto, para efeitos de aprendizagem, estes três métodos estão a abrir um caminho não só para o web scraping, mas para a OOP com Python. E eu acho que isso é muito legal! Agora vamos remover tudo o que codificámos e vamos começar do zero:

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

from selenium.webdriver.common.by import By

from selenium.webdriver.remote.webelement import WebElement

class Scraper:

def __init__(self, headless: bool = True) -> None:

self.headless = headless

pass

def setup_scraper(self) -> None:

self.options = Options()

self.options.headless = self.headless

self.driver = webdriver.Chrome(options=self.options)

def navigate(self, target) -> None:

self.driver.get(target) if target else print('[!] No target given. Please specify a URL.')

def extract_raw_data(self) -> str:

return self.driver.page_source

def extract_single_element(self, seletor: str, selector_type: By = By.CSS_SELECTOR) -> WebElement:

return self.driver.find_element(selector_type, seletor)



def extract_all_elements(self, seletor: str, selector_type: By = By.CSS_SELECTOR) -> list[WebElement]:

return self.driver.find_elements(selector_type, seletor)

Eu adicionei anotações de tipo para facilitar a compreensão, em vez de desempenho. Dessa forma, é possível visualizar o aplicativo de uma perspetiva de E/S. Agora, os métodos são praticamente autoexplicativos. Não estamos executando nenhum tipo de ação nos dados, estamos apenas retornando-os. Se você quiser, isso pode ser um ponto de partida para construir um scraper complexo com um navegador Python headless.

Até agora, a execução do ficheiro não faz nada. Isso porque apenas declarámos o nosso Scraper e os seus métodos. Agora temos de os utilizar. Então vamos adicionar os seguintes trechos de código:

# Inicializa um novo Scraper e navega para um destino

scraper = Scraper()

scraper.setup_scraper()

scraper.navigate('https://httpbin.org')

# Extrai e imprime todo o documento HTML

raw_data = scraper.extract_raw_data()

print(raw_data)

# Extrai e imprime um elemento pelo seu nome de classe

single_element = scraper.extract_single_element('title', By.CLASS_NAME)

print(single_element.text)

# Extrair e imprimir todos os elementos pertencentes a um tipo de etiqueta

all_elements = scraper.extract_all_elements('a', By.TAG_NAME)

print([el.get_attribute('href') for el in all_elements])

E é isso. Se executar o seu script agora, poderá ver alguma ação a acontecer. Mais uma vez, este é apenas um protótipo concebido para o ajudar a começar. Se quiseres aprender mais sobre como um browser Python headless pode ser usado em web scraping, desafio-te a fazê-lo:

  1. Ler a documentação do Selenium
  2. Adicionar mais funcionalidades ao script que criámos hoje

Desta forma, poderá adquirir conhecimentos e acrescentar um projeto ao seu portfólio.

Quais são as melhores alternativas aos navegadores sem cabeça Python?

Python é uma das linguagens de programação mais populares para construir scrapers da Web. No entanto, não é a única solução. Nem é a melhor! Nesta secção, vamos discutir alternativas a um browser sem cabeça em Python. Começaremos por explicar porquê procurar soluções alternativas e veremos também exemplos específicos.

A principal razão pela qual se opta por uma alternativa à construção de um raspador web Python são os recursos. Uma solução completa de recolha de dados da Web exige que implemente um sistema de rotação de IP, algumas técnicas de evasão, uma conta de desempenho, e isto só para citar alguns exemplos. Assim, construir um raspador da Web não só é caro como também consome muito tempo. Para não mencionar que a manutenção da infraestrutura gera ainda mais custos.

A segunda desvantagem do navegador sem cabeça Python tem a ver com o desempenho. Embora Python seja uma ótima linguagem e seja muito fácil de usar, ela não é especificamente conhecida por sua velocidade. Ao contrário de Java, por exemplo (que também tem um pacote Selenium), Python é dinamicamente tipada e interpretada. Estas duas caraterísticas tornam-no muito mais lento quando comparado com outras linguagens. Agora que temos algum entendimento geral, vamos ser específicos. Aqui estão as 5 principais alternativas ao Selenium e ao navegador sem cabeça Python:

#1: API de raspagem da Web

Se quiser resolver o primeiro inconveniente que identificámos, então tem de procurar fornecedores de raspagem de terceiros. E a Web Scraping API possui um conjunto completo de scraping. Além disso, nosso serviço está repleto de recursos como:

  • Sistema de rotação de IP para proxies de centros de dados e residenciais
  • Modo furtivo
  • Solucionadores de Captcha

Estes três factores, por si só, tornam quase impossível que um alvo apanhe o nosso scraper e o bloqueie. E depois há as funcionalidades de raspagem. Com a Web Scraping API, é possível extrair dados com base em selectores, alternar entre tipos de dispositivos, tirar capturas de ecrã e muito mais. A lista completa de funcionalidades pode ser consultada aqui.

#2: Marionetista

O Puppeteer é o equivalente ao Selenium para JavaScript. É uma das bibliotecas mais usadas para automação web. Ao contrário do Selenium, o estado padrão do Puppeteer é headless. Portanto, não é necessário adicionar algum código extra para torná-lo headless. O que é ainda mais interessante é que existe também uma implementação da API do Puppeteer para Python. Você pode conferir este blog onde eu me aprofundo na construção de um web scraper com o Pyppeteer.

#3: Dramaturgo

O Playwright é outra ferramenta de automatização da Web desenvolvida pelos colaboradores da Microsoft. É popular principalmente porque oferece suporte para várias línguas e plataformas. O seu lema é, de facto, "Qualquer navegador, qualquer plataforma". A sua API pode ser acedida em qualquer sistema operativo e com qualquer uma das seguintes linguagens:

Estas são as principais alternativas para um navegador sem cabeça Python. Mas há também outras ferramentas disponíveis. ZombieJS ou HtmlUnit são apenas mais duas de uma lista de muitas. Acho que escolher uma tecnologia é tanto uma questão de desempenho quanto de preferência pessoal. Por isso, encorajo-o a testá-las todas e a escolher a sua favorita.

Conclusões

Usar um navegador sem cabeça Python tem seus prós e contras. Por um lado, é possível construir uma solução personalizada à qual se pode sempre acrescentar mais funcionalidades. Por outro lado, o desenvolvimento e a manutenção podem ser bastante caros. E há também a questão da invisibilidade. Se precisar de uma solução profissional, penso que é melhor optar por um fornecedor externo. Caso contrário, para efeitos de aprendizagem, encorajo-o sempre a brincar com a tecnologia.

Notícias e actualizações

Mantenha-se atualizado com os mais recentes guias e notícias sobre raspagem da Web, subscrevendo a nossa newsletter.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artigos relacionados

miniatura
GuiasAPI SERP Scraping - Guia de início

Recolha sem esforço dados em tempo real dos motores de busca utilizando a API SERP Scraping. Melhore a análise de mercado, SEO e pesquisa de tópicos com facilidade. Comece hoje mesmo!

WebscrapingAPI
avatar do autor
WebscrapingAPI
7 min. de leitura
miniatura
GuiasComo extrair dados de produtos da Amazon: Um guia abrangente de melhores práticas e ferramentas

Explore as complexidades da extração de dados de produtos da Amazon com nosso guia detalhado. De práticas recomendadas e ferramentas como a API Amazon Scraper a considerações legais, saiba como enfrentar desafios, contornar CAPTCHAs e extrair insights valiosos com eficiência.

Suciu Dan
avatar do autor
Suciu Dan
15 min. de leitura
miniatura
Ciência da recolha de dados da WebScrapy vs. Selenium: Um guia abrangente para escolher a melhor ferramenta de raspagem da Web

Explore a comparação aprofundada entre o Scrapy e o Selenium para raspagem da Web. Desde a aquisição de dados em grande escala até o tratamento de conteúdo dinâmico, descubra os prós, os contras e os recursos exclusivos de cada um. Saiba como escolher a melhor estrutura com base nas necessidades e na escala do seu projeto.

WebscrapingAPI
avatar do autor
WebscrapingAPI
14 min ler