Ir para o conteúdo

Como raspar a pesquisa Algolia

Aqui está uma postagem de blog com mais de 2000 palavras sobre "Como raspar a pesquisa Algolia":

Introdução

Algolia é uma API de pesquisa popular que potencializa a funcionalidade de pesquisa de muitos sites na Internet. Ele permite que os sites implementem pesquisas rápidas e relevantes sem a necessidade de executar eles próprios uma infraestrutura de pesquisa complexa.

Alguns exemplos de sites populares que usam Algolia incluem:

  • Reddit
  • Médio
  • GitHub
  • StackOverflow
  • Hacker News

O objetivo deste post é explicar:

  1. O que é Algolia e como funciona
  2. Como raspar os resultados da pesquisa Algolia usando Python
  3. Técnicas para destruir Algolia de forma eficiente e em grande escala
  4. Como evitar ser bloqueado ao raspar Algolia

Ao final, você entenderá como construir um web scraper Algolia escalável para qualquer site que o utilize.

O que é Algolia?

Algolia é uma API de pesquisa hospedada que fornece serviços como indexação, pesquisa e recomendações. Muitas vezes é chamado de provedor de pesquisa como serviço (SaaS).

As principais propostas de valor da Algolia incluem:

  • Pesquisa rápida – Algolia afirma ser capaz de pesquisar bilhões de registros em menos de 100 ms. Isso é muito mais rápido do que fazer pesquisas em sua própria infraestrutura.

  • Pesquisa relevante – Algolia lida com coisas como tolerância a erros de digitação, sinônimos e aprendizado com base no comportamento do usuário para retornar os resultados mais relevantes.

  • Serviço hospedado – Algolia cuida de coisas como escalonamento e redundância. Não há infraestrutura para você gerenciar.

  • Acesso à API – A funcionalidade de pesquisa pode ser acessada via API que permite fácil integração em sites, aplicativos móveis, etc.

Algolia fornece bibliotecas clientes para a maioria das principais linguagens e estruturas que lidam com a comunicação API. No front-end, os desenvolvedores adicionam código JavaScript para fazer interface com a API da Algolia.

Resumindo, Algolia fornece pesquisa hospedada e escalável via API. Isso permite que os sites criem ótimas pesquisas rapidamente, sem a necessidade de construir eles próprios sistemas complexos.

Raspando Pesquisa Algolia com Python

Agora que entendemos o que é Algolia, vamos ver como podemos extrair os resultados da pesquisa Algolia usando Python.

Scraping Algolia é simples, pois a API é pública e documentada. Nós simplesmente precisamos:

  1. Identifique o endpoint e os parâmetros da API
  2. Extraia todas as chaves de acesso
  3. Envie solicitações de pesquisa e analise a resposta JSON

Vejamos um exemplo completo de raspagem de um site baseado em Algolia.

Encontrando o endpoint da API

Primeiro, precisamos encontrar o endpoint da API usado pelo site para pesquisa. A maneira mais fácil é abrir o site no seu navegador, executar uma consulta de pesquisa e verificar as solicitações de rede nas ferramentas do desenvolvedor.

Por exemplo, em Hacker News vemos uma solicitação feita para:

https://hn.algolia.com/api/v1/search?query=python

A /api/v1/search path revela que esta é a API de pesquisa Algolia. Também vemos o termo de pesquisa python passado como parâmetro de consulta.

Ao verificar a resposta, podemos ver que ela retorna JSON com os resultados. Agora sabemos o endpoint da API e o parâmetro de pesquisa a ser usado.

Obtendo as chaves de API

Em seguida, precisamos obter a chave API necessária para autenticação. Verificando novamente a solicitação de rede, podemos ver que ela passou pelo X-Algolia-API-Key cabeçalho.

Podemos extrair essa chave de API e adicioná-la às nossas solicitações. Alguma engenharia reversa adicional pode ser necessária se a chave for ofuscada em JavaScript.

