Voltar ao blogue
Guias
Mihai MaximLast updated on Mar 31, 20265 min read

Como executar JavaScript com o Scrapy

Como executar JavaScript com o Scrapy

Introdução

Bem-vindo ao emocionante mundo da extração de dados de sites dinâmicos! Como deve saber pelos nossos artigos anteriores, este tipo de sites pode ser um pouco complicado de navegar com ferramentas tradicionais de extração de dados. Mas não se preocupe! O Scrapy, o seu fiel assistente de extração de dados, está aqui para o ajudar com uma variedade de plugins e bibliotecas que tornam a extração de dados de sites dinâmicos uma brisa.

Neste artigo, vamos aprofundar algumas das opções mais populares para extrair dados desses sites baseados em JavaScript com o Scrapy. E para tornar as coisas ainda mais fáceis, forneceremos exemplos de como usar cada uma delas, para que possa lidar com confiança com qualquer site que surgir no seu caminho.

Se é novo no Scrapy, não se preocupe. Pode consultar o nosso guia para uma introdução ao webscraping com o Scrapy

Se não está familiarizado com navegadores headless, deixe-me explicar. Essencialmente, são navegadores web que funcionam sem uma interface visível. Sim, eu sei que parece estranho não conseguir ver a janela do navegador quando o está a utilizar. Mas acredite em mim, os navegadores headless podem ser uma verdadeira revolução quando se trata de web scraping.

Eis o motivo: ao contrário dos navegadores normais que se limitam a apresentar páginas web, os navegadores headless conseguem executar JavaScript. Isto significa que, se estiver a tentar fazer web scraping num site que depende de JavaScript para gerar o seu conteúdo, um navegador headless pode ajudá-lo, executando o JavaScript e permitindo-lhe extrair o HTML resultante.

Explorar diferentes soluções

A melhor estratégia para renderizar JavaScript com o Scrapy depende das suas necessidades e recursos específicos. Se tiver um orçamento apertado, vai querer escolher uma solução que seja económica. Utilizar um navegador sem interface gráfica ou uma biblioteca de renderização de JavaScript pode ser a opção mais barata, mas ainda assim terá de lidar com a possibilidade de bloqueios de IP e com o custo de manutenção e execução da solução.

É sempre melhor experimentar algumas opções diferentes e ver qual funciona melhor para o seu caso de uso.

Como executar JavaScript com o Scrapy usando o Splash

O Splash é um navegador headless leve, concebido especificamente para web scraping. Baseia-se no motor WebKit, que é o mesmo motor que alimenta o navegador Safari. O grande vantagem do Splash é que é fácil de configurar, especialmente se utilizar o Docker. Também está integrado com o Scrapy através do middleware scrapy-splash.

Para utilizar o middleware, terá primeiro de instalar este pacote com o pip:

$ pip install scrapy-splash

