Ecco un post sul blog di oltre 2000 parole su "Come raschiare la ricerca in Algolia":
Introduzione
Algolia è una popolare API di ricerca che alimenta la funzionalità di ricerca per molti siti Web su Internet. Consente ai siti Web di implementare una ricerca rapida e pertinente senza la necessità di eseguire autonomamente infrastrutture di ricerca complesse.
Alcuni esempi di siti Web popolari che utilizzano l'Algolia includono:
- Medio
- GitHub
- StackOverflow
- HackerNews
Lo scopo di questo post è spiegare:
- Cos'è l'Algolia e come funziona
- Come ottenere i risultati della ricerca in Algolia utilizzando Python
- Tecniche per raschiare l'Algolia in modo efficiente su larga scala
- Come evitare di rimanere bloccati durante la raschiatura dell'Algolia
Alla fine, capirai come creare uno scraper web Algolia scalabile per qualsiasi sito Web che lo utilizza.
Cos'è l'Algolia?
Algolia è un'API di ricerca ospitata che fornisce servizi come indicizzazione, ricerca e consigli. Viene spesso definito provider SaaS (Search-as-a-Service).
Le proposte di valore chiave dell’Algolia includono:
Ricerca veloce – L’Algolia afferma di essere in grado di cercare oltre miliardi di record in meno di 100 ms. Questo è ordini di grandezza più veloce rispetto alla ricerca sulla propria infrastruttura.
Ricerca pertinente – Algolia gestisce aspetti come la tolleranza agli errori di battitura, i sinonimi e l'apprendimento in base al comportamento dell'utente per restituire i risultati più pertinenti.
Servizio ospitato – L’Algolia si occupa di cose come il ridimensionamento e la ridondanza. Non c'è alcuna infrastruttura da gestire.
Accesso API – È possibile accedere alla funzionalità di ricerca tramite API che consente una facile integrazione in siti Web, app mobili, ecc.
Algolia fornisce librerie client per la maggior parte dei principali linguaggi e framework che gestiscono la comunicazione API. Sul front-end, gli sviluppatori aggiungono il codice JavaScript per interfacciarsi con l'API dell'Algolia.
Quindi, in sintesi, Algolia fornisce una ricerca ospitata e scalabile tramite API. Ciò consente ai siti Web di creare rapidamente un'ottima ricerca senza dover costruire essi stessi sistemi complessi.
Raschiare la ricerca Algolia con Python
Ora che abbiamo capito cos'è l'Algolia, vediamo come possiamo ottenere i risultati della ricerca dell'Algolia usando Python.
Lo scraping dell'Algolia è semplice poiché l'API è pubblica e documentata. Dobbiamo semplicemente:
- Identificare l'endpoint e i parametri dell'API
- Estrarre eventuali chiavi di accesso
- Invia richieste di ricerca e analizza la risposta JSON
Esaminiamo un esempio completo di scraping di un sito Web basato sull'Algolia.
Trovare l'endpoint API
Innanzitutto, dobbiamo trovare l'endpoint API utilizzato dal sito Web per la ricerca. Il modo più semplice è aprire il sito nel browser, eseguire una query di ricerca e controllare le richieste di rete negli strumenti per sviluppatori.
Ad esempio, il HackerNews vediamo una richiesta fatta a:
https://hn.algolia.com/api/v1/search?query=python
I /api/v1/search
path rivela che questa è l'API di ricerca dell'Algolia. Vediamo anche il termine di ricerca python
passato come parametro di query.
Controllando la risposta, possiamo vedere che restituisce JSON con i risultati. Ora conosciamo l'endpoint API e il parametro di ricerca da utilizzare.
Ottenere le chiavi API
Successivamente, dobbiamo ottenere la chiave API necessaria per l'autenticazione. Controllando nuovamente la richiesta di rete, possiamo vederla passata tramite il file X-Algolia-API-Key
intestazione.
Possiamo estrarre questa chiave API e aggiungerla alle nostre richieste. Potrebbe essere necessario un ulteriore reverse engineering se la chiave è offuscata in JavaScript.
Effettuare richieste di ricerca
Con l'endpoint e la chiave API, ora possiamo effettuare richieste di ricerca in 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‘])
Effettuiamo una richiesta GET all'endpoint API passando il nostro termine di ricerca, i risultati per pagina e l'intestazione della chiave API. Il risultato contiene i risultati della ricerca come JSON che possiamo analizzare ed elaborare secondo necessità.
E ora abbiamo un raschietto Algolia di base!
Raschiare pagine aggiuntive
Una limitazione è che l'API restituisce solo la prima pagina dei risultati. Per ottenere pagine aggiuntive, dobbiamo passare il file page
parametro incrementale da 0:
# First page
params[‘page‘] = 0
# Second page
params[‘page‘] = 1
# Third page
params[‘page‘] = 2
Per raschiare tutte le pagine, possiamo ripetere l'esecuzione delle richieste incrementando il numero di pagina finché non vengono restituiti più risultati.
Mettendo insieme questo:
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
Questo scorre sulle pagine e produce tutti i risultati.
Per raccogliere tutti i risultati:
results = []
for result in scrape_search("python"):
results.append(result)
print(len(results))
E ora disponiamo di un impaginatore completo per raccogliere tutti i risultati di ricerca dell'Algolia!
Raschiare l'Algolia su larga scala
Il raschietto di base sopra funziona ma non è ottimizzato per il raschiamento su larga scala. Problemi che potresti riscontrare:
- Rallentare – Le richieste sincrone rallentano il recupero di centinaia di pagine.
- Fragile – Un guasto interrompe l’intero processo di scraping.
- Banned – Lo scraping da un IP rischia di essere bloccato.
Diamo un'occhiata a come affrontare questi problemi per un efficace raschiamento su larga scala.
Richieste asincrone
Per velocizzare lo scraping possiamo sfruttare le richieste asincrone. Questo ci permette di avere molte richieste in volo contemporaneamente.
Ad esempio con il asyncio
modulo:
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()
Ciò recupera 10 pagine contemporaneamente su ogni iterazione. Con le richieste asincrone lo scraper è molto più veloce.
Nuovi tentativi e tolleranza agli errori
Le richieste di rete sono soggette a errori intermittenti. Possiamo aggiungere tentativi per gestire gli errori con garbo:
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
Questo semplicemente riprova fino a 3 volte in caso di errore. Potrebbero essere aggiunti anche altri miglioramenti come il backoff esponenziale.
Per una maggiore resilienza, possiamo racchiudere il ciclo complessivo di scraping in un tentativo/eccetto e riprovare in caso di arresti anomali imprevisti.
Con tentativi a più livelli, il raschiatore può riprendersi da vari guasti e continuare a funzionare.
Proxy rotanti
Lo scraping eccessivo di un singolo IP rischia di essere bloccato. Per evitare ciò, possiamo instradare le richieste attraverso diversi proxy utilizzando moduli come 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
Instradando ciascuna richiesta attraverso un IP proxy diverso, possiamo eseguire operazioni su vasta scala senza preoccuparci dei blocchi.
I passaggi precedenti ci consentono di creare uno scraper Algolia robusto, ad alte prestazioni e su larga scala in Python. Gli stessi principi si applicano a qualsiasi lingua.
Evitare i blocchi durante la raschiatura dell'Algolia
L’ultima questione da affrontare è evitare blocchi dal servizio stesso dell’Algolia. Se effettui troppe richieste aggressive, Algolia potrebbe bloccare il tuo IP o limitare le richieste.
Ecco alcuni suggerimenti per raschiare educatamente e ridurre al minimo i blocchi:
Tasso limite: non sovraccaricare l'API con centinaia di richieste simultanee. Inizia in piccolo e aumenta gradualmente.
Usa i proxy: Ruota diversi IP per distribuire il carico ed evitare richieste concentrate.
Randomizza gli user-agent: varia l'intestazione dell'agente utente tra le richieste.
Segui robots.txt: assicurati che il tuo scraper rispetti le regole del file robots.txt.
Utilizza la logica dei tentativi: Backoff esponenziale se la tua tariffa viene limitata o bloccata.
Raschiare durante i periodi di basso traffico: scegli come target le notti dei giorni feriali quando il carico è inferiore.
Monitorare attentamente: controlla l'aumento degli errori o delle limitazioni.
Con la dovuta cura, è possibile costruire raschiatori Algolia sostenibili e di lunga durata. Ma assicurati di monitorare attentamente e adattare il tuo approccio nel tempo.
Scraping delle librerie di supporto
Gestire manualmente tutta la complessità della scalabilità e della resilienza può essere complicato. Esistono vari strumenti commerciali per semplificare il web scraping.
Per esempio:
- RaschiareApe – Gestisce proxy, CAPTCHA e browser.
- API raschietto – API del browser con rotazione automatica del proxy.
- Scansione proxy – Proxy residenziali con browser headless.
Questi strumenti semplificano la creazione di scraper robusti senza dover codificare da soli una logica complessa. Vedi la mia guida su come e quando utilizzare un'API di scraping.
Avvolgere Up
Ecco i punti chiave da asporto:
- Algolia fornisce la ricerca ospitata tramite API per una facile integrazione nei siti.
- L'API di ricerca è pubblica e può essere recuperata estraendo l'endpoint e le chiavi.
- Lo scraping su larga scala richiede richieste asincrone e rotazione dei proxy.
- Monitorare attentamente e raschiare educatamente per evitare blocchi.
- I servizi di raschiatura commerciale possono semplificare i lavori di raschiatura di grandi dimensioni.
Spero che questo post fornisca una buona panoramica su come raschiare in modo efficace l'API di ricerca Algolia su larga scala con Python. Gli stessi principi valgono anche per le altre lingue.
Fatemi sapere se avete altre domande!