Fazendo solicitações de pesquisa

Com o endpoint e a chave API, agora podemos fazer solicitações de pesquisa em Python:

import requests 

api_key = "abc123" # Extracted key 

search_url = "https://hn.algolia.com/api/v1/search"

params = {
  ‘query‘: ‘python‘,
  ‘hitsPerPage‘: 100, 
  ‘attributesToSnippet‘: [‘title:10‘]
}

headers = {
  "X-Algolia-API-Key": api_key
}

response = requests.get(search_url, params=params, headers=headers)
data = response.json()

print(data[‘hits‘])

Fazemos uma solicitação GET ao endpoint da API, passando nosso termo de pesquisa, resultados por página e o cabeçalho da chave da API. O resultado contém os resultados da pesquisa como JSON que podemos analisar e processar conforme necessário.

E agora temos um raspador Algolia básico!

Raspar páginas adicionais

Uma limitação é que a API retorna apenas a primeira página de resultados. Para obter páginas adicionais, precisamos passar o page parâmetro incrementando de 0:

# First page
params[‘page‘] = 0 

# Second page
params[‘page‘] = 1 

# Third page
params[‘page‘] = 2

Para raspar todas as páginas, podemos fazer solicitações aumentando o número da página até que nenhum outro resultado seja retornado.

Juntando isso:

from typing import Iterator

def scrape_search(search_term: str) -> Iterator[dict]:

  params = {
    ‘query‘: search_term,
    ‘hitsPerPage‘: 100,
  }

  page = 0
  while True:
    params[‘page‘] = page
    resp = requests.get(search_url, params=params, headers=headers)
    data = resp.json()

    if not data[‘hits‘]:
      break

    yield from data[‘hits‘]

    page += 1

Isso itera nas páginas e produz todos os resultados.

Para coletar todos os resultados:

results = []

for result in scrape_search("python"):
  results.append(result)

print(len(results))

E agora temos um paginador completo para raspar todos os resultados de pesquisa do Algolia!

Raspando Algolia em escala

O raspador básico acima funciona, mas não está otimizado para raspagem em grande escala. Problemas que você pode encontrar:

  • Devagar – Solicitações síncronas tornam lenta a raspagem de centenas de páginas.
  • Frágil – Uma falha interrompe todo o processo de raspagem.
  • banido – A extração de um IP corre o risco de ser bloqueada.

Vejamos como resolver esses problemas para uma raspagem robusta em grande escala.

Solicitações assíncronas

Para acelerar a raspagem, podemos aproveitar solicitações assíncronas. Isso nos permite ter muitas solicitações em andamento simultaneamente.

Por exemplo com o asyncio módulo:

import asyncio

async def fetch_page(page):
  params[‘page‘] = page
  resp = await asyncio.to_thread(requests.get, search_url, params=params) 
  return resp.json()

async def async_scrape():
  page = 0 
  while True:
    tasks = [asyncio.create_task(fetch_page(page + i)) for i in range(10)]
    results = await asyncio.gather(*tasks)

    for data in results:
      if not data[‘hits‘]:
        return

      for hit in data[‘hits‘]:
        yield hit

    page += 10

pages = async_scrape()  

Isso busca 10 páginas simultaneamente em cada iteração. Com solicitações assíncronas, o raspador é muito mais rápido.

Novas tentativas e tolerância a falhas

As solicitações de rede estão sujeitas a falhas intermitentes. Podemos adicionar novas tentativas para lidar com erros normalmente:

from time import sleep

async def fetch_page(page):

  for retry in range(3):

    try:
      return await asyncio.to_thread(requests.get, search_url, params=params) 
    except Exception as e:
      print(f"Error: {e}, retrying")
      sleep(1)

  print(f"Failed to fetch page {page} after {retries} retries")
  return {‘hits‘: []} # Return empty result

Isso simplesmente tenta até 3 vezes em qualquer falha. Outras melhorias, como a espera exponencial, também poderiam ser adicionadas.

