Integrazione di A-Parser con Redis: API avanzata
Confronto con l'API HTTP
A-Parser Redis API è stato sviluppato per sostituire i metodi oneRequest e bulkRequest per un'implementazione più performante e per supportare scenari di utilizzo aggiuntivi:
- Redis funge da server per richieste e risultati
- possibilità di richiedere i risultati in modo asincrono o in modalità bloccante
- possibilità di collegare più scraper (sia sullo stesso server che su server diversi) per elaborare le richieste con un unico punto di ingresso
- possibilità di impostare il numero di thread per l'elaborazione delle richieste e visualizzare i log di lavoro
- possibilità di organizzare timeout sulle operazioni
- Expire automatico dei risultati non richiesti
Configurazione preliminare
A differenza di A-Parser HTTP API, per utilizzare Redis API è necessario configurare e avviare preventivamente un'attività con lo scraper
API::Server::Redis:
- installare e avviare il server Redis (localmente o in remoto)
- creare un preset di impostazioni per lo scraper
API::Server::Redis, specificando:Redis Host- indirizzo del server Redis, predefinito127.0.0.1Redis Port- porta del server Redis, predefinito6379Redis Queue Key- nome della chiave per lo scambio di dati con A-Parser, predefinitoaparser_redis_api, è possibile creare code separate ed elaborarle con task diversi o diverse istanze di A-ParserResult Expire(TTL)- tempo di vita del risultato in secondi, serve per il controllo automatico e la rimozione dei risultati non richiesti, predefinito3600secondi (1 ora)
- aggiungere un'attività con lo scraper
API::Server::Redis- come query è necessario indicare
{num:1:N}, doveNdeve corrispondere al numero di thread specificato nel task - è inoltre possibile attivare l'opzione di logging, in modo da poter visualizzare il log per ogni richiesta
- come query è necessario indicare
Esempio di configurazione dell'attività con
API::Server::Redis

