Raspagem da Web com o NODRIVER em 2025

Domine a raspagem da Web com o NODRIVER. Este guia aborda a configuração, os principais recursos e os métodos para otimizar seus fluxos de trabalho de extração de dados.
11 min de leitura
web scraping with NODRIVER blog image

Durante anos, o Undetected Chromedriver foi um elemento básico da navegação segura e do desvio de antibot. Desde então, o desenvolvedor por trás do Undetected Chromedriver criou o NODRIVER. Com o NODRIVER, você não depende mais do Selenium ou do Webdriver. Basta instalar o pip e tudo estará pronto para funcionar.

Neste guia, você aprenderá:

  • O que é NODRIVER?
  • Qual é a diferença em relação a outros navegadores sem cabeça?
  • Como usar o NODRIVER?
  • Quais são as limitações do NODRIVER?
  • Como usar o NODRIVER com um proxy?
  • Alternativas sólidas ao NODRIVER

O que é o NODRIVER e por que você deve se importar?

O que é exatamente o NODRIVER?

O NODRIVER é o sucessor totalmente assíncrono do Undetected Chromedriver. Usando as “práticas recomendadas” como padrão para todos os kwargs, ele foi projetado para funcionar imediatamente com apenas uma pequena quantidade de código.

O NODRIVER apresenta os seguintes recursos:

  • Desempenho
  • Sem dependências externas (nem mesmo o Chromedriver)
  • Contorno do Antibot
  • Cookies persistentes de sessão
  • Nova instância do navegador a cada uso

O que torna o NODRIVER diferente?

O NODRIVER usa uma arquitetura radicalmente diferente do Undetected Chromedriver e até mesmo de outros navegadores sem cabeça. Tradicionalmente, esses outros navegadores dependem do Selenium ou do Chrome DevTools Protocol (CDP).

O NODRIVER usa sua própria implementação personalizada do protocolo DevTools. Na documentação, ele é chamado de “biblioteca de automação chrome (-ish)”. Com o NODRIVER, você não depende do Selenium, nem depende diretamente do CDP. O NODRIVER usa uma implementação personalizada do CDP. Para usar o NODRIVER, tudo o que você precisa é do pip e de um navegador baseado no Chrome.

Raspagem com o NODRIVER

1. Primeiros passos

Antes de começar, você precisa ter certeza de que tem o Python e um navegador instalados. Se estiver lendo este artigo, presumo que já os tenha instalado. Você pode instalar o NODRIVER diretamente com o pip.

pip install nodriver

2. Estrutura básica

Nossa estrutura básica é realmente semelhante à que você obteria com o Playwright ou o Puppeteer. Se estiver interessado em usar o Playwright em Python, você pode ver um guia completo sobre a extração de listagens da Amazon aqui. O NODRIVER tem uma sensação muito semelhante à do Playwright, mas ainda está em desenvolvimento intenso.

Esta é a nossa estrutura básica.

import nodriver

async def main():
    #start the browser
    browser = await nodriver.start()

    base_url = "https://quotes.toscrape.com"

    #navigate to a page
    page = await browser.get(base_url)

    ###logic goes here###

    #close the browser
    await page.close()

if __name__ == '__main__':

    #in their docs, they advise directly against asyncio.run()
    nodriver.loop().run_until_complete(main())

3. Obtendo uma página

Como você provavelmente notou em nosso esqueleto básico acima, browser.get() retorna um objeto de página. Você pode até mesmo abrir várias páginas simultaneamente. Se você estiver disposto a ser criativo, poderá fazer operações altamente simultâneas.

O trecho abaixo é apenas teórico.

#navigate to a page
page_1 = await browser.get(base_url)
page_2 = await browser.get(a_different_url)

####do stuff with the different pages#####

4. Conteúdo dinâmico

Para lidar com o conteúdo dinâmico, você tem duas opções. Você pode usar o método .sleep() para esperar um período de tempo arbitrário ou pode usar .wait_for() para esperar por um seletor específico na página.

#wait an arbitrary amount of time
await tab.sleep(1)

#wait for a specific element
await tab.wait_for("div[data-testid='some-value']")

NOTA: No snippet acima, usei tab em vez de page como nome de variável. Elas são intercambiáveis. Ambos são objetos de guia. Você pode saber mais sobre as guias no NODRIVER aqui.

5. Encontrando elementos

