Hoppa till huvudinnehåll

Integration av A-Parser med Redis: avancerat API

Jämförelse med HTTP API

A-Parser Redis API utvecklades för att ersätta metoderna oneRequest och bulkRequest för en mer högpresterande implementering och stöd för ytterligare användningsfall:

  • Redis fungerar som server för förfrågningar och resultat
  • möjlighet att begära resultat asynkront eller i blockerande läge
  • möjlighet att ansluta flera scrapers (både på samma och på olika servrar) för att behandla förfrågningar med en gemensam ingångspunkt
  • möjlighet att ställa in antal trådar för att behandla förfrågningar och visa arbetsloggar
  • möjlighet att organisera timeout för operationer
  • automatisk Expire för ej efterfrågade resultat

Diskussionstråd på forumet

Förinställning

Till skillnad från A-Parser HTTP API krävs det för att använda Redis API att man först konfigurerar och kör en uppgift med scrapern API::Server::RedisAPI::Server::Redis:

  • installera och starta Redis-server (lokalt eller fjärrstyrt)
  • skapa en förinställning (preset) för scrapern API::Server::RedisAPI::Server::Redis, ange:
    • Redis Host - adress till Redis-servern, standard är 127.0.0.1
    • Redis Port - port för Redis-servern, standard är 6379
    • Redis Queue Key - namnet på nyckeln för datautbyte med A-Parser, standard är aparser_redis_api, du kan skapa separata köer och behandla dem med olika uppgifter eller olika instanser av A-Parser
    • Result Expire(TTL) - livslängd för resultatet i sekunder, används för automatisk kontroll och borttagning av ej efterfrågade resultat, standard är 3600 sekunder (1 timme)
  • lägg till en uppgift med scrapern API::Server::RedisAPI::Server::Redis
    • som förfrågningar måste du ange {num:1:N}, där N ska motsvara antalet trådar som angetts i uppgiften
    • du kan också aktivera loggningsalternativet, vilket gör det möjligt att visa loggen för varje förfrågan

Exempel på konfiguration av uppgift med API::Server::RedisAPI::Server::Redis

Mottagande av API-förfrågan

Starta A-Parser tillsammans med Redis med docker-compose

Vid detta sätt att starta kan man ange tjänstenamnet istället för IP som adress till Redis-servern (Redis Host), i exemplen nedan är detta redis

Om A-Parser inte har körts via docker-compose tidigare

  1. Ladda ner och packa upp distributionen (en engångslänk måste först hämtas i Medlemsområde, enligt beskrivningen här):
curl -O https://a-parser.com/members/onetime/ce42f308eaa577b5/aparser.tar.gz
tar zxf aparser.tar.gz
rm -f aparser.tar.gz
  1. Skapa filen docker-compose.yml och lägg till följande innehåll:

    • Grundläggande variant utan lösenord och öppning av port, Redis kommer endast vara tillgänglig inom Docker-nätverket
    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 med lösenord och öppning av port, Redis kommer vara tillgänglig utifrån, därför rekommenderas starkt att använda lösenord
    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 LÖSENORD_HÄR_FÖR_REDIS
    ports:
    - 6379:6379

    Istället för HÄR_LÖSENORD_FÖR_REDIS hitta på och ange ett lösenord som ska användas vid auktorisering i Redis.

  2. Starta containrarna:

docker compose up -d

Om A-Parser redan har körts via docker-compose tidigare

  1. Redigera filen docker-compose.yml genom att lägga till följande innehåll i slutet:

    • Grundläggande variant utan lösenord och öppning av port, Redis kommer endast vara tillgänglig inom Docker-nätverket
      redis:
    image: redis:latest
    restart: always
    • Variant med lösenord och öppning av port, Redis kommer vara tillgänglig utifrån, därför rekommenderas starkt att använda lösenord
      redis:
    image: redis:latest
    restart: always
    command: redis-server --requirepass LÖSENORD_HÄR_FÖR_REDIS
    ports:
    - 6379:6379

    Istället för HÄR_LÖSENORD_FÖR_REDIS hitta på och ange ett lösenord som ska användas vid auktorisering i Redis.

  2. Starta containrarna:

docker compose up -d
anteckning

Om A-Parser redan kördes och dess konfiguration inte har ändrats, kommer den inte att startas om, utan Docker kommer helt enkelt att lägga till och starta Redis.

Utförande av förfrågningar

