Ga naar de hoofdinhoud

Integratie van A-Parser met Redis: geavanceerde API

Vergelijking met HTTP API

A-Parser Redis API is ontwikkeld ter vervanging van de methoden oneRequest en bulkRequest voor een productievere implementatie en ondersteuning van aanvullende gebruiksscenario's:

  • Redis fungeert als server voor verzoeken en resultaten
  • mogelijkheid om resultaten asynchroon of in blokkerende modus op te vragen
  • mogelijkheid om meerdere scrapers aan te sluiten (zowel op dezelfde als op verschillende servers) voor het verwerken van verzoeken met een centraal toegangspunt
  • mogelijkheid om het aantal threads voor verwerking in te stellen en werklogs te bekijken
  • mogelijkheid om time-outs voor bewerkingen in te stellen
  • automatische Expire voor niet-opgevraagde resultaten

Discussietopic op het forum

Voorafgaande configuratie

In tegenstelling tot de A-Parser HTTP API moet u voor het gebruik van de Redis API vooraf een taak configureren en starten met de scraper API::Server::RedisAPI::Server::Redis:

  • installeer en start de Redis-server (lokaal of op afstand)
  • maak een instellingen-preset voor de scraper API::Server::RedisAPI::Server::Redis, geef op:
    • Redis Host - adres van de Redis-server, standaard 127.0.0.1
    • Redis Port - poort van de Redis-server, standaard 6379
    • Redis Queue Key - naam van de sleutel voor gegevensuitwisseling met A-Parser, standaard aparser_redis_api, u kunt afzonderlijke wachtrijen maken en deze verwerken met verschillende taken of verschillende kopieën van A-Parser
    • Result Expire(TTL) - levensduur van het resultaat in seconden, dient voor automatische controle en verwijdering van niet-opgevraagde resultaten, standaard 3600 seconden (1 uur)
  • voeg een taak toe met de scraper API::Server::RedisAPI::Server::Redis
    • als verzoeken moet u {num:1:N} opgeven, waarbij N moet overeenkomen met het aantal threads dat in de taak is opgegeven
    • u kunt ook de optie voor logboekregistratie inschakelen, zodat het mogelijk is om het logboek per verzoek te bekijken

Voorbeeld van taakconfiguratie met API::Server::RedisAPI::Server::Redis

API-verzoek ontvangen

A-Parser samen met Redis starten via docker-compose

Bij deze startmethode kan in plaats van een IP-adres de servicenaam worden opgegeven als adres voor de Redis-server (Redis Host), in de onderstaande voorbeelden is dit redis

Als A-Parser nog niet eerder via docker-compose is gestart

  1. Download en pak de distributie uit (een eenmalige link moet vooraf worden opgehaald in het Ledengebied, zoals hier beschreven):
curl -O https://a-parser.com/members/onetime/ce42f308eaa577b5/aparser.tar.gz
tar zxf aparser.tar.gz
rm -f aparser.tar.gz
  1. Maak een bestand docker-compose.yml aan en plaats de volgende inhoud erin:

    • Basis variant zonder wachtwoord en poortopening, Redis zal alleen beschikbaar zijn binnen het Docker-netwerk
    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
    • Variant met wachtwoord en poortopening, Redis zal van buitenaf toegankelijk zijn, daarom wordt het ten zeerste aanbevolen om een wachtwoord te gebruiken
    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 HIER_WACHTWOORD_VOOR_REDIS
    ports:
    - 6379:6379

    In plaats van HIER_WACHTWOORD_VOOR_REDIS bedenkt en voert u een wachtwoord in dat zal worden gebruikt voor autorisatie in Redis.

  2. Start de containers:

docker compose up -d

Als A-Parser al eerder via docker-compose is gestart

  1. Bewerk het bestand docker-compose.yml door aan het einde de volgende inhoud toe te voegen:

    • Basis variant zonder wachtwoord en poortopening, Redis zal alleen beschikbaar zijn binnen het Docker-netwerk
      redis:
    image: redis:latest
    restart: always
    • Variant met wachtwoord en poortopening, Redis zal van buitenaf toegankelijk zijn, daarom wordt het ten zeerste aanbevolen om een wachtwoord te gebruiken
      redis:
    image: redis:latest
    restart: always
    command: redis-server --requirepass HIER_WACHTWOORD_VOOR_REDIS
    ports:
    - 6379:6379

    In plaats van HIER_WACHTWOORD_VOOR_REDIS bedenkt en voert u een wachtwoord in dat zal worden gebruikt voor autorisatie in Redis.

  2. Start de containers:

docker compose up -d
opmerking

Als A-Parser al was gestart en de configuratie niet is gewijzigd, zal deze niet opnieuw worden opgestart; Docker zal simpelweg Redis toevoegen en starten.

Verzoeken uitvoeren

