Intégration d'A-Parser avec Redis : API avancée
Comparaison avec l'API HTTP
A-Parser Redis API a été conçu pour remplacer les méthodes oneRequest et bulkRequest pour une implémentation plus performante et le support de scénarios d'utilisation supplémentaires :
- Redis agit comme serveur de requêtes et de résultats
- possibilité de demander les résultats de manière asynchrone ou en mode bloquant
- possibilité de connecter plusieurs scrapers (sur un seul ou sur différents serveurs) pour traiter les requêtes avec un point d'entrée unique
- possibilité de définir le nombre de threads pour le traitement des requêtes et de consulter les logs de fonctionnement
- possibilité d'organiser des timeouts sur les opérations
- expiration automatique (Expire) des résultats non réclamés
Sujet de discussion sur le forum
Configuration préalable
À la différence de l'A-Parser HTTP API, pour utiliser Redis API, il est nécessaire de configurer et de lancer préalablement une tâche avec le scraper
API::Server::Redis :
- installer et lancer un serveur Redis (localement ou à distance)
- créer une présélection de paramètres pour le scraper
API::Server::Redis, indiquer :Redis Host- adresse du serveur Redis, par défaut127.0.0.1Redis Port- port du serveur Redis, par défaut6379Redis Queue Key- nom de la clé pour l'échange de données avec A-Parser, par défautaparser_redis_api, vous pouvez créer des files d'attente séparées et les traiter avec différentes tâches ou différentes instances d'A-ParserResult Expire(TTL)- durée de vie du résultat en secondes, sert au contrôle automatique et à la suppression des résultats non réclamés, par défaut3600secondes (1 heure)
- ajouter une tâche avec le scraper
API::Server::Redis- comme requêtes, il est nécessaire d'indiquer
{num:1:N}, oùNdoit correspondre au nombre de threads indiqué dans la tâche - vous pouvez également activer l'option de journalisation, ainsi il sera possible de consulter le log pour chaque requête
- comme requêtes, il est nécessaire d'indiquer
Exemple de configuration de tâche avec
API::Server::Redis

