Parcurgeți un verificator de backlink-uri URL fără goluri sau bucle infinite
Rânduri per apel, pagini per interogare și un plafon dur la 50.000. Iată o buclă care respectă toate cele trei și vă spune când să vă opriți.

Până la 1.000 de rânduri sunt returnate per apel. Fiecare apel este facturat o singură dată, indiferent de numărul de rânduri. Paginarea profundă este limitată la 50.000 de rânduri, ceea ce reprezintă 50 de apeluri a câte 1.000 de rânduri fiecare.
De ce sortarea precede paginarea
Paginarea peste o listă nesortată este cauza apariției duplicatelor. Trimiteți întotdeauna sort și order împreună cu page și per, astfel încât pagina 3 să însemne același lucru la fiecare solicitare din rulare.
Un pull refdomains costă 2 credite per apel, deci 50 de apeluri ajung la 100 de credite, adică un cent. Chiar și cel mai rău caz este ieftin; costul real este o buclă care nu se termină.
Alegerea coloanei de sortare
Coloana după care se sortează depinde de întrebare. Cel mai mare primul este de obicei alegerea pentru audituri, deoarece plafonul taie apoi coada lungă în loc de partea care vă interesează.
Sortează după un câmp care nu are nicio semnificație pentru întrebarea ta, iar tăierea poate elimina rândurile pe care le-ai dorit. Extrage zece rânduri pentru fiecare sortare candidat și vezi care felie supraviețuiește plafonului.
Scrieți alegerea în raport, astfel încât următoarea persoană să știe de ce tăierea a căzut acolo unde a făcut-o.
Înregistrări care se mută în timpul unei rulări
Datele nu se mută în timpul unei rulări, decât dacă rebuildarea lunară intervine în mijlocul acesteia. Rar, dar real. Un job nocturn care acoperă prima zi a lunii poate returna o pagină din indexul vechi și următoarea din cel nou, așa că înregistrați ora de start în jurnal și comparați.
Scrieți ora de start în partea de sus a jurnalului și numărul paginii pe fiecare linie. Apoi, o neconcordanță în output indică o problemă de timp, nu un bug de parsare.
Dacă jobul este programat, evitați un ora de start chiar înainte de o rebuildare probabilă. Jurnalele dvs. arată o rebuildare ca o schimbare în totaluri între două rulări care se potrivesc în rest, așa că păstrați totalurile în fiecare linie de jurnal.
O rulare care acoperă o rebuildare nu este greșită în mod implicit. Este doar inconsistentă, așa că marcați acele rulări în jurnal și reluați felia afectată atunci când este importantă pentru un raport.
O buclă de paginare care se oprește
TypeScript pentru un worker Node 20. Se oprește la prima pagină scurtă, la plafon sau la orice ok care nu este true.
const BASE = "https://seomasters.dev/api.php";
const CAP = 50_000;
const PER = 1000;
export async function pullAll(domain: string, key: string) {
const rows: unknown[] = [];
for (let page = 1; rows.length < CAP; page++) {
const u = new URL(BASE);
u.search = new URLSearchParams({
action: "refdomains", q: domain,
page: String(page), per: String(PER),
sort: "dr", order: "desc",
}).toString();
const res = await fetch(u, { headers: { Authorization: `Bearer ${key}` } });
if (res.status === 401 || res.status === 402) throw new Error(`stop: HTTP ${res.status}`);
const body = await res.json();
if (!body.ok) throw new Error(JSON.stringify(body).slice(0, 300));
const chunk = findRows(body); // see note below
rows.push(...chunk);
if (chunk.length < PER) break; // short page means we are done
}
return rows;
}Depanarea unei rulări de paginare
| Ce vedeți | Motiv probabil | Ce trebuie făcut |
|---|---|---|
| Pagina 51 revine goală sau cu erori | Ați atins plafonul de 50.000 | Restrângeți cu o altă acțiune sau o sort diferită, apoi uniți după id |
| Același domeniu pe două pagini | Interogare nesortată sau rebuildarea indexului în timpul rulării | Trimiteți sort și order; dedupează după cheia de domeniu |
| Mai puține rânduri decât totalul din dashboard | Totalul este pentru întregul grafic, pull-ul este limitat | Afișați "top 50.000" în interfața utilizatorului |
| Buclele nu se termină niciodată | Verificările de condiție folosesc doar rows.length | Întrerupeți la o pagină scurtă, așa cum s-a menționat mai sus |
| Factura mai mare decât așteptat | Reîncercați la fiecare non-200 | Reîncercați doar erorile de rețea, vezi erori |