De werking van de Redis API is gebaseerd op Redis Lists (lijsten). Bewerkingen op lijsten maken het mogelijk om een onbeperkt aantal verzoeken aan de wachtrij toe te voegen (beperkt door RAM) en resultaten op te halen in blokkerende modus met een time-out (blpop) of in asynchrone modus (lpop).

  • alle instellingen, behalve useproxy, proxyChecker en proxybannedcleanup, worden overgenomen uit de preset van de aangeroepen scraper + overrideOpts
  • de instellingen useproxy, proxyChecker en proxybannedcleanup worden overgenomen uit de preset API::Server::RedisAPI::Server::Redis + overrideOpts

Een verzoek wordt aan Redis toegevoegd met het commando lpush. Elk verzoek bestaat uit een array [queryId, parser, preset, query, overrideOpts, apiOpts] geserialiseerd met JSON:

  • parser, preset, query komen overeen met die voor het API-verzoek oneRequest
  • queryId - wordt samen met het verzoek gegenereerd; we raden aan een volgnummer uit uw database of een goede willekeurige waarde te gebruiken, via dit ID kan het resultaat worden opgehaald
  • overrideOpts - overschrijven van instellingen voor de scraper-preset
  • apiOpts - aanvullende API-verwerkingsparameters
opmerking

Bij verzoeken via Redis wordt de stap voor het formatteren van het resultaat overgeslagen, omdat het volledige resultaat als JSON wordt verzonden voor verdere programmatische verwerking.

redis-cli

Voorbeeld van het uitvoeren van verzoeken, voor testen kan redis-cli worden gebruikt:

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.....

Verschillende cases

Asynchrone controle op de aanwezigheid van een resultaat

lpop aparser_redis_api:some_unique_id

Retourneert het resultaat als het al is verwerkt of nil als het verzoek nog in behandeling is

Blokkerend ophalen van resultaat

blpop aparser_redis_api:some_unique_id 0

Dit verzoek wordt geblokkeerd tot het moment dat het resultaat is ontvangen. U kunt ook een maximale time-out opgeven voor het ontvangen van het resultaat, waarna het commando nil retourneert

Resultaten opslaan in een centrale wachtrij

Standaard slaat A-Parser het resultaat voor elk verzoek op onder zijn eigen unieke sleutel aparser_redis_api:query_id, wat multithreading verwerking mogelijk maakt door verzoeken te verzenden en resultaten afzonderlijk voor elke thread op te halen

In sommige gevallen is het nodig om resultaten in één thread te verwerken naarmate ze binnenkomen. In dat geval is het handiger om resultaten op te slaan in een centrale resultatenwachtrij (de sleutel moet verschillen van de sleutel voor verzoeken)

Hiervoor moet de sleutel output_queue worden opgegeven voor apiOpts:

lpush aparser_redis_api '["some_unique_id", "Net::HTTP", "default", "https://ya.ru", {}, {"output_queue": "aparser_results"}]'

Resultaat ophalen uit de algemene wachtrij:

127.0.0.1:6379> blpop aparser_results 0
1) "aparser_results"
2) "{\"queryId\":\"some_unique_id\",\"results\":{\"data\":\"<!DOCTYPE html><html class=...

Voorbeeld van implementatie (case SpySERP)

Stel dat we een SaaS-dienst maken die domeinparameters evalueert; voor de eenvoud controleren we de registratiedatum van het domein

Onze dienst bestaat uit 2 pagina's:

  • /index.php - landingspagina met een invoerformulier voor het domein
  • /results.php?domain=google.com - pagina met de resultaten van de dienst

Om de gebruikerservaring te verbeteren, willen we dat de pagina's van onze dienst onmiddellijk laden, terwijl het wachten op gegevens er natuurlijk uitziet en er een loader wordt getoond

Bij een verzoek aan results.php voeren we eerst een verzoek uit naar de A-Parser Redis API, waarbij we een uniek request_id genereren:

​lpush aparser_redis_api '["request-1", "Net::Whois", "default", "google.com", {}, {}]'

Daarna kunnen we de pagina aan de gebruiker tonen en een loader weergeven in het gegevensgebied. Door het ontbreken van vertragingen wordt de serverrespons alleen beperkt door de verbindingssnelheid van Redis (meestal binnen 10ms)

A-Parser begint met de verwerking van het verzoek nog voordat de browser van de gebruiker de eerste inhoud ontvangt. Nadat de browser alle benodigde bronnen en scripts heeft geladen, kunnen we het resultaat weergeven. Hiervoor sturen we een AJAX-verzoek om de gegevens op te halen:

/get-results.php?request_id=request-1

Het script get-results.php voert een blokkerend verzoek uit naar Redis met een time-out van 15 seconden:

blpop aparser_redis_api:request-1 15

En retourneert het antwoord zodra het van A-Parser is ontvangen. Als we een nulresultaat krijgen door time-out, kunnen we een foutmelding bij het ophalen van gegevens aan de gebruiker tonen

Op deze manier verkorten we, door bij de eerste opening van de pagina (/results.php) een verzoek naar A-Parser te sturen, de benodigde wachttijd voor de gebruiker (/get-results.php) met de tijd die de browser van de gebruiker besteedt aan het wachten op inhoud, het laden van scripts en het uitvoeren van het AJAX-verzoek