google.com/goto: læs Location med HEAD
Google Search lægger ikke altid den endelige URL i resultatets href længere. Organiske resultater peger på https://www.google.com/goto?url=CAES…. Det er ikke det gamle google.com/url?q=…: parameteren er ikke en kodet URL. Den afkodes ikke.
Google skal alligevel kende destinationen. Den lægges i HTTP-headeren Location, når du kalder /goto. Det er den read, vi bruger.
Eksempler i curl, Python og Node: github.com/automdev/google-goto-url-fix. Automs Google Search-API laver hoppet på serveren.
Udrulningen og baggrunden: google.com/goto: Googles anti-scraping-opdatering.
Én sætning
Følg ikke redirectet. Læs Location.
GET /goto?url=CAES… HTTP/1.1
Host: www.google.com
HTTP/1.1 302 Found
Location: https://www.linkedin.com/in/satyanadella
HEAD beder kun om headers. GET med redirect: "manual" (eller allow_redirects=False) læser det samme. Google svarer sommetider 402 (eller en anden status) med Location: læs headeren, også når det ikke er et 3xx.
curl
curl -sI --max-redirs 0 \
-H 'Referer: https://www.google.com/search' \
'https://www.google.com/goto?url=CAES...' \
| grep -i '^location:'
-I er HEAD. Uden -L følger curl ikke. Linjen Location: er den rigtige URL.
Samme read med GET:
curl -sD - -o /dev/null --max-redirs 0 \
-H 'Referer: https://www.google.com/search' \
'https://www.google.com/goto?url=CAES...' \
| grep -i '^location:'
Python
import requests
goto = "https://www.google.com/goto?url=CAES..."
r = requests.head(
goto,
allow_redirects=False,
headers={"Referer": "https://www.google.com/search"},
timeout=10,
)
print(r.status_code, r.headers.get("Location"))
Hvis HEAD er tom, prøv igen med GET uden at følge:
r = requests.get(goto, allow_redirects=False, timeout=10)
print(r.headers.get("Location"))
Node
const res = await fetch(goto, {
method: "HEAD",
redirect: "manual",
headers: { Referer: "https://www.google.com/search" },
});
console.log(res.status, res.headers.get("location"));
I en browser kan et manuelt 3xx dukke op som opaqueredirect og skjule headeren. I Node er headers synlige.
Hvorfor ikke afkode CAES?
Blobben er ikke et offentligt URL-protobuf. Det er en uigennemsigtig reference. Kun Google kender målet og lægger det i Location ved hoppet. At lime en synlig titel ("LinkedIn · Satya Nadella") sammen til en URL er en dårlig idé.
href er /goto. Siden kender stadig URL’en.
Google kan ikke skjule destinationen helt. Den har brug for den rigtige URL for at tegne SERP’en: synligt domæne, favicon, attributionsblok. De værdier ligger stadig på siden, typisk i et datascript nederst, og i et internt store (W_jd), som SERP-JavaScriptet læser.
Derfor «renser» links sig i nogle browsere efter en musebevægelse: et script læser W_jd og omskriver hvert /goto-href til den rigtige URL. Det dækker kun organisk under #rso div[data-rpos] med en attributionsblok. AI Overviews bliver på /goto. Det kræver en live side og den første musebevægelse. Et headless fetch af HTML’en udløser det ikke. Chrome lader ofte /goto-hrefs stå.
Et andet læk sidder på linket «Oversæt denne side». Hvis UI-sproget ikke matcher resultatsproget, tilføjer Google den control, og den rene URL ligger ofte dér. Latin (Accept-Language: la) vises næsten hver gang, fordi næsten ingen sider er på latin.
Det er forklaringer på, hvad siden stadig indeholder. Det er skrøbeligt: Google kan omdøbe W_jd, ændre scriptet eller fjerne oversættelses-controlen. Det giver heller ikke et stabilt API-felt.
Den holdbare read er stadig Location på /goto. Ingen live DOM, intet muse-event, intet sprogtrick.
Hos Autom
Google Search-API’et opløser allerede /goto og returnerer den endelige URL i organic_results[].link.
curl -s https://api.autom.dev/v1/google/search \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"linkedin.com/in satya nadella","gl":"us","hl":"en"}'
Kode og README: github.com/automdev/google-goto-url-fix.
Relateret læsning
- google.com/goto: Googles anti-scraping-opdatering
- Google fjernede num=100
- Google sagsøger SerpAPI: hvad SearchGuard afslører
1.000 gratis forespørgsler på Autom pricing, API-nøgle på app.autom.dev/register.