Para maior resiliência, podemos agrupar o loop geral de raspagem em uma tentativa/exceto e tentar novamente em caso de falhas inesperadas.

Com novas tentativas em vários níveis, o raspador pode se recuperar de diversas falhas e continuar funcionando.

Proxies rotativos

Extrair muito de um único IP corre o risco de ser bloqueado. Para evitar isso, podemos rotear solicitações através de diferentes proxies usando módulos como requests-proxy-killer:

from proxy_killer import KillerScraper

scraper = KillerScraper(use_cache=False, max_retries=3)

async def fetch_page(page):

  for retry in range(3): 
    try:
      proxy = scraper.get_proxy() # Rotate proxy
      resp = scraper.get(search_url, proxies=proxy, params=params)
      return resp.json()
    except Exception as e:
      print(f"Error: {e}, retrying")
      sleep(1)

# Remainder same as above

Ao rotear cada solicitação por meio de um IP proxy diferente, podemos aumentar a escala sem nos preocupar com bloqueios.

As etapas acima nos permitem construir um raspador Algolia robusto, de alto desempenho e em grande escala em Python. Os mesmos princípios se aplicam a qualquer idioma.

Evitando bloqueios ao raspar Algolia

A última questão a ser abordada é evitar bloqueios do próprio serviço Algolia. Se fizer muitas solicitações agressivas, Algolia pode bloquear seu IP ou limitar as solicitações.

Aqui estão algumas dicas para raspar educadamente e minimizar bloqueios:

  • Taxa limite: não sobrecarregue a API com centenas de solicitações simultâneas. Comece pequeno e aumente gradualmente.

  • Usar proxies: alterne IPs diferentes para distribuir a carga e evitar solicitações concentradas.

  • Randomizar agentes de usuário: Varie o cabeçalho do agente do usuário entre as solicitações.

  • Siga robots.txt: certifique-se de que seu raspador obedece às regras do robots.txt.

  • Usar lógica de repetição: espera exponencial se a taxa for limitada ou bloqueada.

  • Raspe durante períodos de baixo tráfego: segmente noites durante a semana quando a carga for menor.

  • Monitore cuidadosamente: verifique se há falhas crescentes ou limitação.

Com os devidos cuidados, você pode construir raspadores Algolia sustentáveis ​​e de longa duração. Mas certifique-se de monitorar de perto e adaptar sua abordagem ao longo do tempo.

Raspagem de bibliotecas auxiliares

Lidar manualmente com toda a complexidade do dimensionamento e da resiliência pode ser complicado. Existem várias ferramentas comerciais para simplificar o web scraping.

Por exemplo:

  • RaspagemBee – Lida com proxies, CAPTCHAs e navegadores.
  • RaspadorAPI – API do navegador com rotação automática de proxy.
  • ProxyCrawlName – Proxies residenciais com navegador sem cabeça.

Essas ferramentas facilitam a construção de scrapers robustos sem a necessidade de codificar lógica complexa. Veja meu guia em como e quando usar uma API de scraping.

Resumindo

Aqui estão os principais pontos:

  • Algolia fornece pesquisa hospedada via API para fácil integração em sites.
  • A API de pesquisa é pública e pode ser extraída extraindo o endpoint e as chaves.
  • A raspagem em escala requer solicitações assíncronas e rotação de proxy.
  • Monitore com cuidado e raspe educadamente para evitar bloqueios.
  • Os serviços comerciais de raspagem podem simplificar grandes trabalhos de raspagem.

Espero que esta postagem forneça uma boa visão geral de como raspar efetivamente a API de pesquisa Algolia em escala com Python. Os mesmos princípios também se aplicam a outras línguas.

Deixe-me saber se você tem alguma dúvida!

Tags:

Junte-se à conversa

O seu endereço de e-mail não será publicado. Os campos obrigatórios são marcados com *