Redis API:s arbete är baserat på Redis Lists (listor), operationer på listor gör det möjligt att lägga till ett obegränsat antal förfrågningar i kön (begränsat av RAM), samt att erhålla resultat i blockerande läge med timeout (blpop) eller i asynkront läge (lpop).

  • alla inställningar, förutom useproxy, proxyChecker och proxybannedcleanup, hämtas från förinställningen för den anropade scrapern + overrideOpts
  • inställningarna useproxy, proxyChecker och proxybannedcleanup hämtas från förinställningen API::Server::RedisAPI::Server::Redis + overrideOpts

En förfrågan läggs till i Redis med kommandot lpush, varje förfrågan består av en array [queryId, parser, preset, query, overrideOpts, apiOpts] serialiserad med JSON:

  • parser, preset, query motsvarar de som används för API-förfrågan oneRequest
  • queryId - skapas tillsammans med förfrågan, vi rekommenderar att använda ett löpnummer från din databas eller en bra slumpmässig sträng, med detta ID kan resultatet hämtas
  • overrideOpts - överskridning av inställningar för scraperns förinställning
  • apiOpts - ytterligare parametrar för API-behandling
anteckning

Vid förfrågningar via Redis hoppas steget för formatering av resultatet över, eftersom hela resultatet skickas som JSON för vidare programmatisk behandling.

redis-cli

Exempel på utförande av förfrågningar, för testning kan redis-cli användas:

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

Olika användningsfall

Asynkron kontroll av resultatets tillgänglighet

lpop aparser_redis_api:some_unique_id

Returnerar resultatet om det redan har behandlats eller nil om förfrågan fortfarande behandlas

Blockerande hämtning av resultat

blpop aparser_redis_api:some_unique_id 0

Denna förfrågan kommer att blockeras tills resultatet erhålls, du kan också ange en maximal timeout för att erhålla resultatet, varefter kommandot returnerar nil

Spara resultat i en gemensam kö

Som standard sparar A-Parser resultatet för varje förfrågan under sin egen unika nyckel aparser_redis_api:query_id, vilket gör det möjligt att organisera flertrådad behandling genom att skicka förfrågningar och ta emot resultat separat för varje tråd

I vissa fall är det nödvändigt att behandla resultaten i en tråd allt eftersom de kommer in, i så fall är det bekvämare att spara resultaten i en gemensam resultatkön (nyckeln måste skilja sig från nyckeln för förfrågningar)

För att göra detta måste du ange nyckeln output_queue för apiOpts:

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

Hämtning av resultat från den gemensamma kön:

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

Exempel på implementering (fallet SpySERP)

Antag att vi skapar en SaaS-tjänst som utvärderar domänparametrar, för enkelhetens skull kommer vi att kontrollera domänens registreringsdatum

Vår tjänst består av 2 sidor:

  • /index.php - landningssida där ett formulär för domäninmatning finns
  • /results.php?domain=google.com - sida med resultaten från tjänstens arbete

För att förbättra användarupplevelsen vill vi att sidorna i vår tjänst ska laddas omedelbart, och att väntetiden för data ska se naturlig ut och visa en laddningsikon

Vid en förfrågan till results.php utför vi först en förfrågan till A-Parser Redis API och skapar ett unikt request_id:

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

Därefter kan vi visa sidan för användaren och visa en laddningsikon i dataområdet, tack vare avsaknaden av fördröjningar kommer serverns svarstid endast begränsas av Redis anslutningshastighet (vanligtvis inom 10ms)

A-Parser börjar behandla förfrågan redan innan användarens webbläsare får det första innehållet, efter att webbläsaren har laddat alla nödvändiga resurser och skript kan vi visa resultatet, för detta skickar vi en AJAX-förfrågan för att hämta data:

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

Skriptet get-results.php utför en blockerande förfrågan till Redis med en timeout på 15 sekunder:

blpop aparser_redis_api:request-1 15

Och returnerar svaret så snart det erhålls från A-Parser, om vi fick ett nollresultat på grund av timeout kan vi visa ett felmeddelande om datahämtning för användaren

På så sätt, genom att skicka en förfrågan till A-Parser vid första öppningen av sidan (/results.php), förkortar vi den nödvändiga väntetiden för data för användaren (/get-results.php) med den tid som användarens webbläsare spenderar på att vänta på innehåll, ladda skript och utföra AJAX-förfrågan