Lancement d'A-Parser avec Redis via docker-compose
Avec cette méthode de lancement, vous pouvez indiquer le nom du service au lieu de l'IP comme adresse du serveur Redis (Redis Host), dans les exemples ci-dessous c'est redis
Si A-Parser n'a jamais été lancé via docker-compose auparavant
- Téléchargez et décompressez la distribution (le lien à usage unique doit être préalablement récupéré dans l'Espace Membres, comme décrit ici) :
curl -O https://a-parser.com/members/onetime/ce42f308eaa577b5/aparser.tar.gz
tar zxf aparser.tar.gz
rm -f aparser.tar.gz
Créez un fichier
docker-compose.ymlet insérez-y le contenu suivant :- Variante de base sans mot de passe et sans ouverture de port, Redis sera accessible uniquement à l'intérieur du réseau 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 avec mot de passe et ouverture de port, Redis sera accessible de l'extérieur, il est donc fortement recommandé d'utiliser un mot de passe
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 VOTRE_MOT_DE_PASSE_REDIS
ports:
- 6379:6379À la place de VOTRE_MOT_DE_PASSE_REDIS, inventez et indiquez le mot de passe qui sera utilisé lors de l'authentification dans Redis.
Lancez les conteneurs :
docker compose up -d
Si A-Parser a déjà été lancé via docker-compose auparavant
Modifiez le fichier
docker-compose.ymlen ajoutant à la fin le contenu suivant :- Variante de base sans mot de passe et sans ouverture de port, Redis sera accessible uniquement à l'intérieur du réseau Docker
redis:
image: redis:latest
restart: always- Variante avec mot de passe et ouverture de port, Redis sera accessible de l'extérieur, il est donc fortement recommandé d'utiliser un mot de passe
redis:
image: redis:latest
restart: always
command: redis-server --requirepass VOTRE_MOT_DE_PASSE_REDIS
ports:
- 6379:6379À la place de VOTRE_MOT_DE_PASSE_REDIS, inventez et indiquez le mot de passe qui sera utilisé lors de l'authentification dans Redis.
Lancez les conteneurs :
docker compose up -d
Si A-Parser était déjà lancé et que sa configuration n'a pas changé, il ne sera pas redémarré, et Docker ajoutera et lancera simplement Redis.
Exécution des requêtes
Le fonctionnement de l'API Redis est basé sur les Redis Lists (listes). Les opérations sur les listes permettent d'ajouter à la file d'attente un nombre illimité de requêtes (limité par la mémoire vive), ainsi que d'obtenir les résultats en mode bloquant avec un timeout (blpop) ou en mode asynchrone (lpop).
- tous les paramètres, sauf
useproxy,proxyCheckeretproxybannedcleanup, sont extraits de la présélection du scraper appelé +overrideOpts - les paramètres
useproxy,proxyCheckeretproxybannedcleanupsont récupérés depuis la présélection
API::Server::Redis + overrideOpts
La requête est ajoutée à Redis par la commande lpush, chaque requête se compose d'un tableau [queryId, parser, preset, query, overrideOpts, apiOpts] sérialisé à l'aide de JSON :
parser,preset,querycorrespondent aux paramètres analogues de la requête APIoneRequestqueryId- est généré avec la requête, nous recommandons d'utiliser un numéro séquentiel de votre base de données ou un bon nombre aléatoire ; ce ID permettra de récupérer le résultatoverrideOpts- redéfinition des paramètres pour la présélection du scraperapiOpts- paramètres supplémentaires de traitement de l'API
Lors des requêtes via Redis, l'étape de formatage du résultat est ignorée, car tout le résultat est transmis sous forme de JSON pour un traitement logiciel ultérieur.
redis-cli
Exemple d'exécution de requêtes, vous pouvez utiliser redis-cli pour tester :
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.....
Différents cas d'utilisation
Vérification asynchrone de la présence du résultat
lpop aparser_redis_api:some_unique_id
Retournera le résultat s'il est déjà traité ou nil si la requête est encore en cours de traitement
Récupération bloquante du résultat
blpop aparser_redis_api:some_unique_id 0
Cette requête sera bloquée jusqu'à l'obtention du résultat, vous pouvez également indiquer un timeout maximum pour l'obtention du résultat, après quoi la commande retournera nil
Sauvegarde des résultats dans une file d'attente unique
Par défaut, A-Parser sauvegarde le résultat de chaque requête sous sa propre clé unique aparser_redis_api:query_id, ce qui permet d'organiser un traitement multithread en envoyant des requêtes et en recevant des résultats séparément pour chaque thread.
Dans certains cas, il est nécessaire de traiter les résultats dans un seul thread au fur et à mesure de leur arrivée. Dans ce cas, il est plus pratique de sauvegarder les résultats dans une file d'attente de résultats unique (la clé doit être différente de la clé des requêtes).
Pour cela, il est nécessaire d'indiquer la clé output_queue pour apiOpts :
lpush aparser_redis_api '["some_unique_id", "Net::HTTP", "default", "https://ya.ru", {}, {"output_queue": "aparser_results"}]'
Récupération du résultat depuis la file d'attente commune :
127.0.0.1:6379> blpop aparser_results 0
1) "aparser_results"
2) "{\"queryId\":\"some_unique_id\",\"results\":{\"data\":\"<!DOCTYPE html><html class=...
Exemple d'implémentation (cas SpySERP)
Supposons que nous créons un service SaaS qui évalue les paramètres des domaines. Pour simplifier, nous allons vérifier la date d'enregistrement du domaine.
Notre service se compose de 2 pages :
/index.php- page de destination (landing page) sur laquelle se trouve le formulaire de saisie du domaine/results.php?domain=google.com- page avec les résultats du fonctionnement du service
Pour améliorer l'expérience utilisateur, nous voulons que les pages de notre service se chargent instantanément, et que le processus d'attente des données paraisse naturel avec l'affichage d'un loader.
Lors de la requête vers results.php, nous effectuons en premier lieu une requête vers l'API Redis d'A-Parser, en générant un request_id unique :
lpush aparser_redis_api '["request-1", "Net::Whois", "default", "google.com", {}, {}]'
Après quoi nous pouvons afficher la page à l'utilisateur et montrer un loader sur la zone d'affichage des données. Grâce à l'absence de délais, la réponse du serveur ne sera limitée que par la vitesse de connexion à Redis (généralement dans les 10 ms).
A-Parser commencera le traitement de la requête avant même que le navigateur de l'utilisateur ne reçoive le premier contenu. Une fois que le navigateur aura chargé toutes les ressources et scripts nécessaires, nous pourrons afficher le résultat. Pour cela, nous envoyons une requête AJAX pour obtenir les données :
/get-results.php?request_id=request-1
Le script get-results.php effectue une requête bloquante vers Redis avec un timeout de 15 secondes :
blpop aparser_redis_api:request-1 15
Et retourne la réponse dès qu'elle est reçue d'A-Parser. Si nous avons reçu un résultat nul par timeout, nous pouvons afficher une erreur de récupération des données à l'utilisateur.
Ainsi, en envoyant la requête à A-Parser lors de la première ouverture de la page (/results.php), nous réduisons le temps d'attente des données nécessaire pour l'utilisateur (/get-results.php) du temps que le navigateur de l'utilisateur passe à attendre le contenu, à charger les scripts et à exécuter la requête AJAX.