O NODRIVER nos fornece uma variedade de métodos para localizar elementos na página. Parece que eles estão lidando com alguns métodos antigos.

Há quatro métodos diferentes baseados em texto para localizar elementos. Dois deles provavelmente desaparecerão no futuro.

#find an element using its text
my_element = page.find("some text here")

#find a list of elements by their text
my_elements = page.find_all("some text here")

#find an element using its text
my_element = page.find_element_by_text("some text here")

#find a list of elements using their text
my_elements = page.find_element_by_text("some text here")

Assim como os métodos acima, há também quatro métodos baseados em seletores para localizar elementos. Dois deles provavelmente desaparecerão. Se os desenvolvedores do NODRIVER quiserem se alinhar claramente com o CDP, os métodos query_selector provavelmente sobreviverão.

#find a single element using its css selector
my_element = page.select("div[class='your-classname']")

#find a list of elements using a css selector
my_elements = page.select_all("div[class='your-classname']") 

#find a single element using its css selector
my_element = page.query_selector("div[class='your-classname']")

#find a list of elements using a css selector
my_elements = page.query_selector_all("div[class='your-classname']") 

Como você pode ver acima, não importa como você queira encontrar elementos na página, provavelmente há várias maneiras de fazer isso. Com o tempo, os desenvolvedores por trás do NODRIVER poderão melhorar isso. Dito isso, no momento, seus métodos de análise são como uma motosserra do exército suíço.

6. Extração de seus dados

O NODRIVER oferece alguns métodos para extrair dados. Você pode usar a característica .attributes para extrair atributos diretamente. Isso não é muito fácil de usar, pois retorna uma matriz, não um objeto JSON.

Aqui está uma solução improvisada que criei para extrair o href de um objeto de link. É feio, mas funciona. Espero que o método de atributos seja substituído em breve por algo um pouco mais funcional.

next_button = await page.select("li[class='next'] > a")

#this returns an array
attributes = next_button.attributes

#use array indexing to find the href object and its value
for i in range(len(attributes)):
    if attributes[i] == "href":
        next_url = attributes[i+1]

OBSERVAÇÃO: a maioria dos outros navegadores sem cabeça contém um método get_attribute(). No entanto, esse método ainda não está funcionando no NODRIVER.

Veja como extraímos os dados de texto. Como você pode notar, não usamos o await aqui. Suspeito que isso mudará no futuro para se alinhar com outros navegadores de estilo CDP. Em sua forma atual, o texto é apenas um atributo, não um método – o await, na verdade, gera um erro quando usado com atributos. Isso parece contrário ao Puppeteer e ao Playwright, mas esse é o estado atual do NODRIVER – ainda em desenvolvimento intenso.

#find the quote element
quote_element = await quote.query_selector("span[class='text']")
#extract its text
quote_text = quote_element.text

7. Armazenamento de dados

Armazenaremos nossos dados em um pequeno arquivo JSON. Ao extrair citações, cada uma delas tem uma lista de tags, e as listas não se saem muito bem no formato CSV.

import json

with open("quotes.json", "w", encoding="utf-8") as f:
    json.dump(scraped_data, f, ensure_ascii=False, indent=4)

8. Colocando tudo junto

Agora, vamos reunir todos esses conceitos em um script funcional. No exemplo abaixo, usamos os conceitos acima para extrair dados do Qutoes to Scrape – um site criado apenas para tutoriais de raspagem. Copie e cole o código abaixo para ter uma ideia de como o NODRIVER realmente funciona.

import nodriver
import json

async def main():

    #list to hold scraped data
    scraped_data = []


    browser = await nodriver.start()

    next_url = "/"

    base_url = "https://quotes.toscrape.com"

    #while we still have urls to scrape
    while next_url:

        #go to the page
        page = await browser.get(f"{base_url}{next_url}")

        #find quote divs using a selector
        quotes = await page.select_all("div[class='quote']")

        #iterate through the quotes
        for quote in quotes:

            #find the quote element and extract its text
            quote_element = await quote.query_selector("span[class='text']")
            quote_text = quote_element.text

            #find the author and extract the text
            author_element = await quote.query_selector("small[class='author']")
            author = author_element.text

            #find the tag elements
            tag_elements = await quote.query_selector_all("a[class='tag']")
            tags = []

            #iterate through the tags and extract their text
            for tag_element in tag_elements:
                text = tag_element.text
                tags.append(text)

            #add our extracted data to the list of scraped data
            scraped_data.append({
                "quote": quote_text,
                "author": author,
                "tags": tags
            })

        #check the page for a "next" button
        next_button = await page.select("li[class='next'] > a")

        #if it doesn't exist, close the browser and break the loop
        if next_button == None:
            await page.close()
            next_url = None

        #if it does, follow this block instead
        else:
            attributes = next_button.attributes

            #loop through the attributes to find your desired attribute, its value is the next index
            for i in range(len(attributes)):
                if attributes[i] == "href":
                    next_url = attributes[i+1]

    #write the data to a json file
    with open("quotes.json", "w", encoding="utf-8") as f:
        json.dump(scraped_data, f, ensure_ascii=False, indent=4)


