Scarnox · Blog

Scrapuj bez blokad: praktyczny przewodnik z kodem

Blokada podczas scrapingu zwykle oznacza jedną z trzech rzeczy: wysłałeś zbyt wiele żądań zbyt szybko, twój klient wyglądał zupełnie nie jak przeglądarka albo znany bot, albo twój adres IP znajduje się na liście, której strona ufa mniej. Wszystkie trzy możesz ograniczyć kilkoma nawykami: zauważaj blokadę wcześnie, zwalniaj, gdy strona cofa cię, zachowuj spójną i uczciwą tożsamość i używaj proxy tylko tam, gdzie jest to właściwe. Ten przewodnik omawia każdy z nich z działającym kodem. Stosuj go na stronach, które wolno ci scrapować.

Rozpoznaj blokadę

Blokada nie zawsze wygląda jak strona z błędem. Obserwuj:

Zapisuj kod statusu i krótką próbkę treści dla każdego błędu. Blokadę, której nie widzisz w logach, nie da się naprawić.

Cofaj się z ponowieniami

Gdy strona mówi „zwolnij”, twój kod powinien zwolnić wyraźnie. Standardowym podejściem jest wykładniczy backoff z limitem prób. Uwzględnia też Retry-After, gdy strona go wysyła:

import time
import requests

session = requests.Session()
session.headers.update({
    "User-Agent": "ExampleBot/1.0 (+https://example.com/bot)",
    "Accept-Language": "en-US,en;q=0.9",
})

def polite_get(url: str, max_attempts: int = 4) -> requests.Response:
    delay = 2.0
    resp = None
    for _ in range(max_attempts):
        resp = session.get(url, timeout=30)
        if resp.status_code not in (429, 503):
            return resp
        retry_after = resp.headers.get("Retry-After", "")
        wait = float(retry_after) if retry_after.isdigit() else delay
        time.sleep(wait)
        delay *= 2
    return resp  # wciąż zablokowany: zwróć ostatnią odpowiedź do obsługi przez wywołującego

resp = polite_get("https://example.com/products?page=1")
print(resp.status_code, len(resp.text))

Zwróć uwagę, czego ta funkcja nie robi. Nie ponawia 403 i nie rotuje tożsamości, żeby obejść jedną blokadę. 403 to decyzja, by przestać, a nie zagadka do rozwiązania.

Diagnozuj blokadę krok po kroku

Gdy przebieg zaczyna zawodzić, przejdź przez te sprawdzenia, zanim cokolwiek zmienisz:

  1. Spójrz na pierwszy nieudany adres URL i jego kod statusu. Blokada zwykle zaczyna się w konkretnym punkcie, a nie losowo.
  2. Porównaj tempo żądań w minutach przed pierwszym błędem. Seria to najczęstsza przyczyna.
  3. Sprawdź, czy błąd jest przypisany do jednej ścieżki, jednej sekcji lub jednej pory dnia.
  4. Pobierz ten sam adres raz ręcznie w zwykłej przeglądarce. Jeśli przeglądarka go załaduje, różnica leży we wzorcu twoich żądań. Jeśli przeglądarka też jest zablokowana, strona na razie przestała serwować ci tę stronę.
  5. Dopiero potem zmieniaj kod. Najpierw zwolnij, po drugie dodaj backoff, a tożsamość przeglądaj na końcu.

Zmiana kilku rzeczy naraz uniemożliwia ustalenie, co pomogło.

Zachowaj spójną, uczciwą tożsamość

Scrapery są blokowane, gdy ich tożsamość zmienia się między żądaniami albo gdy nie pasuje do reszty ruchu. Pojedyncza sesja z jednym, wyraźnym User-Agentem to najprostsza stabilna tożsamość. Nazwij swojego bota, dodaj link kontaktowy i wysyłaj tylko nagłówki, które wysłałby zwykły klient. Zmienianie User-Agentów, żeby wyglądać jak wielu różnych odwiedzających, to forma unikania wykrycia i zwykle zwiększa prawdopodobieństwo blokady, a nie je zmniejsza.

Jeśli strona serwuje inną treść przeglądarkom niż zwykłym klientom HTTP, używaj prawdziwej przeglądarki dla tych stron i zachowaj ten sam limit tempa. To uprawniona droga, która utrzymuje sensowny wzorzec żądań.

Używaj proxy z rozwagą

Proxy zmienia adres, z którego pochodzi żądanie. To narzędzie do uprawnionych potrzeb, takich jak testowanie z konkretnego regionu na stronie, którą wolno ci testować, albo rozłożenie obciążenia na własną infrastrukturę. Nie jest sposobem na ucieczkę od limitu, który strona ci nałożyła. Format proxy to ten, którego używają typy zadań proxy:

proxies = {
    "http": "http://user:pass@proxy.example.net:8000",
    "https": "http://user:pass@proxy.example.net:8000",
}
resp = session.get("https://example.com/products", proxies=proxies, timeout=30)

Wybór typu proxy to osobna kwestia, omówiona w proxy rezydencjalnych a datacenter i rotujących proxy do scrapingu.

Gdy blokada staje się captcha

Niektóre strony odpowiadają na problem z tempem captcha zamiast twardą blokadą. Rozsądna kolejność to: zatrzymaj się, zwolnij, sprawdź ponownie zasady, a dopiero potem rozważ rozwiązanie. Dla widgetów PopularCaptcha żywe API Scarnox zwraca token, który wysyłasz w polu h-captcha-response. Dla innych typów captcha sprawdź listę obsługiwanych na żywo, ponieważ reCAPTCHA, Cloudflare Turnstile, GeeTest, AWS WAF i Arkose są wkrótce. Szczegółowy przewodnik to captcha w web scrapingu.

Jeśli zaczynasz widzieć blokady na jakiejś stronie, przyczyną niemal zawsze jest wzorzec żądań. Unikanie captcha przy scrapingu omawia nawyki, które temu zapobiegają.

Scrapuj odpowiedzialnie

Dalsze kroki