Bir müşteri listesi için toplu DR, 40 satırlık bir Python işi olarak
Bir alan adı tablonuz ve her satır için bir sayıya ihtiyaç duyan bir panonuz var. Bu iş için bir backlink alan adı denetleyici çoğunlukla altyapı işidir ve bu betik o altyapıyı sağlar.

Betik
domains.txt dosyasını okur, istek başına 200 alan adı gönderir, her ham yanıtı SQLite'ta saklar ve çalışmanın maliyetini yazdırır. Alan adlarının bir blog yazısından değil, gerçek bir yanlıştan kopyalanmasının en iyi yol olduğunu düşündüğümüz için tüm yükü depolarız.
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"))Her parçanın ne yaptığı
action=bulk_dr
Her çağrı başına bir kredi. Belgelenmiş üst sınır, çağrı başına 2.000 alan adıdır.
domains=
Burada bir GET parametresi. Uç nokta aynı zamanda bir POST gövdesini de kabul eder; bu, listeler uzunlaştığında daha iyi bir seçenektir. Tam çalışmadan önce iki alan adıyla ayırıcıyı test edin.
BATCH = 200
Bizim alışkanlığımız, bir sınır değil: 200 kısa alan adı, URL'yi ortak proxy limitlerinin çok altında tutar.
_credits
Kimlik doğrulaması yapılan yanıtlarda bulunur: çağrının maliyeti ve kalan miktar. Her partide yazdırmak, en ucuz denetim izidir.
Ham body sütunu
Daha sonra, depolanan bir örneğe karşı tek seferlik olarak ayrıştırırsınız. Tarafımızdaki bir şema değişikliği, size bir yeniden çalıştırmadan ziyade bir sorgu maliyeti getirir.

