Node.js, Tor, Puppeteer e Cheerio: raspagem anônima da web

A raspagem da Web é um método de coleta de dados de sites. Esse termo é comumente usado em relação à coleta automatizada de dados. Hoje falaremos sobre como coletar dados de sites anonimamente. A razão pela qual alguém pode querer anonimato na raspagem da Web é porque muitos servidores da Web aplicam certas regras às conexões dos endereços IP, a partir das quais um certo número de solicitações é feito durante um certo período de tempo. Aqui vamos usar as seguintes ferramentas:

  • Titereiro - para acessar páginas da web.
  • Cheerio - para analisar o código HTML.
  • Tor - para executar cada solicitação de um endereço IP diferente.

Deve-se notar que os aspectos legais da raspagem da Web são uma questão complexa e muitas vezes pouco clara. Portanto, respeite os " Termos de uso " das páginas cujos dados você coleta. Aqui está um bom material sobre este tópico.



Instalação do Tor


Vamos começar do começo - portanto, antes de tudo, instale o cliente Tor usando o seguinte comando:

sudo apt-get install tor

Configuração do Tor


Agora configure o cliente Tor. A configuração padrão do Tor usa a porta SOCKS , que fornece um caminho para um único nó de saída (ou seja, um endereço IP). Para o uso diário do Tor, como apenas navegar na web, este é um bom ajuste. Mas precisamos de alguns endereços IP. Isso permitirá que você alterne entre eles durante o processo de raspagem da web.

Para configurar o Tor conforme necessário, simplesmente abrimos portas adicionais para ouvir as conexões do SOCKS. Isso é feito adicionando várias entradas SocksPortao arquivo de configuração principal do programa, que pode ser encontrado em /etc/tor.

Abra o arquivo /etc/tor/torrcusando algum editor de texto e adicione as seguintes entradas ao final do arquivo:

#  4 SOCKS-,       Tor-.

SocksPort 9050
SocksPort 9052
SocksPort 9053
SocksPort 9054

Aqui vale a pena prestar atenção ao seguinte:

  • SocksPort . — , , SOCKS, .
  • SocksPort , , , - .
  • 9050 — , Tor- .
  • 9051. Tor , , , Tor.
  • 9051, , 1.

Para aplicar as alterações feitas no arquivo de configuração, reinicie o cliente Tor:

sudo /etc/init.d/tor restart

Criando um novo projeto Node.js.


Crie um novo diretório para o projeto. Vamos chamá-la superWebScraping:

mkdir superWebScraping

Vamos para este diretório e inicialize um projeto Node vazio:

cd superWebScraping && npm init -y

Defina as dependências necessárias:

npm i --save puppeteer cheerio

Trabalhar com sites usando o Puppeteer


O Puppeteer é um navegador sem uma interface de usuário que usa o protocolo DevTools para interagir com o Chrome ou o Chromium . A razão pela qual não usamos uma biblioteca aqui para trabalhar com solicitações, como tor-request , é porque essa biblioteca não poderá processar sites criados como aplicativos da Web de página única, cujo conteúdo é carregado dinamicamente.

Crie um arquivo index.jse coloque o seguinte código nele. Os principais recursos deste código estão descritos nos comentários.

/**
 *   puppeteer.
 */
const puppeteer = require('puppeteer');

/**
 *   main  , 
 *     -.
 * ,      ,
 *   ,     
 *  puppeteer.
 */
async function main() {
  /**
   *  Chromium.   `headless`   false,
   *     .
   */
  const browser = await puppeteer.launch({
    headless: false
  });

  /**
   *   .
   */
  const page = await browser.newPage();

  /**
   *   ,   https://api.ipify.org.
   */
  await page.goto('https://api.ipify.org');

  /**
   *  3     .
   */
  setTimeout(() => {
    browser.close();
  }, 3000);
}

/**
 *  ,  main().
 */
main();

Execute o script com o seguinte comando:

node index.js

Depois disso, a janela do navegador Chromium deve aparecer na tela em que o endereço está aberto https://api.ipify.org.


Janela do navegador, a conexão Tor não é usada.

Abri-a na janela do navegador exatamentehttps://api.ipify.orgporque esta página pode mostrar o endereço IP público a partir do qual é acessado. Este é o endereço visível para os sites que eu visito se os visitar sem usar o Tor.

Altere o código acima adicionando a seguinte chave ao objeto com os parâmetros passadospuppeteer.launch:

  /**
   *  Chromium.   `headless`  false,
   *     .
   */
  const browser = await puppeteer.launch({
  headless: false,
  
  //   .
  args: ['--proxy-server=socks5://127.0.0.1:9050']
});

Passamos uma discussão para o navegador --proxy-server. O valor desse argumento informa ao navegador que ele deve usar um servidor proxy socks5 em execução no nosso computador e acessível na porta 9050. O número da porta é um daqueles números que inserimos anteriormente no arquivo torrc.

