Większość scraperów zawodzi, zanim serwer odczyta choćby jeden header.
Serwer analizuje sygnaturę na poziomie połączenia, którą Twój klient wysyła w sieci, i decyduje, czy jesteś przeglądarką, czy biblioteką klienta, która tylko ją udaje. Python requests, Go net/http, zwykły curl: każdy z nich przekazuje charakterystyczny fingerprint w momencie nawiązywania połączenia. Strony stosujące zabezpieczenia (Datadome, Akamai, Imperva, zarządzana warstwa Cloudflare) zrywają połączenie lub zwracają stronę challenge, zanim Twój ciąg User-Agent będzie miał jakiekolwiek znaczenie.
To właśnie rozwiązuje unblocker: true w FourA. W zeszłym miesiącu dopracowaliśmy elementy, które zapewniają jego niezawodne działanie.
Co nowego
unblocker: true to pojedyncza flaga w dowolnym wywołaniu /api/single. Po jej włączeniu wykonujemy trzy rzeczy: wstrzykujemy zestaw nagłówków przeglądarki, wysyłamy request przez warstwę transportową zgodną z sygnaturą prawdziwej przeglądarki i dekompresujemy odpowiedź serwera (gzip, brotli, deflate). Dwie pierwsze funkcje były dostępne od wersji beta. Trzecia (automatyczna dekompresja brotli) została wdrożona 25 marca, a przypinanie wersji dodaliśmy następnego dnia, aby nagłówki i transport były zawsze w pełni zsynchronizowane.
Jak to działa
Oto jak wygląda request:
curl -X POST "https://api.foura.ai/api/single" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true
}'
Pod spodem działają trzy warstwy.
Wstrzykiwanie nagłówków. Ustawiamy pełny zestaw nagłówków przeglądarki: User-Agent, Sec-Ch-Ua, Sec-Ch-Ua-Platform, Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, Accept, Accept-Language oraz Accept-Encoding. Kolejność ma znaczenie. Prawdziwe przeglądarki wysyłają je w określonej sekwencji, a biblioteki detekcji to weryfikują.
Sygnatura połączenia. Nasza warstwa transportowa odwzorowuje strukturę bajtową aktualnej sesji przeglądarki: tę samą kolejność rozszerzeń, te same preferencje szyfrów, te same niuanse handshake. Standardowy cURL, Python requests i Go net/http generują sygnatury, które chroniona infrastruktura natychmiast oznacza jako boty.
Automatyczna dekompresja. Gdy opcja unblocker jest włączona, ustawiamy Accept-Encoding na gzip, deflate, br, a warstwa transportowa automatycznie rozpakowuje treść. Otrzymujesz zdekodowany string (lub Buffer, jeśli przekażesz returnBuffer: true). Bez ręcznej obsługi brotli i bez rozbieżności między nagłówkami a treścią, gdy strona wybierze deflate zamiast gzip.
Dlaczego przypinanie wersji ma znaczenie
Sygnatury połączeń są powiązane z konkretnymi wersjami. Szczegóły komunikacji sieciowej przeglądarki zmieniają się z miesiąca na miesiąc, a strona precyzyjnie analizująca fingerprint natychmiast zauważy różnice. Przypinamy wszystkie zmienne elementy razem, aby nagłówki, obiekty navigator i sygnatura połączenia wskazywały tę samą wersję przeglądarki.
Brzmi drobiazgowo i dokładnie tak jest. Sami natrafiliśmy na problem niespójności podczas marcowej migracji monorepo, gdy jeden z komponentów zaktualizował się automatycznie, a reszta przestała do niego pasować. Rozwiązaniem były dwa commity: przypięcie zmieniającego się elementu i zasada, by nigdy nie ufać menedżerowi pakietów w kwestii automatycznej synchronizacji.
Wpływ
W testach wewnętrznych na stronach weryfikujących klienta (finanse, turystyka, duży e-commerce) różnica między unblocker: false a unblocker: true oznacza różnicę między stroną z wyzwaniem a kodem 200. Zwykły klient HTTP często od razu dostaje 403. Ten sam URL z unblocker: true pobiera stronę bez problemu, ponieważ request wygląda dokładnie tak, jak deklarowana przeglądarka.
W przypadku stron, które nie sprawdzają fingerprintów (większość publicznych API, starsze szablony CMS, zasoby chronione tylko przez rate limit na adres IP), wyłączenie unblocker jest w porządku i pozwala zaoszczędzić kilka milisekund negocjacji. Używaj tej opcji tam, gdzie jest potrzebna.
Dla zaawansowanych użytkowników
Kilka wzorców, które warto znać.
Połącz unblocker z residential proxy, gdy cel sprawdza również reputację IP. IP z centrum danych w połączeniu z idealną sygnaturą połączenia nadal zostanie zablokowane na ASN-ach wpisanych przez stronę na czarną listę. Nasz endpoint proxy (/api/proxy) rotuje adresy według domeny docelowej, więc dodanie "proxy": "residential" do requestu zazwyczaj wystarcza.
Pomiń unblocker przy wywołaniach API JSON, które nie wymagają zachowania przeglądarki. Dodatkowe nagłówki mogą wyglądać podejrzanie dla API oczekującego klienta programistycznego, na przykład gdy backend komunikuje się z własnym mikroserwisem.
Jeśli witryna weryfikuje użytkownika za pomocą JavaScriptu przed wyświetleniem strony, sam unblocker nie wystarczy. Potrzebujesz endpointu przeglądarki, który uruchamia JavaScript strony w pełnej przeglądarce. To inny produkt z innym cennikiem kredytów, który opisaliśmy w artykule Browser Tasks: How to Scrape JavaScript-Heavy Sites.
Możesz także połączyć unblocker z blokiem validate, aby odrzucać odpowiedzi, które technicznie zwracają kod 200, ale zawierają stronę z challenge'em:
{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true,
"validate": {
"data": { "fail": ["captcha", "Access Denied"] }
}
}
To zamienia ciche błędy w błędy sklasyfikowane, co ma znaczenie dla monitorowania wskaźnika sukcesu w dashboardzie.
Co dalej
Przeglądarki wydają nową stabilną wersję co cztery tygodnie. Aktualizujemy nasz stos, aby za nimi nadążyć. Nie musisz niczego zmieniać po swojej stronie: unblocker: true stale wskazuje na wersję przeglądarki zweryfikowaną przez nas end-to-end.
Trudniejsza praca jest jeszcze przed nami. Weryfikacje HTTP/3 pojawiają się już w większych serwisach, transport QUIC jest trudniejszy do precyzyjnego odwzorowania niż starsze warstwy transportowe, a migracja ze statycznych zestawów nagłówków w stronę w pełni dynamicznej emulacji właśnie się zaczyna. Chronione strony zaczęły sprawdzać kolejność ramek HTTP/2, a różnica między "biblioteką wyglądającą jak przeglądarka" a "prawdziwą przeglądarką" będzie się zacierać z obu stron. Napiszemy o tym, gdy wdrożymy te zmiany.