Zawartość: Wprowadzenie · Przygotowanie · Podstawowe pojęcia · Krok 1: Instalacja Pythona i bibliotek · Krok 2: Szybki test bez proxy · Krok 3: Żądanie przez mobilne proxy · Krok 4: Rotacja IP · Krok 5: Błędy, timeouty i powtórzenia · Krok 6: Obsługa CAPTCHA · Sprawdzanie wyniku · Typowe błędy · Dodatkowe możliwości · FAQ · Podsumowanie

Wprowadzenie

W tym przewodniku krok po kroku skonfigurujesz środowisko robocze Pythona, wykonasz zapytania do stron internetowych przez mobilne proxy, wyodrębnisz potrzebne dane za pomocą BeautifulSoup i nauczysz się bezpiecznie oraz stabilnie pracować z rotacją IP. Użyjemy biblioteki requests do zapytań sieciowych oraz BeautifulSoup do analizy HTML. W wyniku otrzymasz minimalnie funkcjonalny parser, który: wysyła żądania HTTP przez mobilne proxy, poprawnie zmienia nagłówki na urządzenie mobilne, powtarza zapytania z inteligentnym backoffem w przypadku błędów, rotuje IP po stronie dostawcy mobilnych proxy, starannie obsługuje CAPTCHA, gdy się pojawi, oraz zapisuje dane w wygodnym formacie.

Dla kogo jest ten przewodnik: dla początkujących, którzy dopiero zapoznają się z web scrapingiem; dla specjalistów z pokrewnych dziedzin (marketing, badania, OSINT), którym potrzebne jest proste i niezawodne narzędzie; dla programistów, którzy muszą szybko stworzyć działający prototyp i rozwijać go dalej.

Co trzeba wiedzieć z góry: podstawowe umiejętności obsługi komputera; zrozumienie, czym jest plik, folder i jak uruchamiać wiersz poleceń; minimalne zaznajomienie z Pythonem będzie plusem, ale nie jest konieczne, ponieważ idziemy krok po kroku. Ważne: powinieneś mieć prawne podstawy do przetwarzania wybranych stron i przestrzegać zasad korzystania z tych stron, w tym robots.txt i umów użytkownika.

Ile czasu potrzeba: 2–4 godziny, jeśli wykonasz wszystko krok po kroku. Instalacja środowiska i szybki test zajmą do 30 minut. Podłączenie mobilnego proxy i konfiguracja rotacji — od 40 minut do 1,5 godziny. Dodanie obsługi błędów i CAPTCHA — od 30 do 60 minut.

Rada: Zapisz sobie link do sekcji Krok 4: Rotacja IP i Krok 5: Błędy, timeouty i powtórzenia. Te blokady są najczęściej potrzebne do debugowania i zwiększania stabilności.

⚠️ Uwaga: Cały materiał jest przeznaczony do nauki i praktyki legalnego skrapowania. Nie używaj technik do obejścia ograniczeń dostępu, nie łam prawa i regulaminów stron. Nie omawiamy również VPN i innych sposobów obchodzenia blokad.

Przygotowanie

Potrzebne narzędzia i dostęp: komputer z Windows, macOS lub Linux; dostęp do internetu; zainstalowany Python 3.11–3.13 (zalecana jest aktualna wersja); instalator pakietów pip; edytor tekstu (Visual Studio Code, PyCharm Community lub inny). Będzie Ci również potrzebne konto u dostawcy mobilnych proxy. Jako przykład można kierować się funkcjonalnymi wymaganiami, które oferują usługi klasy mobileproxy.space: oddzielny punkt końcowy proxy, autoryzacja za pomocą loginu i hasła lub przez IP, konfigurowalna rotacja (na timerze lub poprzez API), statystyki zapytań.

Wymagania systemowe: co najmniej 4 GB pamięci RAM; 1–2 GB wolnego miejsca na dysku dla Pythona i bibliotek; stabilny kanał internetowy od 10 Mb/s; możliwość instalacji programów. Poziom uprawnień administratora jest potrzebny tylko do instalacji Pythona (na Windows).

Co pobrać i zainstalować: instalator Pythona; edytor kodu (np. VS Code); biblioteki requests, beautifulsoup4, lxml (do szybszego parsowania HTML).

Tworzenie kopii zapasowych (jeśli to aktualne): przed wprowadzeniem zmian w istniejących projektach utwórz kopię folderu z kodem. Jeśli tworzysz projekt po raz pierwszy, utwórz osobny folder roboczy. Przechowuj plik z danymi dostępowymi do proxy poza repozytorium i, jeśli to możliwe, używaj pliku .env oraz menedżera sekretów.

Rada: Utwórz folder projektu bez spacji i bez cyrylicy w nazwie, np. parser_mobile_proxy. To uprości uruchamianie skryptów i wyeliminuje błędy ścieżek.