if __name__ == '__main__':

    nodriver.loop().run_until_complete(main())

Se você executar o script acima, obterá um arquivo JSON com objetos como o que você vê abaixo.

[
    {
        "quote": "“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”",
        "author": "Albert Einstein",
        "tags": [
            "change",
            "deep-thoughts",
            "thinking",
            "world"
        ]
    },
    {
        "quote": "“It is our choices, Harry, that show what we truly are, far more than our abilities.”",
        "author": "J.K. Rowling",
        "tags": [
            "abilities",
            "choices"
        ]
    },

Limitações atuais do NODRIVER

Atualmente, o NODRIVER tem algumas limitações sérias que merecem ser observadas. Vamos examiná-las.

Modo sem cabeça

O NODRIVER gera um erro sempre que o executamos no modo headless. Não temos certeza se isso é intencional (como um desvio antibot) ou um problema legítimo.

Um rastreamento de erro Python exibido em uma janela de terminal, indicando um erro de profundidade máxima de recursão excedida em um script Nodriver, com caminhos de arquivo e números de linha referenciados. O erro sugere problemas com a preparação de uma sessão sem cabeça e o envio de uma solicitação única.

Interações de páginas

Embora o NODRIVER tenha várias interações de página listadas em seus documentos, a maioria delas funciona parcialmente ou não funciona. Como você pode ver, isso está documentado na captura de tela abaixo, tanto para click_mouse() quanto para mouse_click().

Trecho de código que mostra os parâmetros e o uso das funções assíncronas mouse_click e click_mouse, incluindo detalhes sobre a seleção de botões, teclas modificadoras e um evento interno para espera.

Extração de atributos

O maior problema do NODRIVER é a extração de atributos. Como mencionado anteriormente, isso gera uma matriz e é extremamente arcaico, como você viu em nossa solução alternativa de href. Aqui está a saída literal do atributo. Para a raspagem em nível de produção, isso precisa ser resolvido.

Um trecho de código que mostra um atributo de hiperlink com o valor '/page/2/' em um formato de matriz.

Uso de proxy com o NODRIVER

Atualmente, o suporte a proxy do NODRIVER é limitado. Eles fornecem um método create_context() para conexão proxy.

O trecho abaixo vem diretamente da página de problemas deles. No entanto, depois de horas tentando esse e vários outros métodos, ainda não consegui me conectar.

tab = await  browser.create_context("https://www.google.nl", proxy_server='socks5://myuser:mypass@somehost')

# or add  new_window=True if you would like a new window

Se você observar a documentação, há uma seção sobre proxies[1]. Embora haja uma seção oficial de proxy, não há documentação real. Presumimos que isso será corrigido em um futuro próximo.

Alternativas viáveis

Embora não esteja pronto para uso em produção no momento, espero que o NODRIVER faça grandes coisas no futuro. Se estiver procurando por algo mais pesado, dê uma olhada nos navegadores abaixo.

  • Selênio: Forte desde 2004. O Selenium depende do Chromedriver, mas é testado em batalha e está pronto para a produção. Saiba mais sobre o Selenium web scraping.
  • Playwright: O Playwright parece uma versão polida e pronta para uso do que você viu neste tutorial com o NODRIVER. Saiba como usar o Playwright para raspagem da Web.

Conclusão

O NODRIVER é uma ferramenta nova e interessante para automação do navegador, mas o rápido desenvolvimento significa que alguns recursos ainda estão amadurecendo. Para obter uma raspagem da Web confiável e em grande escala, considere o uso de soluções robustas como:

Inscreva-se para uma avaliação gratuita e comece hoje mesmo!

Não é necessário cartão de crédito