Avvio di A-Parser insieme a Redis utilizzando docker-compose
Con questo metodo di avvio, come indirizzo del server Redis (Redis Host) è possibile indicare il nome del servizio invece dell'IP, negli esempi seguenti è redis
Se A-Parser non è mai stato avviato tramite docker-compose
- Scaricare ed estrarre la distribuzione (il link monouso deve essere preventivamente prelevato dall'Area membri, come descritto qui):
curl -O https://a-parser.com/members/onetime/ce42f308eaa577b5/aparser.tar.gz
tar zxf aparser.tar.gz
rm -f aparser.tar.gz
Creare il file
docker-compose.ymle inserire il seguente contenuto:- Variante base senza password e apertura porta, Redis sarà accessibile solo all'interno della rete Docker
version: '3'
services:
a-parser:
image: aparser/runtime:latest
command: ./aparser
restart: always
volumes:
- ./aparser:/app
ports:
- 9091:9091
redis:
image: redis:latest
restart: always- Variante con password e apertura porta, Redis sarà accessibile dall'esterno, pertanto si raccomanda vivamente di utilizzare una password
version: '3'
services:
a-parser:
image: aparser/runtime:latest
command: ./aparser
restart: always
volumes:
- ./aparser:/app
ports:
- 9091:9091
redis:
image: redis:latest
restart: always
command: redis-server --requirepass QUI_PASSWORD_PER_REDIS
ports:
- 6379:6379Al posto di QUI_PASSWORD_PER_REDIS inventate e indicate la password che verrà utilizzata per l'autorizzazione in Redis.
Avviare i container:
docker compose up -d
Se A-Parser è già stato avviato tramite docker-compose
Modificare il file
docker-compose.ymlaggiungendo alla fine il seguente contenuto:- Variante base senza password e apertura porta, Redis sarà accessibile solo all'interno della rete Docker
redis:
image: redis:latest
restart: always- Variante con password e apertura porta, Redis sarà accessibile dall'esterno, pertanto si raccomanda vivamente di utilizzare una password
redis:
image: redis:latest
restart: always
command: redis-server --requirepass QUI_PASSWORD_PER_REDIS
ports:
- 6379:6379Al posto di QUI_PASSWORD_PER_REDIS inventate e indicate la password che verrà utilizzata per l'autorizzazione in Redis.
Avviare i container:
docker compose up -d
Se A-Parser è già stato avviato e la sua configurazione non è cambiata, non verrà riavviato, e Docker aggiungerà e avvierà semplicemente Redis.
Esecuzione delle richieste
Il funzionamento della Redis API si basa sulle Redis Lists (liste); le operazioni sulle liste consentono di aggiungere alla coda un numero illimitato di richieste (limitato dalla memoria RAM), nonché di ottenere i risultati in modalità bloccante con timeout (blpop) o in modalità asincrona (lpop).
- tutte le impostazioni, eccetto
useproxy,proxyCheckereproxybannedcleanup, vengono prese dal preset dello scraper chiamato +overrideOpts - le impostazioni
useproxy,proxyCheckereproxybannedcleanupvengono prese dal preset
API::Server::Redis + overrideOpts
La richiesta viene aggiunta a Redis con il comando lpush, ogni richiesta consiste in un array [queryId, parser, preset, query, overrideOpts, apiOpts] serializzato tramite JSON:
parser,preset,querycorrispondono agli analoghi per la richiesta APIoneRequestqueryId- viene generato insieme alla richiesta, consigliamo di utilizzare un numero progressivo dal vostro database o un buon valore casuale; tramite questo ID sarà possibile ottenere il risultatooverrideOpts- sovrascrittura delle impostazioni per il preset dello scraperapiOpts- parametri aggiuntivi di elaborazione API
Nelle richieste tramite Redis, la fase di formattazione del risultato viene saltata, poiché l'intero risultato viene trasmesso sotto forma di JSON per un'ulteriore elaborazione programmatica.
redis-cli
Esempio di esecuzione delle richieste, per il test è possibile utilizzare redis-cli:
127.0.0.1:6379> lpush aparser_redis_api '["some_unique_id", "Net::HTTP", "default", "https://ya.ru"]'
(integer) 1
127.0.0.1:6379> blpop aparser_redis_api:some_unique_id 0
1) "aparser_redis_api:some_unique_id"
2) "{\"data\":\"<!DOCTYPE html><html.....
Casi d'uso
Verifica asincrona della presenza del risultato
lpop aparser_redis_api:some_unique_id
Restituirà il risultato se è già stato elaborato o nil se la richiesta è ancora in fase di elaborazione
Ottenimento bloccante del risultato
blpop aparser_redis_api:some_unique_id 0
Questa richiesta rimarrà bloccata fino al momento della ricezione del risultato; è inoltre possibile specificare un timeout massimo per la ricezione del risultato, dopodiché il comando restituirà nil
Salvataggio dei risultati in un'unica coda
Per impostazione predefinita, A-Parser salva il risultato per ogni richiesta sotto la propria chiave univoca aparser_redis_api:query_id, il che consente di organizzare un'elaborazione multithreading, inviando richieste e ricevendo risultati separatamente per ogni thread
In alcuni casi è necessario elaborare i risultati in un unico thread man mano che arrivano; in questo caso è più comodo salvare i risultati in un'unica coda dei risultati (la chiave deve essere diversa dalla chiave per le richieste)
Per fare ciò, è necessario specificare la chiave output_queue per apiOpts:
lpush aparser_redis_api '["some_unique_id", "Net::HTTP", "default", "https://ya.ru", {}, {"output_queue": "aparser_results"}]'
Ottenimento del risultato dalla coda comune:
127.0.0.1:6379> blpop aparser_results 0
1) "aparser_results"
2) "{\"queryId\":\"some_unique_id\",\"results\":{\"data\":\"<!DOCTYPE html><html class=...
Esempio di implementazione (caso SpySERP)
Supponiamo di creare un servizio SaaS che effettua la valutazione dei parametri dei domini; per semplicità controlleremo la data di registrazione del dominio
Il nostro servizio è composto da 2 pagine:
/index.php- landing page, sulla quale si trova il modulo di inserimento del dominio/results.php?domain=google.com- pagina con i risultati del lavoro del servizio
Per migliorare l'esperienza utente, vogliamo che le pagine del nostro servizio si carichino istantaneamente e che il processo di attesa dei dati sembri naturale e mostri un loader
Alla richiesta a results.php, eseguiamo prima di tutto una richiesta all'API Redis di A-Parser, generando un request_id univoco:
lpush aparser_redis_api '["request-1", "Net::Whois", "default", "google.com", {}, {}]'
Dopodiché possiamo mostrare la pagina all'utente e visualizzare un loader nell'area di visualizzazione dei dati; grazie all'assenza di ritardi, la risposta del server sarà limitata solo dalla velocità di connessione a Redis (solitamente entro i 10 ms)
A-Parser inizierà l'elaborazione della richiesta ancora prima che il browser dell'utente riceva il primo contenuto; dopo che il browser avrà caricato tutte le risorse e gli script necessari, potremo visualizzare il risultato, inviando per questo una richiesta AJAX per ottenere i dati:
/get-results.php?request_id=request-1
Lo script get-results.php esegue una richiesta bloccante a Redis con un timeout di 15 secondi:
blpop aparser_redis_api:request-1 15
E restituisce la risposta non appena viene ricevuta da A-Parser; se abbiamo ottenuto un risultato nullo per timeout, possiamo mostrare un errore di ricezione dati all'utente
In questo modo, inviando la richiesta ad A-Parser alla prima apertura della pagina (/results.php), riduciamo il tempo di attesa dei dati necessario per l'utente (/get-results.php) del tempo che il browser dell'utente impiega per attendere il contenuto, caricare gli script ed eseguire la richiesta AJAX