Podstawowe pojęcia

Kluczowe terminy prostym językiem: parsowanie lub web scraping — to automatyczne zbieranie publicznie dostępnych danych ze stron internetowych. requests — biblioteka Pythona do wykonywania zapytań HTTP. BeautifulSoup — biblioteka Pythona do analizy HTML i wyodrębniania fragmentów treści według tagów, klas, atrybutów. Proxy — pośredni serwer, który wysyła zapytania do strony w swoim imieniu. Mobilne proxy — proxy wykorzystujące adresy IP mobilnych operatorów. Rotacja IP — zmiana wychodzącego IP z określoną częstotliwością lub na żądanie.

Główne zasady działania: tworzysz żądanie HTTP do strony; Twoje żądanie przechodzi przez mobilne proxy; strona widzi adres proxy, a nie Twój. Otrzymujesz stronę HTML i analizujesz ją przy pomocy BeautifulSoup.

Co ważne przed rozpoczęciem: przestrzegaj robots.txt i zasad strony; nie przeciążaj serwera częstymi zapytaniami; używaj timeoutów; wysyłaj rozsądne ilości równoległych zapytań; obsługuj kody odpowiedzi 4xx i 5xx. Mobilne proxy pomaga zmniejszyć prawdopodobieństwo uruchomienia triggerów fraudowych i ograniczeń, ponieważ mobilne zakresy adresów są aktywnie używane przez rzeczywistych użytkowników. Przy tym stabilność zależy od jakości dostawcy, obciążenia i poprawności Twojego kodu.

⚠️ Uwaga: Nie używaj parsowania do obejścia autoryzacji lub dostępu do zastrzeżonych sekcji bez pozwolenia. Nie próbuj ingerować w działanie strony. Pracuj tylko z otwartymi danymi, do których masz prawo przetwarzania.

Krok 1: Instalacja Pythona i bibliotek

Cel etapu

Zainstalujmy Pythona i niezbędne biblioteki, utwórzmy projekt oraz podstawowe pliki. Po tym kroku będziesz mógł uruchamiać skrypty i wykonywać zapytania HTTP.

Pojedyncza instrukcja

  1. Pobierz i zainstaluj Pythona z oficjalnej strony. Podczas instalacji na Windows zaznacz pole Add Python to PATH. Na macOS możesz użyć menedżera pakietów brew lub oficjalnego instalatora. Na Linuxie użyj repozytoriów swojej systemu.
  2. Sprawdź instalację. Otwórz terminal i wykonaj polecenie: python --version lub python3 --version. Upewnij się, że wersja jest od 3.11 do 3.13.
  3. Utwórz folder projektu, np. C:\Users\twój_użytkownik\parser_mobile_proxy lub /Users/twój_użytkownik/parser_mobile_proxy.
  4. Otwórz folder projektu w edytorze kodu. Utwórz plik main.py oraz plik requirements.txt.
  5. Dodaj do requirements.txt: requests==2.32.3; beautifulsoup4==4.12.3; lxml==5.2.2.
  6. Zainstaluj zależności poleceniem pip install -r requirements.txt lub pip3 install -r requirements.txt.
  7. Sprawdź, czy biblioteki są zainstalowane. W terminalu wykonaj python -c "import requests, bs4, lxml; print('ok')". Powinno wyświetlić ok.

Ważne punkty

Ważne: Instaluj biblioteki w wirtualnym środowisku, aby uniknąć konfliktów wersji. Możesz stworzyć środowisko poleceniem python -m venv .venv i aktywować je source .venv/bin/activate (macOS, Linux) lub .venv\Scripts\activate (Windows), a następnie uruchamiać pip install -r requirements.txt.

Rada: Jeśli nie masz uprawnień administratora, użyj instalacji użytkownika pip install --user -r requirements.txt lub pracuj w wirtualnym środowisku.

Oczekiwany rezultat

Możesz uruchomić prosty skrypt i zaimportować potrzebne moduły bez błędów.

Problem i rozwiązania

  • Komenda python nie została znaleziona. Rozwiązanie: użyj python3 lub upewnij się, że PATH jest ustawiony. Ponownie zainstaluj Pythona z zaznaczeniem Add to PATH.
  • Konflikt wersji lxml. Rozwiązanie: zaktualizuj pip (python -m pip install --upgrade pip), a następnie zainstaluj lxml ponownie.
  • Brak wystarczających praw przy instalacji. Rozwiązanie: aktywuj wirtualne środowisko lub użyj flagi --user.

✅ Sprawdzenie: Komenda python -c "import requests, bs4; print('ready')" wyświetla ready, a plik main.py istnieje w folderze projektu.

Krok 2: Szybki test parsowania bez proxy

Cel etapu

Chcemy zrozumieć, że podstawowa kombinacja requests + BeautifulSoup działa, zanim podłączymy proxy. Wykonamy zwykłe żądanie do strony testowej i wyodrębnimy nagłówek.

