Recept

Backlinks finder i Python: en prospekteringslista på fyrtio rader

Hitta domäner som länkar till dina konkurrenter men inte till dig, betygsätt dem i ett anrop och sortera CSV-filen. Ett genomgående exempel med hypotetiska siffror finns nedan.

Workshop-bänk med utkastningsverktyg och en röd tråd som förbinder punkter på papper

Logiken innan koden

Tre anrop gör jobbet. intersect tar två till tio domäner och returnerar vilka som länkar till flera av dem. refdomains på din egen sida ger mängden att subtrahera. bulk_dr betygsätter sedan vad som finns kvar.

Kostnaden per körning är liten, och aritmetiken är värd att göra en gång. Två credits för intersecten, två för din egen lista, en för betygssättning av upp till 2 000 domäner. Fem credits är $0.0005.

Ordning betyder något. Subtrahera innan du betygsätter.

Människor betygsätter ofta allt först och filtrerar senare. Det är bakvänt. Betygsättning kostar lite, men det slösar mycket tid när CSV-filen har femtiotusen rader. Klipp ner listan genom överlappning först, be om DR på överlevnaderna och behåll allt i en vanlig dict så att en andra körning kan återanvända resultatet från igår.

prospects.py

Domäner i RIVALS är platshållare. Fältnamn läses med .get, så kontrollera en rå rad från din egen körning innan du litar på en kolumn.

python
import csv, json, os, urllib.request as u, urllib.parse as p
KEY = os.environ['LZ_KEY']
ME = 'mysite.example'
RIVALS = ['rival-a.example', 'rival-b.example', 'rival-c.example']
def get(**kw):
    q = p.urlencode(kw)
    with u.urlopen(f'https://linkzoid.pro/api.php?{q}&key={KEY}', timeout=30) as r:
        d = json.load(r)
    if not d['ok']:
        raise SystemExit(d)
    return d
gap = get(action='intersect', q=','.join(RIVALS), per=1000)['rows']
mine = {r.get('domain') for r in get(action='refdomains', q=ME, per=1000)['rows']}
fresh = [r.get('domain') for r in gap if r.get('domain') not in mine]
scores = get(action='bulk_dr', domains=','.join(fresh[:2000]))['rows']
with open('prospects.csv', 'w', newline='') as f:
    wr = csv.writer(f)
    for row in scores:
        wr.writerow([row.get('domain'), row.get('dr')])
print(len(fresh), 'candidates')

Genomgående exempel, hypotetiska siffror

Uppfunnen körning för en liten nischblogg; din kommer att skilja sig
StegRader utCredits
intersect av 3 konkurrenter640 domäner2
Minus dina egna refererande domäner410 kvar2
bulk_dr på de 410410 betygsatta1
Behåll DR 20 och högreca 1200
Manuell granskning av de 30 översta30 sidor öppnade0

Från CSV till outreach, utan att skicka spam

01

Sortera efter överlappning

Domäner som länkar till två eller tre av dina konkurrenter är de som har en saklig anledning att länka till dig. Sätt dem först.

02

Öppna trettio manuellt

Titta på sidan som länkar till konkurrenten. Är det en resurslista, en recension, ett nyhetsinlägg? Endast vissa av dessa accepterar en ny post.

03

Skriv en mening om varför

Säg vad din sida tillför som konkurrentens sida inte gör. Om du inte kan säga det i en mening, hoppa över den sidan.

04

Logga vad du skickade

Lägg till kolumner för datum, kontakt och resultat till samma CSV, och commit:a den. Nästa kvartal kommer du att tacka dig själv.

Misstag och åtgärder

Prospekteringsskript går fel på samma få ställen
MisstagVarför det skadarÅtgärd
Sortering enbart efter DRStora kataloger och skrapare flyter upp till toppenSortera efter överlappningsantal först, DR andra
Att maila allt över en gränsLäser ut som spam, kostar goodwillÖppna de 30 översta manuellt
URL-kodning manuelltKommatecken och snedsträck bryter fråganAnvänd urllib.parse.urlencode
Att skicka 3 000 domäner i ett anropÖver 2 000-gränsenDela upp listan, ett credit per chunk
Att lita på DR som kvalitetDet är en logaritmisk skala för antalet refererande domänerBehandla det som en sorteringsnyckel, inte ett omdöme
Två små buskar och ett stort ekträd som delar solljus i en trädgård

