Hromadné DR pro seznam klientů jako 40řádkový Python skript
Máte tabulku domén a dashboard, který potřebuje jednu hodnotu na řádek. Kontroler domén zpětných odkazů pro tento účel je především o propojení komponent a tento skript je právě tímto propojením.

Skript
Čte domains.txt, odesílá 200 domén na požadavek, ukládá každou surovou odpověď do SQLite a vypisuje náklady běhu. Ukládáme celý payload, protože názvy polí je nejlepší kopírovat ze skutečné odpovědi, ne z blogového příspěvku.
import os, sqlite3, time, json, requests
BASE = "https://seomasters.dev/api.php"
KEY = os.environ["SEO_API_KEY"]
BATCH = 200
db = sqlite3.connect("dr.db")
db.execute("create table if not exists raw (ts int, batch text, body text)")
domains = [d.strip() for d in open("domains.txt") if d.strip()]
spent = 0
for i in range(0, len(domains), BATCH):
chunk = domains[i:i + BATCH]
for attempt in range(4):
try:
r = requests.get(BASE, timeout=30,
params={"action": "bulk_dr", "domains": ",".join(chunk)},
headers={"Authorization": "Bearer " + KEY})
break
except requests.RequestException:
time.sleep(2 ** attempt)
else:
raise SystemExit(f"network gave up at batch {i}")
if r.status_code in (401, 402):
raise SystemExit(f"HTTP {r.status_code}: fix the key or top up, do not retry")
body = r.json()
if not body.get("ok"):
raise SystemExit(f"ok=false at batch {i}: {json.dumps(body)[:300]}")
db.execute("insert into raw values (?,?,?)", (int(time.time()), str(i), r.text))
db.commit()
print(body.get("_credits"))Co jednotlivé části dělají
action=bulk_dr
Jeden kredit za volání. Dokumentovaný strop je 2 000 domén na volání.
domains=
GET parametr. Endpoint také přijímá tělo POST, což je lepší volba, když jsou seznamy dlouhé. Před plným spuštěním otestujte oddělovač se dvěma doménami.
BATCH = 200
Naše zvyklost, ne limit: 200 krátkých domén drží URL výrazně pod běžnými limity proxy.
_credits
Přítomno v autentizovaných odpovědích: cena volání a zbývající zůstatek. Vypsání této hodnoty v každé dávce je nejlevnější stopa auditu.
Surový sloupec body
Parsovat budete později, jednou, na základě uložené vzorky. Změna schématu na naší straně vás pak stojí jen dotaz, ne opakování celého běhu.