Execute o script novamente:

node index.js

Desta vez, na página aberta, você pode ver um endereço IP diferente. Este é o endereço usado para visualizar o site através da rede Tor.


Janela do navegador, a conexão Tor é usada.

No meu caso, um endereço apareceu nessa janela144.217.7.33. Você pode ter outro endereço. Observe que, se você executar o script novamente e usar o mesmo número de porta (9050), receberá o mesmo endereço IP que você recebeu anteriormente.


Relançada a janela do navegador, a conexão Tor é usada.

É por isso que nas configurações do Tor abrimos várias portas. Tente conectar seu navegador a uma porta diferente. Isso mudará o endereço IP.

Coleta de dados com Cheerio


Agora que temos um mecanismo conveniente para carregar páginas, é hora de fazer a raspagem na web. Para isso, vamos usar a biblioteca cheerio . Este é um analisador de HTML cuja API é construída da mesma maneira que a API do jQuery . Nosso objetivo é obter 5 das últimas postagens na página de Notícias do Hacker.

Acesse o site do Hacker News .


Site do Hacker News

Queremos receber cinco novas manchetes da página aberta (agora é HAKMEM (1972), Larry Roberts morreu, entre outros). Examinando o título do artigo usando as ferramentas de desenvolvedor do navegador, notei que cada título é colocado em um elemento HTML<a>com uma classestorylink.


Estudo da estrutura do documento

Para extrair o que precisamos do código HTML da página, precisamos executar a seguinte sequência de ações:

  • Iniciando uma nova instância do navegador sem uma interface de usuário conectada ao proxy Tor.
  • Crie uma nova página.
  • Vá para o endereço https://news.ycombinator.com/.
  • Recuperando o conteúdo HTML da página.
  • Carregando o conteúdo HTML da página em cheerio.
  • Criando uma matriz para salvar os títulos dos artigos.
  • Acessando elementos com uma classe storylink.
  • Obtendo os 5 primeiros elementos usando o método cheerio slice () .
  • Atravessando os elementos resultantes usando o método cheerio each () .
  • Escreva cada cabeçalho encontrado em uma matriz.

Aqui está o código que implementa essas ações:

const puppeteer = require('puppeteer');

/**
 *   cheerio.
 */
const cheerio = require('cheerio');

async function main() {
  const browser = await puppeteer.launch({
    /**
     *       (   ).
     */
    headless: true,
    args: ['--proxy-server=socks5://127.0.0.1:9050']
  });

  const page = await browser.newPage();

  await page.goto('https://news.ycombinator.com/');

  /**
   *      HTML-.
   */
  const content = await page.content();

  /**
   *    cheerio.
   */
  const $ = cheerio.load(content);


  /**
   *      .
   */
  const titles = [];

  /**
   *   ,   `storylink`.
   *  slice()      5   .
   *      each().
   */
  $('.storylink').slice(0, 5).each((idx, elem) => {
    /**
     *   HTML-,   .
     */
    const title = $(elem).text();
  
    /**
     *    .
     */
    titles.push(title);
  })

  browser.close();
  
  /**
   *     .
   */
  console.log(titles);
}

main();

Aqui está o que acontece depois de executar este script.


Primeiras 5 notícias de hackers extraídas com sucesso do código da página

Raspagem contínua usando diferentes endereços IP


Agora vamos falar sobre como usar as várias portas SOCKS que especificamos no arquivo torrc. É bem simples. Declararemos uma matriz, cada uma contendo um número de porta. Em seguida, renomeie a função main()para uma função scrape()e declare uma nova função main()que a chamará scrape(), passando um novo número de porta a cada chamada.

Aqui está o código finalizado:

const puppeteer = require('puppeteer');
const cheerio = require('cheerio');

async function scrape(port) {
  const browser = await puppeteer.launch({
    args: ['--proxy-server=socks5://127.0.0.1:' + port]
  });

  const page = await browser.newPage();
  await page.goto('https://news.ycombinator.com/');
  const content = await page.content();

  const $ = cheerio.load(content);

  const titles = [];

  $('.storylink').slice(0, 5).each((idx, elem) => {
    const title = $(elem).text();
    titles.push(title);
  });

  browser.close();
  return titles;
}

async function main() {
  /**
   *  SOCKS- Tor,    torrc. 
   */
  const ports = [
    '9050',
    '9052',
    '9053',
    '9054'
  ];
  
  /**
   *  -...
   */
  while (true) {
    for (const port of ports) {
      /**
       * ...  -    .
       */
      console.log(await scrape(port));
    }
  }
}

main();

Sumário


Agora você tem ferramentas à sua disposição que permitem fazer raspagem anônima na web.

Queridos leitores! Você já fez raspagem na web? Nesse caso, informe-nos quais ferramentas você usa para isso.

Source: https://habr.com/ru/post/undefined/


All Articles