Citirea rândurilor fără a ghici numele câmpurilor
Helper-ul findRows de mai sus este lăsat intenționat deschis. Faceți un singur apel real, priviți JSON-ul și scrieți accessorul în funcție de ceea ce vedeți, nu de ceea ce a promis un tutorial.
Pentru verișorul mai ieftin al acestui job, evaluarea multor domenii simultan, fără nicio paginare, citiți scriptul DR în vrac.
Înghețați un răspuns ca fixture
Apoi înghețați-l cu un test. Salvați un răspuns ca fișier fixture și afirmați numărul de rânduri și cheile primului rând, astfel încât o modificare viitoare să eșueze în CI și nu în graficul unui client.
Păstrați fixture-ul în controlul versiunii alături de test, astfel încât un reviewer să vadă forma pe care o așteaptă codul fără a rula nimic.
Când API-ul adaugă un câmp mai târziu, diferența de fixture vă spune dacă accessorul a observat sau a ignorat în tăcere.
Numiți fixture-ul după interogarea din care provine, cum ar fi acțiunea, domeniul și sortarea. Un fișier numit response1.json nu spune cititorului următor nimic despre ceea ce dovedește.
Numărați rândurile stocate
Comparați rândurile salvate cu totalul raportat de buclă. Un gap înseamnă că o pagină a fost pierdută, iar un repeat înseamnă că o pagină a fost preluată de două ori și upsertată într-un singur rând.
Rulați această verificare după fiecare extragere de test, nu doar după prima. Deriva în număr este de obicei primul simptom al unei sortări schimbate sau a unei rebuildări care intervine în timpul rulării.
Păstrați numărul în aceeași linie de jurnal cu numărul paginii, astfel încât cele două să poată fi citite împreună dintr-o privire.
Împărțirea muncii deasupra plafonului
Unele întrebări depășesc plafonul. Pentru listele deasupra plafonului, împărțiți problema în loc să paginați mai agresiv. Extrageți top 50.000 după o sortare, apoi întrebați alte acțiuni despre cei mai grei, deoarece aceștia costă și ei 2 credite și răspund la întrebări diferite. Paginarea mai agresivă nu trece niciodată de tăiere.
Extrageți top 50.000 după o sortare
Luați plafonul ca pe un fapt al API-ului. Extrageți top 50.000 de rânduri după o sortare, stocați-le și etichetați rezultatul ca felia de top în orice raport.
Un dashboard care arată un număr limitat ca și cum ar fi totalul complet înșală persoanele care îl citesc. Eticheta nu costă nimic, iar un raport url backlink checker este mai onest cu ea.
Decideți dimensiunea feliei înainte de rulare și scrieți-o în antetul raportului, astfel încât numărul să nu pară niciodată mai mare decât este. O linie de antet nu costă nimic, iar un cititor care găsește un rând lipsă mai târziu vă va mulțumi pentru asta.
Întrebați cei mai grei o întrebare diferită
anchors și toppages răspund la alte întrebări, cum ar fi care text anchor domină sau care pagini atrag link-uri. Pentru un domeniu dincolo de plafon, acele răspunsuri pot fi mai importante decât următoarea pagină din aceeași listă.
Păstrați rezultatele lor în propriile tabele, indexate după domeniu, astfel încât o extragere ulterioară a aceluiași domeniu să le poată înlocui fără a atinge rândurile feliei de top.
Fiecare acțiune suplimentară costă propriile credite, așa că evaluați-o înainte de rulare, nu după sosirea facturii.
O listă scurtă a celor mai grele domenii, extrasă o dată pe lună, oferă adesea un context mai util decât o listă mai lungă extrasă în fiecare noapte.
Unirea pe cheia de domeniu
Când două extrageri se suprapun, uniți-le pe cheia de domeniu și păstrați timestamp-ul mai nou. Unirea nu depinde atunci de care extragere s-a terminat prima.
Logați care extragere a câștigat fiecare rând. Dacă un număr se mută între două rapoarte, acel jurnal vă spune dacă indexul sau unirea s-a schimbat.
Păstrați unirea într-o singură funcție cu un test, deoarece este singurul loc în care se întâlnesc două extrageri.
Repreluarea după un crash
Crashurile se întâmplă. Un deploy repornește workerul, un laptop doarme, un VPN cade și bucla moare la pagina 31 din 50.
Salvați pagina după fiecare apel
Persistați numărul ultimei pagini finalizate după fiecare apel. Reporniți de la acel număr plus unu, nu de la început, și plătiți 2 credite per pagină în loc să cumpărați din nou întreaga extragere.
Salvați-l după parsarea răspunsului, nu înainte. O pagină pe care nu ați reușit să o citiți ar trebui preluată din nou, iar un număr de pagină salvat trebuie să însemne întotdeauna rânduri pe care le aveți.
Un save care se întâmplă o dată pe minut în loc de o dată per apel lasă o fereastră în care un crash poate repeta cheltuiala de credite. Păstrați scrierea mică, astfel încât să fie ieftină de făcut de fiecare dată.
Logați cât durează fiecare save, precum și cât durează fiecare apel. Un save care rivalizează cu apelul însuși indică stratul de stocare, iar asta merită reparat înainte ca bucla să crească.
Upsert pe cheia de domeniu
Păstrați o scriere idempotentă. Upsert fiecare rând pe cheia de domeniu, astfel încât o pagină preluată de două ori să lase un singur rând, nu două.
Folosiți aceeași cheie pe fiecare cale de scriere, inclusiv scriptul manual de reparare. Două căi de scriere cu două chei sunt cauza supraviețuirii duplicatelor la o repreluare.
Un script de reparare este adesea scris în grabă, după o rulare eșuată. Acolo se strecoară de obicei o a doua cheie, așa că revizuiți-l la fel de atent ca bucla principală.
Respingeți o repreluare când sortarea s-a schimbat
Logați sortarea și ordinea alături de numărul paginii. Dacă cineva schimbă sort între un crash și repornire, numărul de pagină salvat nu mai înseamnă aceeași felie. Respingeți repreluarea și începeți curat.
Stocați un mic record de repreluare cu sortarea, ordinea, pagina și timpul. Bucla citește acel record mai întâi și refuză să continue dacă orice câmp nu mai se potrivește cu solicitarea pe care urmează să o facă.
O repreluare respinsă nu este un eșec. Este bucla care spune că pagina salvată nu mai înseamnă aceleași rânduri, iar începerea curată este greșeala mai ieftină.
Rularea buclei în producție
- 1
Începeți cu un domeniu mic
Rulați bucla împotriva unui domeniu cu câteva sute de rânduri, astfel încât oprirea la pagina scurtă să se activeze și să priviți cum funcționează calea de ieșire.
- 2
Verificați o pagină cu ochii
Deschideți un răspuns stocat și confirmați că accessorul citește încă rândurile. Nu aveți încredere într-o parsare pe care nu ați privit-o.
- 3
Păstrați limitele în config
Puneți plafonul și dimensiunea paginii într-un singur fișier config, astfel încât o modificare să apară în review și să nu se ascundă în interiorul unei funcții.
- 4
Logați motivul pentru care bucla s-a oprit
Înregistrați dacă rularea s-a terminat pe o pagină scurtă, pe plafon sau pe o eroare. Acele trei finaluri înseamnă lucruri diferite pentru cineva care citește jurnalul.