Hypotetický běh s aritmetikou
Toto je příklad, ne příběh zákazníka. Představte si agenturu, která sleduje 1 800 domén klientů a potenciálních klientů v Google Sheetu a chce aktualizovat DR každé pondělí.
Při 200 doménách na dávku to je 9 požadavků. Devět požadavků po 1 kreditu je 9 kreditů, což je 0,0009 $ za běh, a za 52 pondělí celkem 468 kreditů, což se zaokrouhlí na méně než pět centů.
Náklad není omezením. Omezením je čerstvost. Index se rebuilduje přibližně měsíčně, takže týdenní běhy budou ve třech ze čtyř týdnů ukazovat stejné hodnoty a měsíční běch zachytí stejný vývoj za přibližně čtvrtinu volání.
Takže jej spusťte měsíčně a týdenní tabulku ponechte pro lidské úpravy. Podrobnosti o tom, proč se skóre může pohybovat, najdete v referenci DR.
Co se může pokazit v tomto skriptu
| Příznak | Příčina | Řešení |
|---|---|---|
SystemExit: HTTP 402 | Zůstatek je nulový | Doplňte kredit na stránce účtu, spusťte znovu; hotové dávky jsou již v SQLite |
SystemExit: HTTP 401 | Proměnná prostředí je prázdná nebo je překlep v klíči | Vypište len(KEY) a zkontrolujte prefix sk_ |
ok=false na dávce 3 | Špatná hodnota v seznamu, např. úplná URL | Odstraňte protokol a cestu před odesláním, viz tabulka chyb |
| Stejné DR jako minulý týden | Index ještě nebyl rebuildován | Očekávané; srovnejte měsíčně |
| Dlouhá URL zamítnuta | Příliš velká dávka pro GET | Snížit BATCH nebo přejít na tělo POST |
Velikost dávky, GET a POST pro dlouhé seznamy
Strop je 2 000 domén na volání a skript odesílá desetinu této hodnoty. Každé volání stojí stejný fixní kredit, takže velikost dávky je otázkou selhání a payloadu, ne ceny.
Proč 200 a ne 2 000
Menší dávka selhává levně. Pokud běh přeruší uprostřed, ocas, který je třeba opakovat, je dlouhý jen jednu dávku, ne celý seznam.
Kratší seznamy také udržují uložený body dostatečně malý na to, aby šel zkontrolovat očima, když vypadá hodnota špatně, a to je důležitější než několik ušetřených volání.
Pokud později zvýšíte velikost dávky, udělejte to jednou, v jedné konstantě, a spusťte test se dvěma doménami. Větší číslo není důvodem test přeskočit.
Naplánujte dávku podle délky běhu, kterou snesete, ne podle stropu. Noční úloha, která musí skončit před rannou zprávou, si může dovolit menší, bezpečnější dávky než jednorázové doplnění dat.
GET pro krátké seznamy, POST pro dlouhé
Formát GET vkládá každou doménu do URL. To funguje, dokud proxy nebo záznam v logu nezkreslí dotaz, proto výše uvedená tabulka doporučuje nejprve snížit dávku. Jakmile seznamy porostou, odesílejte stejnou hodnotu domains v těle POST.
Před plným spuštěním otestujte oddělovač a kódování se dvěma doménami. Přilepená čárka se projeví v první dávce a je levnější ji tam zjistit.
Tělo POST také drží seznam mimo přístupové logy, které mnoho hostitelů výchoze ukládá. To je malý zisk pro soukromí u seznamů klientů a stojí to jeden další řádek záhlaví ve skriptu.
Při přechodu na POST ponechte verzi GET jako zálohu pro krátké seznamy. Dvě cesty kódu zní náročně, ale jedna malá funkce, která vybere cestu podle délky, je snadno čitelná a testovatelná.
Oříznout a odstranit duplicity před prvním požadavkem
Odstraňte mezery, převedte hostitele na malá písmena a vyhoďte duplicity, než cokoliv opustí váš stroj. Duplicita zabírá místo pod stropem 2 000 domén a způsobuje nesoulad mezi počtem v tabulce a počtem v odpovědi.
Vyberte jedno pravidlo pro www. a aplikujte ho v jedné funkci, aby se stejný web nikdy nevyhledával pod dvěma pravopisy. Jakýkoliv kontroler domén zpětných odkazů, který škáluje nad několik stovek jmen, potřebuje tuto disciplínu.
Co by měl říhat log běhu
Vypište hodnotu _credits po každé dávce a vedle ní zapište číslo dávky, počet domén a čas. Tyto tři čísla odpoví téměř každé otázce, kterou si finance oddělení kladne k běhu.
Běh, který nic nevypisuje až do konce, vám nedá tušit, kdy zasekne. Řádek na dávku je levný a změní tichý visící stav na číslo dávky, které můžete identifikovat.
Udržujte log ve stejné složce jako soubor SQLite, aby jedna záloha zkopírovala obojí. Log, který žije jinde, je ten, který při incidentu chybí.

