Du willst das Domain Rating deiner eigenen Domain regelmäßig mitschreiben. Oder das von ein paar Kundenseiten, Wettbewerbern, einem Linkkandidaten. Bisher klickst du dich dafür durch die Ahrefs-Weboberfläche und tippst die Zahl von Hand in eine Tabelle. Geht auch anders. Es gibt einen kostenlosen Endpunkt, ohne API-Key, und du holst den Wert mit Bordmitteln direkt in deine Access-Anwendung oder dein Excel-Sheet.
Das Problem ist nicht der Abruf, sondern die Antwort
Eine REST-Antwort abholen kann VBA seit Jahren über MSXML2.ServerXMLHTTP. Der unangenehme Teil ist das JSON. Der Reflex vieler Entwickler ist, sich den VBA-JSON-Konverter ins Projekt zu ziehen, eine externe Klassendatei mit ein paar hundert Zeilen, nur um anschließend eine einzige Zahl auszulesen. Das ist Aufwand, der in keinem Verhältnis zum Ergebnis steht.
Für genau einen Zahlenwert lohnt keine Bibliothek. Harte Zerlegung der Zeichenkette reicht, ist nachvollziehbar und hat keine Abhängigkeit, die dir bei der nächsten Office-Aktualisierung um die Ohren fliegt.
Was Domain Rating ist, und was nicht
Domain Rating, kurz DR, ist eine Ahrefs-Metrik für die relative Stärke des Backlink-Profils einer Website, gemessen auf einer logarithmischen Skala von 0 bis 100. Logarithmisch heißt: der Sprung von 70 auf 71 ist deutlich schwerer als der von 20 auf 21.
Wichtig für die Einordnung, bevor du anfängst, die Zahl zu überhöhen: DR ist rein linkbasiert und kein Google-Ranking-Faktor. Der Wert taugt zum Vergleichen und zum Beobachten von Trends über die Zeit, nicht als Steuerungsgröße, an der du blind drehst. Genau deshalb ist es sinnvoll, ihn automatisiert mitzuschreiben statt punktuell abzulesen, denn interessant ist die Bewegung, nicht der Einzelwert.
Der kostenlose Endpunkt
Ahrefs stellt unter v3/public/domain-rating-free einen öffentlichen Endpunkt bereit. Kostenlos, kein API-Key, kein Authentifizierungs-Header. Du übergibst eine Domain oder eine vollständige URL als target, dazu das gewünschte Ausgabeformat. Mehr braucht es nicht.
Die Antwort hat einen kleinen Haken, der beim harten Zerlegen der einzige Stolperstein ist. Der Schlüssel ist verschachtelt und heißt zweimal gleich:
{ "domain_rating": { "domain_rating": 67.0 } }
Der äußere Schlüssel zeigt auf ein Objekt, der innere auf die Zahl. Wer naiv das erste Vorkommen von domain_rating greift, landet auf der Klammer, nicht auf dem Wert. Lösung: mit InStrRev von hinten suchen, dann steht man automatisch auf dem inneren, letzten Vorkommen.
Die Funktion
Der folgende Code holt die Antwort ab, prüft den HTTP-Status, zerlegt die Zahl hart heraus und gibt sie als Double zurück. Im Fehlerfall liefert er minus 1 und schreibt einen Klartext in den optionalen Parameter errText. Kein Verweis auf externe Bibliotheken, reines Late Binding.
'==================================================================
' Ahrefs Domain Rating (Free Endpoint, ohne API-Key)
' Laeuft unveraendert in Access VBA UND Excel VBA (Late Binding).
' Rueckgabe: DR als Double (0..100), bei Fehler -1 + errText gesetzt.
' Quelle Endpoint: https://docs.ahrefs.com/en/api/reference/public/get-domain-rating-free
'==================================================================
Public Function AhrefsDomainRating(ByVal target As String, _
Optional ByRef errText As String) As Double
Const ENDPOINT As String = "https://api.ahrefs.com/v3/public/domain-rating-free"
Dim http As Object
Dim url As String, body As String, drText As String
Dim status As Long
errText = ""
AhrefsDomainRating = -1
If Len(Trim$(target)) = 0 Then
errText = "Kein target uebergeben."
Exit Function
End If
url = ENDPOINT & "?target=" & UrlEncode(target) & "&output=json"
On Error GoTo EH
Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
http.setTimeouts 10000, 10000, 10000, 30000 ' resolve, connect, send, receive
http.Open "GET", url, False
http.setRequestHeader "Accept", "application/json"
http.send
status = http.status
body = http.responseText
Set http = Nothing
' --- Fehler-Responses (400/401/403/429/500) liefern {"error":"..."} ---
If status <> 200 Then
Dim apiErr As String
apiErr = ExtractJsonString(body, "error")
If Len(apiErr) > 0 Then
errText = "HTTP " & status & ": " & apiErr
Else
errText = "HTTP " & status & " - " & Left$(body, 300)
End If
Exit Function
End If
' --- 200: inneren domain_rating-Wert extrahieren ---
drText = ExtractDomainRating(body)
If Len(drText) = 0 Then
errText = "domain_rating nicht gefunden. Body: " & Left$(body, 300)
Exit Function
End If
AhrefsDomainRating = Val(drText) ' Val => '.' immer Dezimaltrenner, locale-unabhaengig
Exit Function
EH:
errText = "Fehler " & Err.Number & ": " & Err.Description
AhrefsDomainRating = -1
On Error Resume Next
Set http = Nothing
End Function
'------------------------------------------------------------------
' Inneren domain_rating-Wert holen.
' Response: {"domain_rating":{"domain_rating":67.0}}
' -> InStrRev nimmt das LETZTE (innere) Vorkommen des Schluessels.
'------------------------------------------------------------------
Private Function ExtractDomainRating(ByVal json As String) As String
Dim key As String, p As Long, c As Long, i As Long
Dim ch As String, numChars As String
key = """domain_rating"""
p = InStrRev(json, key) ' inneres Vorkommen
If p = 0 Then Exit Function
c = InStr(p + Len(key), json, ":")
If c = 0 Then Exit Function
i = c + 1
' fuehrende Whitespaces ueberspringen
Do While i <= Len(json)
ch = Mid$(json, i, 1)
If ch <> " " And ch <> vbTab And ch <> vbCr And ch <> vbLf Then Exit Do
i = i + 1
Loop
' erstes signifikantes Zeichen muss numerisch sein (sonst z. B. null)
ch = Mid$(json, i, 1)
If InStr("0123456789+-.", ch) = 0 Then Exit Function
' Zahl einsammeln (inkl. wissenschaftlicher Notation)
Do While i <= Len(json)
ch = Mid$(json, i, 1)
If InStr("0123456789+-.eE", ch) > 0 Then
numChars = numChars & ch
i = i + 1
Else
Exit Do
End If
Loop
ExtractDomainRating = numChars
End Function
'------------------------------------------------------------------
' String-Wert zu einem Schluessel holen (fuer "error").
' Beruecksichtigt escapte Anfuehrungszeichen \"
'------------------------------------------------------------------
Private Function ExtractJsonString(ByVal json As String, ByVal key As String) As String
Dim k As String, p As Long, c As Long, q1 As Long, q2 As Long
Dim i As Long, ch As String
k = """" & key & """"
p = InStr(1, json, k, vbTextCompare)
If p = 0 Then Exit Function
c = InStr(p + Len(k), json, ":")
If c = 0 Then Exit Function
q1 = InStr(c + 1, json, """")
If q1 = 0 Then Exit Function
i = q1 + 1
Do While i <= Len(json)
ch = Mid$(json, i, 1)
If ch = "\" Then
i = i + 2 ' Escape-Sequenz ueberspringen
ElseIf ch = """" Then
q2 = i
Exit Do
Else
i = i + 1
End If
Loop
If q2 = 0 Then Exit Function
ExtractJsonString = Mid$(json, q1 + 1, q2 - q1 - 1)
End Function
'------------------------------------------------------------------
' Minimales URL-Encoding (RFC 3986 unreserved bleibt stehen).
' Hinweis: nur ASCII. IDN-Domains mit Umlauten vorher in Punycode wandeln.
'------------------------------------------------------------------
Private Function UrlEncode(ByVal s As String) As String
Dim i As Long, code As Long, ch As String, out As String
For i = 1 To Len(s)
ch = Mid$(s, i, 1)
code = Asc(ch)
Select Case code
Case 48 To 57, 65 To 90, 97 To 122, 45, 46, 95, 126 ' 0-9 A-Z a-z - . _ ~
out = out & ch
Case Else
out = out & "%" & Right$("0" & Hex$(code), 2)
End Select
Next i
UrlEncode = out
End Function
Zwei Stellen sind nicht offensichtlich. Erstens das InStrRev, das wegen des doppelten Schlüssels von hinten suchen muss. Zweitens das Val am Ende: auf einem deutschen System interpretiert CDbl("67.0") den Punkt als Tausendertrenner oder wirft einen Typkonflikt, je nach Office-Version. Val ignoriert die Regions-Einstellung komplett und nimmt immer den Punkt als Dezimaltrenner. Genau das willst du bei JSON-Zahlen.
Aufruf in Access
Im Direktbereich oder aus einer Prozedur:
Sub TestDR()
Dim e As String, dr As Double
dr = AhrefsDomainRating("sesoft.de", e)
If dr < 0 Then
Debug.Print "Fehler: " & e
Else
Debug.Print "DR sesoft.de = " & dr
End If
End Sub
Wer den Wert mitschreiben will, packt das Ergebnis in eine kleine Verlaufstabelle nach dem Muster reines Einfügen, eine Zeile pro Abruf mit Domain, Wert und Zeitstempel. So bekommst du die Bewegung über Wochen, und die ist aussagekräftiger als jede Momentaufnahme.
Excel: als Zellfunktion und als Sammel-Makro
Der Code oben läuft in Excel VBA unverändert, weil er nichts aus der Access-Bibliothek braucht. Kopier die vier Prozeduren in ein Standardmodul, fertig. Für die Tabellen-Fraktion gibt es zwei Wege.
Erstens als Zellfunktion. Ein dünner Wrapper macht das Ergebnis zellfreundlich, indem er den Fehlertext direkt in die Zelle schreibt statt über einen ByRef-Parameter:
' In Excel als UDF nutzbar: =DR(A2)
Public Function DR(ByVal target As String) As Variant
Dim e As String, v As Double
v = AhrefsDomainRating(target, e)
If v < 0 Then
DR = "Fehler: " & e
Else
DR = v
End If
End Function
Damit schreibst du in eine Zelle schlicht =DR(A2) und ziehst die Spalte runter. Der entscheidende Punkt: Jede Neuberechnung löst einen neuen HTTP-Abruf aus. Für eine Handvoll Zellen ist das egal, für eine lange Liste wird es lahm und reizt das Limit des kostenlosen Endpunkts aus.
Deshalb zweitens für größere Listen ein Sammel-Makro, das einmal über den Bereich läuft und feste Werte schreibt, also nicht bei jeder Neuberechnung erneut zieht:
' Liest Domains aus Spalte A ab Zeile 2, schreibt DR nach Spalte B,
' Zeitstempel nach Spalte C. Pause gegen das Rate-Limit.
Sub DR_Batch()
Dim ws As Worksheet, lastRow As Long, r As Long
Dim e As String, v As Double
Set ws = ActiveSheet
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
For r = 2 To lastRow
If Len(Trim$(ws.Cells(r, "A").Value)) > 0 Then
v = AhrefsDomainRating(CStr(ws.Cells(r, "A").Value), e)
If v < 0 Then
ws.Cells(r, "B").Value = "Fehler: " & e
Else
ws.Cells(r, "B").Value = v
End If
ws.Cells(r, "C").Value = Now
DoEvents
Application.Wait Now + TimeSerial(0, 0, 1) ' 1 Sekunde Pause
End If
Next r
MsgBox "Fertig: " & (lastRow - 1) & " Zeilen geprueft."
End Sub
Der Unterschied in der Praxis: Die UDF ist bequem für den schnellen Blick, das Makro ist die saubere Variante für eine Wettbewerbsliste, die du einmal pro Woche aktualisierst.
Wo der Ansatz an Grenzen stößt
Drei Dinge solltest du wissen, bevor du das in den Produktivbetrieb nimmst.
Der kostenlose Endpunkt ist mengenbegrenzt. Bei zu vielen Abrufen in kurzer Zeit kommt ein HTTP 429 zurück, den der Code sauber abfängt und als Klartext meldet. Bau die Pause aus dem Batch-Makro ein, dann bleibst du im grünen Bereich.
Die freien Werte können gerundet oder leicht zeitverzögert sein gegenüber dem, was du im bezahlten Ahrefs-Konto siehst. Für Trendbeobachtung reicht das, für Vertragszahlen nicht.
Und die wichtigste Grenze ist keine technische: DR ist linkbasiert und kein Google-Ranking-Faktor. Die Zahl ist ein grober Indikator für Link-Popularität, mehr nicht. Wer seine Inhaltsstrategie an einer einzelnen Drittmetrik ausrichtet, optimiert am Ziel vorbei.
Für Entwickler, die weiterdenken
Das Muster, eine externe REST-Antwort ohne Bibliothek hart zu zerlegen, trägt weit über diesen einen Endpunkt hinaus. Tankerkönig, Wechselkurse, Wetterdienste, Webshop-Schnittstellen: Überall, wo eine API einen überschaubaren JSON-Brocken liefert, ist die harte Zerlegung der schlankere Weg als eine eingebundene Klassenbibliothek. Den vollständigen Code dieses Beitrags kannst du eins zu eins übernehmen, die beiden Hilfsfunktionen für Zahl und String sind generisch.
Wenn dich nicht der Code interessiert, sondern die Frage, was es deinem Betrieb bringt, Daten aus solchen Außenquellen automatisch in deine bestehende Access- oder Excel-Landschaft zu holen, statt sie von Hand abzutippen oder dafür neue Software zu kaufen: Darum geht es im Kern bei der Anbindung von Altsystemen an die Außenwelt. Ein unverbindliches Erstgespräch dazu gibt es über sesoft.de/kontakt.
Quellen
- Ahrefs API Reference, Domain rating free (Endpunkt, Parameter, Antwortstruktur): https://docs.ahrefs.com/en/api/reference/public/get-domain-rating-free
- Ahrefs Blog, Domain Rating: What It Is & What It’s Good For (Definition, logarithmische Skala, linkbasiert): https://ahrefs.com/blog/domain-rating/
Autor
Sönke Schäfer ist selbstständiger IT-Berater und Datenarchitekt aus Sierksdorf in Ostholstein. Er entwickelt seit über 25 Jahren mit Microsoft Access, VBA und SQL Server und verbindet gewachsene Datenbankbestände im norddeutschen Mittelstand mit externen Schnittstellen, von REST-APIs über WordPress bis zur Power Platform. Mehr zur Person unter Der Datenschäfer.