Pojedyncza instrukcja

  1. Otwórz plik main.py w edytorze.
  2. Wklej podstawowy kod do żądania i parsowania.
  3. Uruchom skrypt i sprawdź wynik.

Przykładowy kod

import requests; from bs4 import BeautifulSoup; session = requests.Session(); session.headers.update({"User-Agent": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Mobile Safari/537.36"}); url = "https://example.com"; resp = session.get(url, timeout=30); html = resp.text; soup = BeautifulSoup(html, "lxml"); title = soup.title.text.strip() if soup.title else "(brak tagu title)"; print("Status:", resp.status_code, "Nagłówek:", title)

Ważne punkty

Ważne: Używamy mobilnego User-Agent, aby naśladować mobilną przeglądarkę. To pomoże w zgodności z mobilnym proxy w następnym kroku.

Rada: Jeśli strona docelowa może dostarczać różne wersje dla desktopu i urządzeń mobilnych, zapisz HTML do pliku w celu debugowania: open("page.html", "w", encoding="utf-8").write(html). W ten sposób będziesz mógł zbadać strukturę tagów.

Oczekiwany rezultat

Skrypt drukuje kod odpowiedzi i nagłówek strony. To podstawowe sprawdzenie, czy parser widzi HTML i może go przeanalizować.

Problem i rozwiązania

  • Kod 403 lub 404. Rozwiązanie: sprawdź URL; spróbuj zmienić User-Agent; upewnij się, że strona jest dostępna.
  • Timeout. Rozwiązanie: zwiększ timeout do 60, sprawdź połączenie internetowe.
  • Nieodpowiednia kodowanie. Rozwiązanie: użyj resp.encoding = resp.apparent_encoding przed parsowaniem.

✅ Sprawdzenie: Widzisz status 200 i napis Nagłówek: (nazwa strony). W folderze może pojawić się page.html, jeśli zapisałeś HTML.

Krok 3: Żądanie przez mobilne proxy

Cel etapu

Podłącz mobilne proxy do requests, wyślij żądanie i upewnij się, że ruch rzeczywiście przechodzi przez proxy, a nie bezpośrednio. Dodamy również autoryzację i sprawdzimy nagłówki.

Co przygotować

Dane Twojego mobilnego proxy: host (np. proxy.provider.local lub adres IP), port (np. 12345), login i hasło do autoryzacji, bądź potwierdzony biały lista IP, jeśli dostawca autoryzuje przez adres IP. Większość dostawców mobilnych, w tym rozwiązania klasy mobileproxy.space, dostarcza te parametry w panelu klienta.

Pojedyncza instrukcja

  1. Otwórz plik main.py.
  2. Dodaj słownik proxies z danymi Twojego proxy.
  3. Wyślij żądanie przez session.get z parametrem proxies.
  4. Sprawdź, czy odpowiedź przyszła i przeanalizuj stronę.

Przykładowy kod

import requests; from bs4 import BeautifulSoup; PROXY_HOST = "PROXY_HOST"; PROXY_PORT = 12345; PROXY_USER = "USER"; PROXY_PASS = "PASS"; proxy_auth = f"http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}"; proxies = {"http": proxy_auth, "https": proxy_auth}; session = requests.Session(); session.headers.update({"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Mobile/15E148 Safari/604.1", "Accept-Language": "pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7"}); url = "https://example.com"; resp = session.get(url, proxies=proxies, timeout=45); print("HTTP:", resp.status_code); soup = BeautifulSoup(resp.text, "lxml"); print("TYTUŁ:", soup.title.text.strip() if soup.title else "(brak)")

Ważne punkty

Ważne: Jeśli Twój dostawca wymaga autoryzacji przez IP, użyj formatu proxies bez loginu i hasła: "http": f"http://{PROXY_HOST}:{PROXY_PORT}". Upewnij się, że Twój bieżący IP jest dodany do białej listy w panelu dostawcy.

Rada: Przy pierwszym uruchomieniu dodaj parametr verify=False tylko w celach diagnostycznych dla błędów TLS. Nie zostawiaj tego w produkcji. Lepiej zainstalować certyfikaty główne, jeśli dostawca tego wymaga.

Rada: Przechowuj ustawienia proxy w pliku .env: PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS. Załaduj je przez os.getenv lub bibliotekę python-dotenv, aby nie przechowywać sekretów w kodzie.

Oczekiwany rezultat

Otrzymujesz kod 200 i poprawny TYTUŁ. Jeśli na stronie docelowej wyświetla się IP, powinno się różnić od Twojego, ponieważ zapytanie przechodzi przez mobilne proxy.

Problem i rozwiązania

  • 407 Proxy Authentication Required. Rozwiązanie: sprawdź login i hasło; upewnij się, że używasz poprawnego formatu URL z autoryzacją.
  • 403 Forbidden. Rozwiązanie: zmień User-Agent na mobilny; sprawdź nagłówki Accept-Language; zmniejsz częstotliwość zapytań.
  • ConnectionError lub ReadTimeout. Rozwiązanie: zwiększ timeout, sprawdź stabilność proxy u dostawcy, powtórz zapytanie z backoff.

✅ Sprawdzenie: Odpowiedź przychodzi ze statusem 200. TYTUŁ jest poprawny. Jeśli testujesz na stronie, która pokazuje Twój IP, to odpowiada IP mobilnego proxy (sprawdź dashboard dostawcy).

Krok 4: Rotacja adresów IP bezpiecznie i przewidywalnie

Cel etapu

Skonfiguruj zmianę IP mobilnego proxy na timerze lub na żądanie API. To zwiększa odporność parsowania i zmniejsza szanse na napotkanie ograniczeń ochronnych. Zrealizujemy dwa sposoby: cykliczną listę punktów końcowych proxy oraz rotację w ramach jednego punktu końcowego za pomocą API lub timera dostawcy.

Pojedyncza instrukcja

  1. Określ strategię rotacji: na czas (np. co 5–10 minut), na liczbę zapytań (np. co 10–20 zapytań) lub hybrydowo.
  2. Jeśli masz wiele punktów końcowych proxy, przygotuj listę i zrealizuj przełączanie round-robin.
  3. Jeśli dostawca ma API zmiany IP dla jednego punktu końcowego, dodaj wywołanie do kodu i poczekaj na potwierdzony interwał rotacji (zwykle 10–60 sekund).
  4. Weź pod uwagę ograniczenia dostawcy: minimalny interwał rotacji i limit wywołań API na dobę.
  5. Dodaj przerwy i sprawdzenie IP po rotacji, aby upewnić się, że nowe IP jest aktywne.

Przykład round-robin dla kilku punktów końcowych

import itertools, requests; from bs4 import BeautifulSoup; proxies_list = [{"http": "http://user1:pass1@host1:10001", "https": "http://user1:pass1@host1:10001"}, {"http": "http://user2:pass2@host2:10002", "https": "http://user2:pass2@host2:10002"}]; cycle = itertools.cycle(proxies_list); def fetch(url): s = requests.Session(); s.headers.update({"User-Agent": "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Mobile Safari/537.36"}); proxies = next(cycle); r = s.get(url, proxies=proxies, timeout=45); return r; r = fetch("https://example.com/catalog"); print(r.status_code)

Przykład rotacji w ramach jednego punktu końcowego przez API

Wielu dostawców mobilnych proxy, w tym oferty klasy mobileproxy.space, umożliwia zmianę IP w jednym i tym samym punkcie końcowym w określonym czasie (np. co N minut) lub na żądanie w API. W kodzie wygląda to jak dodatkowe zapytanie do usługowego URL dostawcy. Poniżej ogólny szablon. Zastąp URL i token swoimi z panelu dostawcy. Weź pod uwagę limity i okna rotacji.

import time, requests; def rotate_ip(api_rotate_url, timeout=30): try: r = requests.get(api_rotate_url, timeout=timeout); return r.status_code, r.text; except Exception as e: return None, str(e); api_url = "http://PROXY_HOST:PORT/changeip?token=YOUR_TOKEN"; status, body = rotate_ip(api_url); print("ROTATE:", status, body); time.sleep(20); # poczekaj na okno rotacji; s = requests.Session(); proxies = {"http": "http://USER:PASS@PROXY_HOST:PORT", "https": "http://USER:PASS@PROXY_HOST:PORT"}; resp = s.get("https://example.com", proxies=proxies, timeout=45); print(resp.status_code)

Ważne punkty

Ważne: Rotacja nie jest srebrną kulą. Jeśli wykonujesz zbyt wiele zapytań w krótkim czasie, wyzwalacze ochrony mogą zadziałać nawet przy zmianie IP. Utrzymuj umiarkowaną częstotliwość, stosuj losowe opóźnienia i powtórzenia z backoffem.

Rada: Planuj rotację na godziny i według obciążenia. Na przykład jedna rotacja co 10–20 minut oraz zmiana po 15–25 zapytaniach na domenę. To wygładza zachowanie i sprawia, że wygląda naturalnie.

Rada: Zachowuj metadane zapytania: który proxy został użyty, jaki był IP, jaki status zwrócił serwer. To przyspieszy debugowanie.

Oczekiwany rezultat

Twój kod stabilnie przełącza punkty końcowe proxy lub inicjuje zmianę IP w jednym punkcie końcowym i czeka na okno rotacji. Po zmianie zapytania nadal zostaną wykonane ze statusem 200.

Problem i rozwiązania

  • IP nie zmienia się po wywołaniu API. Rozwiązanie: poczekaj dłużej, sprawdź limity; upewnij się, że wywołujesz poprawny URL i token jest aktywny; sprawdź statystyki w panelu dostawcy.
  • W momencie rotacji spada dostępność. Rozwiązanie: w czasie rotacji przełączaj się na inny punkt końcowy, korzystaj z zapasowego kanału w round-robin.
  • Częste 429 Too Many Requests. Rozwiązanie: zwiększ interwał między zapytaniami, zmniejsz całkowitą liczbę równoległych strumieni.

✅ Sprawdzenie: Przy regularnym drukowaniu bieżącego IP w logach widać, że adres zmienia się zgodnie ze strategią rotacji, a status zapytań pozostaje 200–299.

Krok 5: Obsługa błędów, timeoutów i powtórzeń

Cel etapu

Uczynić Twój parser odpornym na problemy sieciowe i tymczasowe błędy serwera. Dodamy timeouty, powtórzenia z eksponencjalnym backoffem, losowe opóźnienia i logowanie.

Pojedyncza instrukcja

  1. Określ maksymalną liczbę powtórzeń (np. 3–5) i podstawowe opóźnienie (np. 1–2 sekundy).
  2. Wprowadź backoff: przy każdej nieudanej próbie zwiększaj oczekiwanie 2 razy plus trochę losowego szumu.
  3. Obsługuj kody 5xx i 429 jako tymczasowe, 4xx traktuj ostrożnie (403 często jest stałą blokadą).
  4. Dodaj zrozumiałe logi, aby wiedzieć, co się dzieje na każdym kroku.
  5. Inkaplusuj wezwanie sieciowe do funkcji fetch_safely, którą będzie łatwo ponownie wykorzystać.

Przykładowy kod

import time, random, requests; from bs4 import BeautifulSoup; def fetch_safely(url, session, proxies=None, max_retries=4, base_delay=1.5, timeout=45): attempt = 0; while attempt <= max_retries: try: r = session.get(url, proxies=proxies, timeout=timeout); if r.status_code in (200, 201): return r; elif r.status_code in (429, 500, 502, 503, 504): delay = base_delay * (2 ** attempt) + random.uniform(0.0, 0.7); time.sleep(delay); attempt += 1; continue; elif r.status_code == 403: return r; else: return r; except (requests.exceptions.ConnectTimeout, requests.exceptions.ReadTimeout, requests.exceptions.ConnectionError) as e: delay = base_delay * (2 ** attempt) + random.uniform(0.1, 0.9); time.sleep(delay); attempt += 1; continue; return None

Ważne punkty

Ważne: Ustalaj rozsądne timeouty: 30–60 sekund dla niestabilnych kanałów, 10–20 sekund dla szybkiej sieci. Nie wyłączaj weryfikacji SSL, jeśli nie ma krytycznej potrzeby.

Rada: Do logów użyj modułu logging. Na początku dodaj minimalną konfigurację: logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s"). To ułatwi diagnostykę.

Rada: Podziel problemy „tymczasowe” i „stałe” błędy. Tymczasowe — retry; stałe — zapisuj i idź dalej, aby uniknąć zapętlenia.

Oczekiwany rezultat

Skrypt kontynuuje pracę przy czasowych błędach i zwraca odpowiedź, lub poprawnie przechodzi do następnego zadania, nie zawieszając się.

Problem i rozwiązania

  • Powtórzenia nie pomagają, zawsze 429. Rozwiązanie: zmniejsz częstotliwość zapytań, wydłuż opóźnienia, zwiększ okno między rotacjami IP.
  • Stałe 403. Rozwiązanie: sprawdź zasady strony, upewnij się, że nagłówki są poprawne, zmniejsz częstotliwość, jeśli to konieczne, użyj oficjalnych API.
  • Częste ConnectionError. Rozwiązanie: sprawdź dostawcę mobilnych proxy; być może potrzebny inny region lub inny port.

✅ Sprawdzenie: Przy symulowaniu błędów widzisz w logach powtórzenia z rosnącym opóźnieniem. Po 1–2 próbach wiele zapytań kończy się sukcesem.

Krok 6: Wykrywanie i obsługa CAPTCHA w sposób legalny

Cel etapu

Naucz się rozpoznawać, że strona zwróciła CAPTCHA i poprawnie reagować: zmniejszać obciążenie, tymczasowo wstrzymywać zapytania, poprawnie używać rotacji IP. Nie omijamy ochrony, działamy w ramach etycznego skrapowania.

Pojedyncza instrukcja

  1. Określ oznaki CAPTCHA na stronach docelowych: obecność słów kluczowych w HTML (captcha, g-recaptcha), formularze z nietypowymi polami, strony-trapery.
  2. Dodaj do kodu sprawdzenie zawartości HTML przed parsowaniem głównej logiki.
  3. Jeśli uruchomiła się CAPTCHA, wykonaj łagodne działania: zwiększ przerwę; zmniejsz częstotliwość na domenie; inicjuj rotację IP; spróbuj wywołać ponowne zapytanie.
  4. Jeśli CAPTCHA pozostaje, zaprzestań automatycznych prób i zbadaj zasady korzystania z strony. Możliwe, że dane są dostępne przez oficjalne API.

Przykładowy kod

from bs4 import BeautifulSoup; import time, requests; def is_captcha(html): text = html.lower(); hints = ["captcha", "g-recaptcha", "hcaptcha", "distil", "cloudflare", "please verify", "are you a human"]; return any(h in text for h in hints); def get_with_captcha_handling(url, session, proxies, rotate_func=None): r = session.get(url, proxies=proxies, timeout=45); if r.status_code == 200 and not is_captcha(r.text): return r; time.sleep(10); if rotate_func: try: rotate_func(); time.sleep(20); except Exception: pass; r2 = session.get(url, proxies=proxies, timeout=60); return r2

Ważne punkty

Ważne: Jeśli CAPTCHA nadal się pojawia, zmniejsz intensywność skanowania, poczekaj na następne okno rotacji lub przełącz na inny punkt końcowy. Przestrzegaj etyki i zasad strony.

Rada: Czasami CAPTCHA pojawia się tylko dla niektórych ścieżek. Zmniejsz częstotliwość tylko dla takich ścieżek, a nie dla całej domeny. To zachowa ogólną szybkość.

⚠️ Uwaga: Nie omawiamy obejść CAPTCHA z wykorzystaniem zewnętrznych usług, skryptów omijania, emulacji przeglądarki i podobnych technik. Pracuj tylko w ramach dozwolonych, korzystaj z oficjalnych API, jeśli są dostępne.

Oczekiwany rezultat

Skrypt umie delikatnie reagować na pojawienie się CAPTCHA: robi przerwę, inicjuje zmianę IP (jeśli dostępne) i powtarza zapytanie. To zmniejsza liczbę fałszywych refusów i pomaga zachować stabilność.

Problem i rozwiązania

  • CAPTCHA przy każdym zapytaniu. Rozwiązanie: radykalnie zmniejsz częstotliwość, używaj różnych interwałów między zapytaniami, przełącz strefę czasową lub region proxy u dostawcy (jeśli dostępne), sprawdź robots.txt.
  • CAPTCHA znika, ale dane są niestabilne. Rozwiązanie: zwiększ timeout, zapisuj i analizuj HTML, porównuj wersje stron dla różnych IP.

✅ Sprawdzenie: Przy sztucznym wyzwalaniu (np. częste zapytania w krótkim czasie) w logach widać przerwy oraz rotację, a po nich — udane odpowiedzi bez CAPTCHA.

Sprawdzanie wyniku

Lista kontrolna

  • Python zainstalowany, zależności dostarczone.
  • Skrypt bez proxy uzyskuje HTML i parsuje nagłówek.
  • Skrypt z mobilnym proxy zwraca status 200.
  • Rotacja IP włączona i sprawdzona.
  • Powtórzenia przy błędach działają, timeouty ustawione.
  • Obsługa oznak CAPTCHA obecna.
  • Dane zapisywane do pliku lub drukowane w konsoli oczekiwanie.

Jak testować

  1. Uruchom podstawowe zapytanie bez proxy i upewnij się, że parsowanie tytułu działa.
  2. Włącz proxy i powtórz zapytanie, porównaj wyniki.
  3. Wywołaj zmianę IP u dostawcy (jeśli dostępne) i powtórz zapytanie po 20–60 sekundach.
  4. Sztucznie zmniejsz timeout do 1–2 sekund i sprawdź, że powtórzenia z backoffem się włączają, a następnie wracają do normy po przywróceniu timeoutu.
  5. Obciąż wiele stron zapytaniami i upewnij się, że przy pojawieniu się oznak CAPTCHA zadawane są przerwy i, jeśli to konieczne, aktywuje się rotacja.

Wskaźniki udanego wykonania

  • Procent udanych zapytań powyżej 90% na „spokojnych” stronach.
  • Kody 429 i 5xx występują rzadko i są obsługiwane przez powtórzenia.
  • Rotacja IP odbywa się w ustalonym harmonogramie, bez długich przestojów.

Rada: Wprowadź metrykę „czas odpowiedzi” i „liczba powtórzeń” i loguj je. To pomoże zrozumieć, kiedy zmieniać strategię rotacji lub częstotliwość zapytań.

Typowe błędy i rozwiązania

  • Problem: 407 Proxy Authentication Required. Przyczyna: błędny login lub hasło, niepoprawny format URL proxy. Rozwiązanie: sprawdź format http://USER:PASS@HOST:PORT, upewnij się, że nie ma nadmiarowych znaków i spacji; jeśli autoryzacja przez IP — usuń login i hasło.
  • Problem: 403 Forbidden. Przyczyna: uruchomiona ochrona strony, niewłaściwy User-Agent lub zbyt częste zapytania. Rozwiązanie: użyj mobilnego User-Agent, zmniejsz częstotliwość, włącz rotację IP, sprawdź Accept, Accept-Language i Referer.
  • Problem: 429 Too Many Requests. Przyczyna: przekroczony limit częstotliwości. Rozwiązanie: dodaj eksponencjalny backoff, zwiększ przerwy, rotację rób rzadziej, rozłóż zapytania na różne pory dnia.
  • Problem: ConnectionError lub ReadTimeout. Przyczyna: niestabilny kanał proxy lub przeciążona sieć. Rozwiązanie: zwiększ timeout, powtórz z backoffem, użyj zapasowego punktu końcowego.
  • Problem: błędne parsowanie, puste dane. Przyczyna: zmieniona struktura HTML lub ładowanie treści przez JavaScript. Rozwiązanie: zaktualizuj selektory BeautifulSoup; jeśli dane generowane są dynamicznie, spójrz na sieciowe zapytania strony i użyj ich oficjalnych punktów końcowych JSON, gdy dostępne i jeśli to dozwolone.
  • Problem: CAPTCHA na każdej stronie. Przyczyna: agresywne obciążenie lub podejrzana aktywność. Rozwiązanie: zmniejsz częstotliwość, zwiększ przerwy, używaj rotacji, sprawdź poprawność nagłówków i przestrzeganie robots.txt.
  • Problem: blokada po kilku udanych zapytaniach. Przyczyna: przewidywalne zachowanie skryptu. Rozwiązanie: wprowadź losowe opóźnienia, zmieniaj kolejność zapytań, zmieniaj proxy, aktualizuj nagłówki.

Rada: Zachowuj przykłady HTML przed i po incydencie. To pomoże szybko odróżnić zmianę struktury od oznak ochrony anty-botowej.

Dodatkowe możliwości

Zaawansowane ustawienia

  • Sesje i ciasteczka: używaj requests.Session do automatycznego przechowywania ciasteczek, to przybliża zachowanie do prawdziwej przeglądarki.
  • Nagłówki: dodawaj Accept, Accept-Language, Referer i DNT w razie potrzeby. Zmieniaj User-Agent z puli mobilnych agentów.
  • Proxy SOCKS: w razie potrzeby podłącz requests[socks]. Jednak mobilne proxy częściej dostarczane są jako HTTP(S).
  • Zapisywanie do CSV lub JSON: po parsowaniu zapisuj dane do plików. To wygodne dla integracji.

Przykład mini-pipeline'a parsowania

import csv, requests, time; from bs4 import BeautifulSoup; MOBILE_UA = "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Mobile Safari/537.36"; session = requests.Session(); session.headers.update({"User-Agent": MOBILE_UA}); proxies = {"http": "http://USER:PASS@HOST:PORT", "https": "http://USER:PASS@HOST:PORT"}; urls = ["https://example.com/page1", "https://example.com/page2"]; rows = []; for u in urls: r = session.get(u, proxies=proxies, timeout=45); if r.status_code == 200: s = BeautifulSoup(r.text, "lxml"); title = s.title.text.strip() if s.title else ""; rows.append({"url": u, "title": title}); time.sleep(2); open("data.csv", "w", newline="", encoding="utf-8"); with open("data.csv", "w", newline="", encoding="utf-8") as f: w = csv.DictWriter(f, fieldnames=["url","title"]); w.writeheader(); w.writerows(rows); print("zapisano:", len(rows))

Optymalizacja

  • Przetwarzanie wsadowe: grupuj zapytania według domen z uwzględnieniem opóźnień i rotacji.
  • Cache: przechowuj już uzyskane strony lokalnie, aby nie wysyłać ich na nowo bez potrzeby.
  • Strategia wytrwałości: planuj czas zapytań na „niepiki” godziny, kiedy strona jest mniej obciążona.

Rada: Jeśli masz wiele zadań, dziel je na mniejsze partie i uruchamiaj po kolei. To zwiększa stabilność i zmniejsza prawdopodobieństwo wystąpienia CAPTCHA.

Rada: Wiele dostawców mobilnych proxy (w tym rozwiązania klasy mobileproxy.space) ma panel kontrolny z czytelną statystyką. Porównuj czas, częstotliwość i kody odpowiedzi — to daje zrozumienie, kiedy właściwie zrobić rotację.

FAQ

Pytanie: Jak zrozumieć, że zapytanie rzeczywiście idzie przez mobilne proxy? Odpowiedź: Sprawdź w panelu dostawcy aktywne połączenia i aktualne zewnętrzne IP, porównaj je z tym, co widzisz w odpowiedziach na stronie. Dodatkowo dostawca zwykle pokazuje statystyki zapytań do punktu końcowego.

Pytanie: Jak wybrać User-Agent: Android czy iOS? Odpowiedź: Wybierz platformę, pod którą działa Twoja treść (mobilna wersja strony). Często agent Android daje przewidywalny rezultat. Testuj oba i zapisuj, gdzie jest mniej refusów.

Pytanie: Jak często zmieniać IP podczas parsowania? Odpowiedź: Podstawowa rekomendacja: nie częściej niż raz na 10–20 minut, lub po 15–25 zapytaniach do domeny. Dostosuj do obciążenia, nie nadużywaj częstej rotacji.

Pytanie: Co zrobić, jeśli strona zwraca treść przez JavaScript? Odpowiedź: Spójrz na sieciowe zapytania strony (w narzędziach dewelopera przeglądarki). Często dane przychodzą przez punkty końcowe JSON. Jeśli dostęp jest legalny i nie narusza zasad, użyj tych punktów końcowych. W przeciwnym razie sprawdź zasady strony.

Pytanie: Czy mogę używać kilku mobilnych dostawców jednocześnie? Odpowiedź: Tak, jeśli to potrzebne dla rozłożenia obciążenia. Ustawiaj round-robin i kontroluj limity każdego dostawcy.

Pytanie: Jak bezpiecznie przechowywać dane dostępowe? Odpowiedź: Użyj zmiennych środowiskowych oraz pliku .env, nie umieszczaj sekretów w repozytorium. W produkcji przechowuj sekrety w menedżerach sekretów.

Pytanie: Jak właściwie zatrzymać skrypt w przypadku masowych błędów? Odpowiedź: Wprowadź licznik nieudanych prób i górny próg. Jeśli z rzędu N zapytań do tego samego domeny zakończy się niepowodzeniem, zrób dłuższą przerwę, zarejestruj incydent i zakończ proces.

Pytanie: Czy potrzebuję lxml, jeśli jest wbudowany parser html.parser? Odpowiedź: Wbudowany parser nadaje się do prostych przypadków. lxml jest szybszy i bardziej odporny na częściowo niepoprawny HTML. Do regularnego parsowania zaleca się lxml.

Pytanie: Co zrobić, jeśli strona zmienia układ? Odpowiedź: Zapisuj testowe strony, dodaj regresyjne testy selektorów. W przypadku zmian aktualizuj logikę BeautifulSoup i pisz funkcje-adaptery pod nową strukturę.

Pytanie: Po co mi mobilne proxy, jeśli zwykłe również działa? Odpowiedź: Mobilne adresy często budzą mniej podejrzeń z powodu specyfiki mobilnych sieci i rozkładu ruchu. To zwiększa szansę na stabilne odpowiedzi przy rozsądnych obciążeniach.

Podsumowanie

Podsumowanie wykonanych działań: zainstalowałeś Pythona oraz biblioteki requests i BeautifulSoup, sprawdziłeś podstawowe parsowanie bez proxy, dodałeś mobilne proxy i upewniłeś się, że zapytania idą przez nie, skonfigurowałeś rotację IP na kilka sposobów, wprowadziłeś obsługę błędów i łagodną reakcję na CAPTCHA. Teraz masz bazowy projekt do stabilnego i etycznego skrapowania publicznych danych.

Co robić dalej: rozwijaj parser pod swoje cele — dodawaj nowe selektory, zapisuj dane w bazie, konfigurowaj harmonogramy uruchomień. Włącz alerty przy spadku udziału udanych zapytań lub wzroście statusów 429 i 403. Dodaj plik konfiguracyjny dla parametrów kontrolnych (częstotliwość, rotacja, timeouty).

Gdzie się rozwijać: zapoznaj się z asynchronicznymi zapytaniami w Pythonie (aiohttp), kolejkami zadań (Celery, RQ), przechowywaniem i analizą danych (SQLite, PostgreSQL, Pandas). Osobno zapoznaj się z prawnymi aspektami przetwarzania danych i interakcjami z witrynami, jak również z oficjalnym dostępem do danych przez legalne API. Dla mobilnych proxy korzystaj z funkcji, podobnych do tych, które oferują nowoczesne serwisy klasy mobileproxy.space: elastyczna rotacja, statystyki, różne regiony i stabilne wsparcie.

Rada: Zapisz ten przewodnik i regularnie wracaj do sekcji Krok 4: Rotacja IP oraz Krok 5: Błędy, timeouty i powtórzenia. To przynosi główny wzrost stabilności i pomaga unikać przestojów.

⚠️ Uwaga: Zawsze sprawdzaj robots.txt i zasady korzystania z wybranych stron. Jeśli zasady zabraniają automatycznego zbierania danych, szanuj zakazy i szukaj legalnych alternatyw, takich jak otwarte lub płatne API.