Tři rozšíření, za která stojí věnovat odpoledne
Uložte číslo dávky vedle časového razítka. Již je v tabulce výše a umožňuje spustit pouze dávku, která selhala po 402 uprostřed běhu.
Napište malý pohled přes surovou tabulku, jakmile jste zkontrolovali skutečnou odpověď: doména, skóre, staženo-datum. Dashboardy čtou pohled a surový sloupec zůstává jako důkaz, pokud bude hodnota zpochybněna.
Spuštějte z GitHub Actions nebo z běžného cronu na malém VPS. Obojí je v pořádku. Důležité je, aby úloha končila s nenulovým exit kódem při jakémkoliv selhání, protože tiché selhání vypadá jako zastaralý graf o tři týdny později.
Třídění výstupu je záležitostí front-endu. Seřaďte portfolio podle skóre, seskupte ho nebo ho porovnejte s dr_distribution (1 kredit), abyste viděli, kde se každý klient nachází mezi všemi 181 132 097 doménami.
Posun polí a surová tabulka
Dlouhodobě běžící úloha tiše selže, když se změní tvar pole. Surový sloupec tam je, aby selhání zůstalo zřetelné a levné na opravu.
Nejprve uložte surové tělo
Surový sloupec je pojistná síť. Pokud se přejmenuje pole nebo se objeví nové, spustíte dotaz nad uloženými odpověďmi místo placení za celý seznam znovu. Pozdější parsování je levné, zatímco opětovný nákup není.
Udržujte také jeden uložený vzorek týdně ve vlastním souboru. Když parsování selže, porovnáte vzorek tohoto týdne s tím posledním, který fungoval.
Uložte tělo přesně tak, jak bylo přijato, bez formátování a bez ořezávání. Jakákoliv změna, kterou provedete s textem před uložením, je změnou, kterou později nemůžete vrátit.
Jak drift vypadá v praxi
Řekněme, že dashboard najednou ukazuje prázdná skóre pro jednu dávku. Surový řádek stále existuje. Otevřete jej, porovnejte jeho klíče se vzorkem z minulého týdne a rozdíl zjistíte během několika minut.
Řešení je pak jediný řádek v pohledu, ne opakování celého seznamu. To je celý smysl ukládání těla.
Udržujte vedle pohledu krátkou poznámku, které pole čte a kdy jste jej naposledy zkontrolovali proti skutečné odpovědi. Zapsání poznámky zabere minutu a ušetří dlouhé hledání později.
Migrace seřadit podle dat
Vytvořte surovou tabulku před pohledem a pohled před jakýmkoliv dotazem dashboardu. Udržujte příkazy CREATE v jednom souboru, spusťte je v pořadí a zaznamenejte číslo dávky k každému řádku.
Oddělené databáze pro každého klienta driftují stejně jako jedna sdílená databáze. Pravidlo zůstává stejné: jedno uložené tělo na volání a jedno místo pro parsování.
Udržet parser vedle testů
Umístěte funkci parsování do stejného repozitáře jako test, který čte jedno uložené tělo. Test je místo, kde se posunuté pole projeví poprvé, dlouho předtím, než se tak stane v grafu.
Pojmenujte pole, která parser očekává, v jedné konstantě blízko začátku souboru. Recenzent pak uvidí všechny závislosti na tvaru odpovědi na jedné obrazovce.
První běh v pořadí
- 1
Otestovat jednu doménu
Volat
bulk_drs jednou doménou, kterou znáte, a přečíst celou odpověď. Zapište si klíče, než začnete psát jakýkoliv parsovací kód. - 2
Spustit dvě dávky
Dodat skriptu seznam 400 domén, aby běžely přesně dvě dávky. Zkontrolujte, zda pokles
_creditsodpovídá dvěma voláním po jednom kreditu. - 3
Spočítat uložené řádky
Otevřete soubor SQLite a porovnejte počet řádků s počtem dávek. Nesoulad znamená, že byla dávka přeskočena nebo uložena dvakrát, a to zjistíte dříve, než to dashboard.
- 4
Naplánovat celý seznam
Pouze po čistém průběhu testů přidejte celý seznam a plánovač. Udržte nenulový exit kód, aby selhání bylo zřetelné v první noc.
Před naplánováním
- Nejprve odstranit duplicity a převést na malá písmena
- Rozhodnout jednou, v jedné funkci, zda
www.zůstane nebo jde - Udržet klíč v úložišti tajných klíčů, ne v crontab
- Upozornit na nenulový exit kód
- Spustit čísla rozpočtu kreditů pro svůj vlastní objem