Hipotetik bir çalışma, aritmetik ile
Bu bir müşteri hikayesi değil, bir örnektir. Google Sheet'te 1.800 müşteri ve potansiyel müşteri alan adını takip eden ve her Pazartesi DR'yi güncellemek isteyen bir ajansı hayal edin.
Parti başına 200 alan adı ile bu 9 istektir. Her biri 1 kredi olan 9 istek, 9 kredi eder veya çalışma başına 0,0009 $ eder ve 52 Pazartesi boyunca toplam 468 kredi eder ki bu da beş kuruşun altına yuvarlanır.
Maliyet kısıtlayıcı faktör değildir. Tazeliktir. İndeks yaklaşık olarak aylık olarak yeniden oluşturulur, bu nedenle haftalık çalıştırmalar dört haftanın üçünde aynı değerleri gösterecektir ve aylık bir çalışma, çağrıların yaklaşık dörtte biri için aynı hareketi yakalar.
Bu yüzden aylık olarak çalıştırın ve haftalık sheet'i insan düzenlemeleri için koruyun. Puanun neden sabit kalabileceğine dair detaylar DR referansında yer almaktadır.
Bu betikte neler ters gidebilir
| Belirti | Neden | Çözüm |
|---|---|---|
SystemExit: HTTP 402 | Bakiye sıfır | Hesap sayfasından yükleme yapın, yeniden çalıştırın; tamamlanan partiler zaten SQLite'tadır |
SystemExit: HTTP 401 | Ortam değişkeni boş veya anahtar yazım hatası | len(KEY) yazdırın ve sk_ önekini kontrol edin |
3. partide ok=false | Listede hatalı değer, örneğin tam URL | Göndermeden önce şemayı ve yolu temizleyin, hata tablosuna bakın |
| Geçen haftayla aynı DR | İndeks henüz yeniden oluşturulmadı | Beklenen; aylık olarak karşılaştırın |
| Uzun URL reddedildi | Parti, GET için çok büyük | BATCH değerini düşürün veya POST gövdesine geçin |
Uzun listeler için parti boyutu, GET ve POST
Üst sınır çağrı başına 2.000 alan adıdır ve betik bunun onda birini gönderir. Her çağrı aynı düz kredi maliyetine sahiptir, bu nedenle parti boyutu fiyat sorunu değil, hata ve yük sorunu açısından önemlidir.
Neden 2.000 yerine 200
Daha küçük bir parti ucuz başarısız olur. Bir çalışma ortada durursa, yeniden çalıştırılmaya bırakılan kuyruk bir liste uzunluğunda değil, bir parti uzunluğundadır.
Kısa listeler ayrıca her kaydedilen body'yi gözle taranabilir kadar küçük tutar; bu, birkaç kaydedilen çağrından daha önemlidir.
Daha sonra parti boyutunu artırırsanız, bunu bir kez, bir sabitte yapın ve iki alan adı testini yeniden çalıştırın. Daha büyük bir sayı, testi atlamak için bir neden değildir.
Partiyin, üst sınıra göre değil, tolerans edebileceğiniz çalışma uzunluğuna göre planlayın. Sabah raporu başlamadan önce bitmesi gereken bir gece işi, tek seferlik bir geri yüklemeden daha küçük, daha güvenli partiler alabilir.
Kısa listeler için GET, uzunlar için POST
GET formu, her alan adını URL'ye ekler. Bu, bir proxy veya log satırı sorguyu kesene kadar çalışır; bu nedenle yukarıdaki tablo öncelikle toplu iş boyutunu düşürmenizi önerir. Listeler büyüdükçe, aynı domains değerini bir POST gövdesi içinde gönderin.
Tam çalıştırmadan önce iki alan adı ile ayırıcıyı ve kodlamayı test edin. Bir fazladan virgül ilk topluda ortaya çıkar ve orada görmek daha ucuzdur.
Bir POST gövdesi, çoğu sunucunun varsayılan olarak tuttuğu erişim loglarından listeyi de uzak tutar. Bu, müşteri listeleri için küçük bir gizlilik kazanımıdır ve betikte ekstra bir başlık satırı maliyeti doğurur.
POST'a geçtiğinizde, kısa listeler için GET sürümünü bir yedek olarak bırakın. İki kod yolu ağır görünse de, uzunluğa göre birini seçen tek bir küçük fonksiyon hem okunması hem de test edilmesi kolaydır.
İlk istemden önce boşlukları temizleyin ve yinelenenleri kaldırın
Makinenizden bir şey ayrılırken boşlukları silin, ana alan adını küçük harfe çevirin ve yinelenenleri atın. Yinelenenler, 2.000 alan adı üst sınırının altında yer kaplar ve tablonuzdaki sayı ile yanıtın içindeki sayı arasında tutarsızlığa neden olur.
www. için tek bir kural seçin ve bunu tek bir fonksiyonda uygulayın, böylece aynı site iki farklı yazılışla asla sorgulanmaz. Yüzlerce ismi aşan her backlink alan adı denetleyicisi bu disiplini gerektirir.
Çalıştırma logunda ne yazmalı
Her toplu işten sonra _credits değerini yazdırın ve yanına toplu iş numarasını, alan adı sayısını ve süreyi yazın. Bu üç sayı, bir finans okuyucusunun bir çalıştırma hakkında sorduğu neredeyse tüm soruları yanıtlar.
Sadece sona kadar hiçbir şey yazdırmayan bir çalıştırma, takıldığında size bir ipucu vermez. Her toplu iş için bir satır yazmak ucuzdur ve sessiz bir takılmayı, isimlendirilebilecek bir toplu iş numarasına dönüştürür.
Logu SQLite dosyasıyla aynı klasörde tutun, böylece bir yedekleme ikisini de kopyalar. Başka bir yerde yaşayan bir log, bir olay sırasında kaybolan o logdur.

