google.com/goto: odczyt Location przez HEAD
Google Search nie zawsze wstawia już końcowy URL do href wyniku. Wyniki organiczne wskazują na https://www.google.com/goto?url=CAES…. To nie jest stare google.com/url?q=…: parametr nie jest zakodowanym URL-em. Nie dekoduje się go.
Google i tak musi znać cel. Wkłada go do nagłówka HTTP Location, gdy wywołasz /goto. Tego odczytu używamy.
Przykłady w curl, Pythonie i Node: github.com/automdev/google-goto-url-fix. API Google Search Autom wykonuje ten hop na serwerze.
Rollout i kontekst: google.com/goto: anti-scraping Google.
Jedno zdanie
Nie podążaj za przekierowaniem. Odczytaj 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 prosi tylko o nagłówki. GET z redirect: "manual" (lub allow_redirects=False) czyta to samo. Google czasem zwraca 402 (lub inny status) z Location: czytaj nagłówek nawet gdy to nie jest 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 to HEAD. Bez -L curl nie podąża. Linia Location: to prawdziwy URL.
Ten sam odczyt przez 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"))
Jeśli HEAD jest pusty, spróbuj ponownie z GET bez podążania:
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"));
W przeglądarce ręczne 3xx może przyjść jako opaqueredirect i ukryć nagłówek. W Node nagłówki są widoczne.
Dlaczego nie dekodować CAES?
Blob nie jest publicznym protobufem URL. To nieprzezroczyste odniesienie. Tylko Google zna cel i wkłada go do Location przy hopie. Sklejanie URL z widocznej nazwy ("LinkedIn · Satya Nadella") to zły pomysł.
href to /goto. Strona nadal zna URL.
Google nie może całkowicie ukryć celu. Potrzebuje prawdziwego URL, żeby narysować SERP: widoczna domena, favicon, blok atrybucji. Te wartości nadal są na stronie, zwykle w skrypcie danych na końcu, i w wewnętrznym store (W_jd), który czyta JavaScript SERP.
Dlatego w niektórych przeglądarkach linki «czyszczą się» po ruchu myszy: skrypt czyta W_jd i przepisuje każdy href /goto na prawdziwy URL. Obejmuje tylko organic pod #rso div[data-rpos] z blokiem atrybucji. AI Overviews zostają na /goto. Potrzeba żywej strony i tego pierwszego ruchu myszy. Headless fetch HTML tego nie odpala. Chrome często zostawia href /goto bez zmian.
Kolejny wyciek siedzi na linku «Przetłumacz tę stronę». Jeśli język UI nie zgadza się z językiem wyników, Google dodaje ten kontroler, a czysty URL często tam jest. Łacina (Accept-Language: la) pojawia się prawie zawsze, bo prawie żadna strona nie jest po łacinie.
To wyjaśnienia tego, co strona nadal zawiera. Są kruche: Google może zmienić nazwę W_jd, skrypt albo usunąć kontroler tłumaczenia. Nie dają też stabilnego pola API.
Trwały odczyt to nadal Location na /goto. Bez żywego DOM, bez zdarzenia myszy, bez sztuczki językowej.
W Autom
API Google Search już rozwiązuje /goto i zwraca końcowy URL w 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"}'
Kod i README: github.com/automdev/google-goto-url-fix.
Powiązane artykuły
- google.com/goto: anti-scraping Google
- Google usunął num=100
- Google pozywa SerpAPI: co ujawnia SearchGuard
1 000 darmowych zapytań na cenniku Autom, klucz API na app.autom.dev/register.