Configurar o Splash com o Docker é fácil. Basta executar uma instância do Splash na sua máquina local utilizando o Docker (https://docs.docker.com/get-docker/).

$ docker run -p 8050:8050 scrapinghub/splash

Depois disso, deverá conseguir aceder à instância local do Splash em http://localhost:8050/

O Splash possui uma API REST que facilita a sua utilização com o Scrapy ou qualquer outra ferramenta de web scraping. Pode testar o servidor fazendo um pedido de recuperação dentro do shell do Scrapy:

fetch('http://localhost:8050/render.html?url=<target_url>')

Para configurar o Middleware, adicione as seguintes linhas ao seu ficheiro settings.py.

SPLASH_URL = 'http://localhost:8050'

DOWNLOADER_MIDDLEWARES = {

    'scrapy_splash.SplashCookiesMiddleware': 723,

    'scrapy_splash.SplashMiddleware': 725,

    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,

}

SPIDER_MIDDLEWARES = {

    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,

}

DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'

HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

Visite https://github.com/scrapy-plugins/scrapy-splash para saber mais sobre cada configuração.

A forma mais fácil de renderizar pedidos com o Splash é utilizar o scrapy_splash.SplashRequest dentro do seu spider:

import scrapy

from scrapy_splash import SplashRequest

class RandomSpider(scrapy.Spider):

    name = 'random_spider'

    def start_requests(self):

        start_urls = [

        '<first_url',

        '<second_url>'

       ]

        for url in start_urls:

           yield SplashRequest(url=url, callback=self.parse, args={'wait': 5})

    def parse(self, response):

       

            result = response.css("h3::text").extract()

         

            yield result

Pode adicionar um parâmetro «wait» para especificar o tempo que deseja que o Splash aguarde antes de devolver a sua solicitação.

Uma possível desvantagem de usar o Splash é que ele requer o uso da linguagem de script Lua para realizar ações como clicar em botões, preencher formulários e navegar para páginas.

Como executar Javascript com o Scrapy utilizando o Selenium

Pode utilizar o Scrapy com o Selenium WebDriver. O middleware scrapy-selenium funciona injetando o Selenium WebDriver no processo de solicitação, de modo que o HTML resultante seja devolvido ao spider para análise.

Antes de implementar esta solução, é importante notar que terá de instalar um webdriver para interagir com um navegador. Por exemplo, terá de instalar o geckodriver para utilizar o Firefox com o Selenium. Depois de ter um webdriver instalado, pode configurar o Selenium nas definições do seu projeto Scrapy:

SELENIUM_DRIVER_NAME = 'firefox'

SELENIUM_DRIVER_EXECUTABLE_PATH = which('geckodriver')

SELENIUM_DRIVER_ARGUMENTS=['-headless']  # '--headless' if using chrome instead of firefox

DOWNLOADER_MIDDLEWARES = {

    'scrapy_selenium.SeleniumMiddleware': 800

}

ITEM_PIPELINES = {

    'myproject.pipelines.SanitizePipeline': 1,

}

Em seguida, pode configurar o seu spider:

import scrapy

from scrapy_selenium import SeleniumRequest

class RandomSpider(scrapy.Spider):

    name = 'random_spider'

    def start_requests(self):

        start_urls = [

        '<first_url',

        '<second_url>'

       ]

        for url in start_urls:

            yield SeleniumRequest(url=url, callback=self.parse)

    def parse(self, response):

            print(response.request.meta['driver'].title)

            #The request will be handled by selenium, and the request will have an additional meta key, named driver containing the selenium driver with the request processed.

       

            result = response.selector.css("#result::text").extract()

            #The selector response attribute work as usual (but contains the  html processed by the selenium driver).

         

            yield result

Para mais informações sobre os métodos e atributos de driver disponíveis, consulte a documentação do Selenium Python:

http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webdriver

O Selenium requer que um navegador web esteja instalado na máquina onde está a ser executado, uma vez que não é um navegador headless autónomo. Isto torna mais difícil a sua implementação e execução em várias máquinas ou num ambiente de nuvem.

Como executar JavaScript com o Scrapy utilizando a WebScrapingApi

O WebScrapingAPI fornece uma API que tratará de todo o trabalho pesado por si. Pode executar JavaScript, alternar proxies e até lidar com CAPTCHAs, garantindo que pode extrair dados de sites com facilidade. Além disso, nunca terá de se preocupar com o bloqueio do seu IP por enviar demasiados pedidos. Para configurar o Scrapy para funcionar com a WebScrapingAPI, vamos configurar um middleware de proxy que encaminhará todos os pedidos de recuperação através da WSA.

Para tal, vamos configurar o Scrapy para se ligar ao servidor proxy WSA:

import base64

# add this to your middlewares.py file

class WSAProxyMiddleware:

    def process_request(self, request, spider):

        # Set the proxy for the request

        request.meta['proxy'] = "http://proxy.webscrapingapi.com:80"

        request.meta['verify'] = False

        # Set the proxy authentication for the request

        proxy_user_pass = "webscrapingapi.render_js=1:<API_KEY>"

        encoded_user_pass = base64.b64encode(proxy_user_pass.encode()).decode()

        request.headers['Proxy-Authorization'] = f'Basic {encoded_user_pass}'

E ativar o middleware:

DOWNLOADER_MIDDLEWARES = {

    'myproject.middlewares.WSAProxyMiddleware': 1,

}

webscrapingapi.render_js=1 é o nome de utilizador de autenticação do proxy, <API_KEY> a palavra-passe.

Pode obter uma API_KEY gratuita criando uma nova conta em https://www.webscrapingapi.com/

Ao especificar o parâmetro render_js=1, ativará a capacidade do WebScrapingAPI de aceder à página web alvo utilizando um navegador headless, o que permite que os elementos JavaScript da página sejam renderizados antes de lhe entregar o resultado final da extração.

Também pode instruir o WSA a realizar uma ação específica ao processar a sua URL. Pode fazê-lo especificando o parâmetro js_instructions:

js_instructions=[

{"action":"click","selector":"button#log-in-button"}

]

// esta sequência pode ser utilizada para clicar num botão

E é isso, o WSA irá agora efetuar automaticamente todos os pedidos por si.

Conclusão

Extrair dados de sites dinâmicos pode ser uma tarefa difícil, mas com as ferramentas certas, torna-se muito mais fácil de gerir. Neste artigo, analisámos três opções diferentes para extrair dados de sites dinâmicos com o Scrapy. Navegadores headless como o Splash e o Selenium permitem-lhe executar JavaScript e renderizar páginas web tal como um navegador normal. No entanto, se quiser seguir o caminho mais fácil, utilizar uma API como a WebScrapingApi também pode ser uma ótima solução. Ela trata de todas as tarefas complexas por si e permite-lhe extrair facilmente dados mesmo dos sites mais difíceis. Independentemente da opção que escolher, é importante considerar as suas necessidades específicas e escolher a solução que melhor se adapta ao seu projeto. Obrigado pela leitura e boas extrações!

Sobre o autor
Mihai Maxim, Desenvolvedor Full Stack @ WebScrapingAPI
Mihai MaximDesenvolvedor Full Stack

Mihai Maxim é um programador Full Stack na WebScrapingAPI, contribuindo em todas as áreas do produto e ajudando a criar ferramentas e funcionalidades fiáveis para a plataforma.

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.