Att välja konkurrenter som delar din läsare

Konkurrenter bestämmer vad intersecten returnerar. En backlinks finder är bara så bra som listan du matar in den. Tre direkta konkurrenter för samma läsare ger en ren överlappning, medan en jättestad publikation som rankar för allt ger dig tusentals länkar som säger inget om din sida.

Säg att du driver en liten blogg om cykelreparation. Dina konkurrenter kan vara två reparationsbloggar och en butik med ett starkt guideavsnitt. Det är en fin uppsättning. Lägg till en nationell tidning och listan fylls med sidor som aldrig skulle länka till en cykelblogg.

Två till tio domäner är fönstret som ändpunkten accepterar, så välj uppsättningen inom det. Håll listan kort nog att du kan namnge varje konkurrent från minnet. Korta listor är lättare att försvara.

Varför jättestor hubbar förorenar uppsättningen

Kataloger och aggregat länkar till nästan allt. De dyker upp i varje intersect och begraver de få domäner som länkar ut av verkligt intresse. Läs toppen av den sorterade listan innan du litar på den.

En vanlig exkluderingsfil fixar de flesta av dessa. Håll domänerna du aldrig vill ha i en textfil, en per rad. Ladda den till en set och ta bort matchningar innan betygsättningsanropet, så att credits bara går till kandidater värda att läsa.

Att hålla konkurrenter och din egen sida isär

Din egen domän ska aldrig vara en konkurrent. Det låter uppenbart, men en kopierad lista från ett gammalt projekt bär ofta med sig den, och då rapporterar intersecten dina egna länkar tillbaka till dig.

Sätt konkurrenterna i en config-dict högst upp i skriptet, med en kommentar om varför varje en är där. Nästa månad kommer du ihåg anledningen, och en främling som läser repo:t kommer också.

Att läsa de råa raderna innan du filtrerar

Koden läser varje fält med .get, vilket stoppar en saknad nyckel från att krascha körningen. Den döljer också en fel nyckel. Skriv ut en rad från intersecten innan du skriver någon filter, och titta på fältnamnen och typen av varje värde.

Ett betyg som anländer som text sorteras som text, så 9 hamnar efter 80. Konvertera det till ett nummer en gång, precis efter anropet, och resten av skriptet kan förbli enkelt.

Normalisera domäner innan du jämför

Samma sida kan visas med ett www.-prefix i en lista och utan det i en annan. Gör allt till gemener och ta bort prefixet innan du jämför set. Annars kan din egen sida se ut som en ny kandidat.

Avslutande snedsträck och vilka som helst utrymmen från en klistrad lista orsakar samma problem. En enkel rengöringsfunktion kostar mindre än ett bortkastat betygsättningsanrop.

Håll en daterad kopia av varje körning

Skriv varje körning till en daterad fil, och behåll den föregående. Du kan då skilja nya kandidater från de du redan sett, och se när en konkurrent började länka någon annanstans.

Daterade filer är också det enklaste sättet att felsöka ett konstigt resultat. Öppna de två filerna sida vid sida och förändringen är oftast uppenbar.

Betygsätt bara vad som överlever

Bulk-anropet tar upp till 2 000 domäner i ett credit. Skicka det överlevnaderna av subtraktionen, aldrig hela intersecten. I det uppfunna exemplet ovan kostade 640 rader och 410 rader samma att betygsätta i ett anrop, men den mindre listan är mycket lättare att läsa.

Stenvåg med en mässingsvikt och en grov sten i separata skålar

Frågor innan du kör findern

De flesta av frågorna människor tar med sig till denna del av jobbet handlar om kostnad, sortering och vad som händer när ett anrop misslyckas.

Kostar en prospekteringslista mycket att bygga?

Inte mycket. Receptet använder intersect, refdomains och bulk_dr, så fem credits per körning i den storlek som visas, vilket är $0.0005. En omkörning nästa månad kostar samma. Din egen tid, spenderad på att läsa sidor, är den verkliga kostnaden.

Varför inte sortera intersecten efter DR och sluta där?