Öğleden sonraya değecek üç eklenti
Zaman damgasının yanına toplu iş numarasını kaydedin. Bu zaten yukarıdaki tabloda var ve bir 402 hatası sonrası sadece başarısız olan topluyu yeniden çalıştırmanızı sağlar.
Gerçek bir yanıtı inceledikten sonra ham tablo üzerinde küçük bir görünüm oluşturun: alan adı, puan, çekilme tarihi. Panolar bu görünümü okur ve bir sayı sorgulanırsa ham sütun kanıtınız olarak kalır.
Bunu GitHub Actions veya küçük bir VPS'teki düz bir cron ile çalıştırın. İkisi de uygundur. Önemli olan, herhangi bir hatada işin non-zero (sıfırdan farklı) bir çıkış koduyla sonlanmasıdır, çünkü sessiz bir hata üç hafta sonra solmuş bir grafik gibi görünür.
Çıktıyı sıralamak bir ön uç meselesidir. Portföyü puana göre sıralayın, gruplandırın veya her müşterinin 181.132.097 alan adı arasındaki konumunu görmek için dr_distribution (1 kredi) ile karşılaştırın.
Alan kayması ve ham tablo
Uzun süren bir iş, bir alanın yapısı değiştiğinde sessizce başarısız olur. Ham sütun, bu başarısızlığın gür ve düzeltmesi ucuz kalmasını sağlar.
Ham gövdeyi önce kaydedin
Ham sütun bir güvenlik ağıdır. Bir alan yeniden adlandırılırsa veya yeni bir alan eklenirse, tüm listeyi tekrar satın almak yerine depolanan yanıtlar üzerinde bir sorgu çalıştırırsınız. Sonradan ayrıştırma ucuzdur, yeniden satın alma ise değildir.
Ayrıca her hafta için bir kayıtlı örneği kendi dosyasında da saklayın. Bir ayrıştırma bozulduğunda, bu haftaki örneği son çalışan örnekle karşılaştırın.
Gövdeyi alındığı şekilde, hiçbir biçimlendirme veya temizleme yapmadan yazın. Kaydetmeden önce metin üzerinde yaptığınız herhangi bir değişiklik, daha sonra geri alınamayan bir değişikliktir.
Pratikte bir kayma nasıl görünür
Bir panonun aniden bir toplu iş için boş puanlar gösterdiğini varsayın. Ham satım hala oradadır. Onu açın, anahtarlarını geçen haftaki örnekle karşılaştırın ve farkı birkaç dakikada bulun.
Düzeltme ardından görünümde tek bir satırdır, tüm listenin yeniden çalıştırılması değildir. Gövdenin depolanmasının tüm amacı budur.
Görünümün hangi alanı okuduğunu ve son kez gerçek bir yanıtla ne zaman kontrol edildiğini belirten görünümün yanına kısa bir not yazın. Notu yazmak bir dakika sürer, ancak daha sonra uzun bir aramadan kurtarır.
Geçişleri verilerle birlikte sıralayın
Ham tabloyu görünümden önce oluşturun ve görünümü herhangi bir panel sorgusundan önce oluşturun. Oluşturma ifadelerini tek bir dosyada tutun, sırayla çalıştırın ve her satırla birlikte toplu iş numarasını kaydedin.
Müşteri başına ayrılmış veritabanları, tek bir paylaşılan veritabanında olduğu şekilde kaymaya ayrılır. Kural aynı kalır: her çağrı için bir depolanan gövde ve onu ayrıştırmak için tek bir yer.
Ayrıştırıcıyı testlerin yanında tutun
Ayrıştırma fonksiyonunu, kayıtlı bir gövdeyi okuyan bir testle aynı depoda tutun. Test, bir panoda ortaya çıkmadan çok önce kaymış bir alanın ilk ortaya çıktığı yerdir.
Ayrıştırıcının beklediği alan adlarını dosyanın başındaki bir sabit içinde adlandırın. Bir gözden geçiren, yanıtın yapısına olan tüm bağımlılıkları tek bir ekranda görebilir.
İlk çalıştırma, sırayla
- 1
Bir alan adı ile test edin
Bildiğiniz tek bir alan adı ile
bulk_drçağrısı yapın ve tüm yanıtı okuyun. Herhangi bir ayrıştırma kodu yazmadan önce anahtarları not edin. - 2
İki toplu iş çalıştırın
Betige 400 alan adı içeren bir liste verin, böylece tam olarak iki toplu iş çalışsın.
_creditsdüşüşünün, her biri 1 kredi olmak üzere iki çağrıya eşleştiğini kontrol edin. - 3
Depolanan satırları sayın
SQLite dosyasını açın ve satır sayısını toplu iş sayısı ile karşılaştırın. Bir tutarsızlık, bir toplunun atlandığı veya iki kez depolandığı anlamına gelir ve bunu panodan önce bulursunuz.
- 4
Tam listeyi zamanlayın
Sadece testler temiz çalıştıktan sonra tam listeyi ve zamanlayıcıyı ekleyin. Non-zero çıkışı koruyun, böylece bir hata ilk gecede gür hale gelir.
Zamanlamadan önce
- Listeyi önce yinelenenlerden arındırın ve küçük harfe çevirin
www.'nin kalıp kalmayacağına tek bir fonksiyonda karar verin- Anahtarı bir gizli depoda tutun, crontab'ta değil
- Non-zero bir çıkış kodunda uyarı verin
- Kendi hacminiz için kredi bütçesi sayılarını çalıştırın