DR räknar refererande domäner på en logaritmisk skala. Stora kataloger stiger till toppen oavsett deras relevans, så sortera efter överlappning först och använd DR som tie breaker, inte huvudnyckeln.

Kan jag skicka outreach till allt i CSV?

Du kan, men det är en dålig användning av listan. Öppna sidan som länkar till konkurrenten, avgör om en ny post passar, och skriv bara då. CSV:n är en kortlista, inte en mailinglista.

Hur många konkurrenter ska jag börja med?

Tre är en bra start, inom två till tio-området som intersecten accepterar. Lägg till fler bara när den första körningen returnerar för få rader att rangordna.

Vad händer om min egen domän inte har några refererande domäner än?

Då tar subtraktionen bort ingenting, och varje intersect-rad blir en kandidat. Det är korrekt, men listan kommer att vara lång. Klipp ner den genom överlappning och läs de trettio översta manuellt.

Behöver skriptet en betald nyckel?

Ja. Intersect-, refdomains- och bulk_dr-anropen är prisade per credit. Den gratis översiktsåtgärden behöver ingen nyckel, och $100 registreringskredit täcker många körningar av denna storlek.

Innan ett enda meddelande skickas ut

  • Öppna kandidatsidan och bekräfta att den länkar till konkurrenten, inte bara till en länklista.
  • Kontrollera att sidan passar din läsare, inte bara ditt nyckelord.
  • Ta bort alla domäner du redan kontaktat, och logga datumet bredvid den.
  • Skriv en mening om vad din sida tillför, eller släpp kandidaten.
  • Skicka i små batchar, så att svar faktiskt kan läsas.

Att köra findern i ett schema

Prospekteringslistor blir gamla långsammare än de flesta förväntar sig. Månadsvis är tillräckligt. Nya länkar från en konkurrent dyker upp med den månatliga uppdateringen, så en körning varannan vecka fångar de flesta av dem. Veckovisa körningar reproducerar oftast förra veckans fil, vilket är varför samma backlinks finder kan köras utan tillsyn utan mycket brus.

Den sundaste rytmen är månatlig för betygsättningen och en snabb titt på de översta raderna efter varje körning. Behåll subtraktionssteget i samma jobb, så att listan aldrig inkluderar vad du redan har.

Håll nyckeln utanför filen

Skriptet läser nyckeln från miljön, så den sitter aldrig i repo:t. Ställ in LZ_KEY som en hemlighet i din scheduler, eller exportera den från en fil som förblir utanför git.

En crontab-rad kan anropa samma skript med variabeln inställd framför den. Kontrollera att filen som håller nyckeln har tighta behörigheter på servern.

Misslyckas innan CSV skrivs

En 401 eller en 402 ska stoppa körningen, och så ska en ok-flagga som läser false. Koden raisear innan filen öppnas, så en misslyckad körning skriver aldrig över igår CSV med en delvis en.

Logga utgiften med varje körning

Varje svar bär _credits, så skriv ut saldot i slutet av jobbet. Över några månader säger den raden dig om ett schema kostar vad du planerade, och om en loop har börjat hämta sidor igen.

Para ihop det med SQLite diff om du vill ha historiken i en databas istället för en mapp med filer.

En ord om vad DR kan och inte kan säga

DR här är round(100 gånger log(ref_domains + 1) över log(20 000 000,0)). Det stiger med refererande domäner och inget annat. Ha det i åtanke. En sida kan sitta på 55 och ändå vara värdelös för dig.

Använd den för att rangordna, läs sedan. Titta på vad sidan publicerar, om den länkar ut till hundra orelaterade butiker, och om något på den ändrades nyligen. Dessa kontroller tar en minut per sida, och inget skript ersätter dem.

När listan är ren, behåll den som en daterad fil och kör om i en månad. Actions runbook visar hur du schemalägger det, och n8n-jämförelsen täcker no-code-alternativet om din outreach-person föredrar det.

Betygs- och storleksnoteringar

Varje anrop returnerar upp till 1 000 rader och faktureras en gång, så att bläddra igenom 5 000 intersect-rader kostar 10 credits, eller $0.001. Djup paginering stoppar vid 50 000 rader. Använd sort och order=desc på servern istället för att sortera en stor lista i Python efteråt.