Jak zeskrobać ogłoszenia z Craigslist: pojazdy, wynajem i zlecenia

Craigslist to kopalnia danych strzeżona przez agresywne limity IP. Oto struktura URL dla każdego miasta, matematyka paginacji 120 na stronę, skrót RSS, który większość ludzi pomija, oraz konfiguracja proxy, która trzyma cię z dala od listy zbanowanych.

Craigslist zawiera ogromną ilość użytecznych danych publicznych — używane samochody, wynajem mieszkań, zlecenia, przedmioty na sprzedaż, usługi — rozproszone na setkach stron miast. Jest to również ściana dla początkujących z CAPTCHA i banami IP, ponieważ Craigslist mocno ogranicza szybkość według adresu IP. Dobra wiadomość: struktura URL strony jest prosta i przewidywalna, istnieje skrót RSS, który większość przewodników pomija, a problem z blokowaniem to prawie wyłącznie problem higieny IP. Ten przewodnik obejmuje wzór URL dla każdego miasta, matematykę paginacji, parsowanie, trasę RSS i konfigurację proxy, która trzyma skrobaka z dala od listy zbanowanych. Skrob dla użytku osobistego lub badawczego, szanuj warunki Craigslist i traktuj to jako ogólne informacje, a nie porady prawne.

Wzór URL to cała gra

Craigslist dzieli się na subdomeny miast i kody kategorii, a wszystko inne to parametry zapytania. Naucz się kształtu raz, a będziesz mógł celować w dowolne miasto i sekcję: https://{city}.craigslist.org/search/{category}?query={q}. Kody kategorii są krótkie — sss dla wszystkiego na sprzedaż, cto dla samochodów od właściciela, apa dla mieszkań, ggg dla zleceń. Dodaj min_price, max_price i inne filtry jako parametry. Paginacja używa parametru s, a każda strona pokazuje 120 wyników — więc strona druga to s=120, strona trzecia to s=240, i tak dalej.

import requests
from bs4 import BeautifulSoup

PROXY = "http://USER:PASS@rotating.quantumproxies.io:8000"
PROXIES = {"http": PROXY, "https": PROXY}
UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
      "(KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36")

def build_url(city, category, query, page=0, min_price=None, max_price=None):
    base = f"https://{city}.craigslist.org/search/{category}"
    params = [f"query={query}"]
    if min_price: params.append(f"min_price={min_price}")
    if max_price: params.append(f"max_price={max_price}")
    if page:      params.append(f"s={page * 120}")   # 120 results per page
    return base + "?" + "&".join(params)

url = build_url("minneapolis", "cto", "bmw", page=0, max_price=8000)
r = requests.get(url, headers={"User-Agent": UA}, proxies=PROXIES, timeout=20)

Parsowanie ogłoszeń

Wiersze wyników wyszukiwania są oznaczone stabilnym zestawem klas — blok ogłoszenia to .result-info, z .result-title, .result-price i .result-date wewnątrz. Zabezpiecz każde pole, ponieważ nie każde ogłoszenie ma cenę:

def parse_listings(html):
    soup = BeautifulSoup(html, "html.parser")
    out = []
    for row in soup.select(".result-info"):
        title_el = row.select_one(".result-title")
        price_el = row.select_one(".result-price")
        date_el  = row.select_one(".result-date")
        if not title_el:
            continue
        out.append({
            "title": title_el.get_text(strip=True),
            "url":   title_el.get("href"),
            "price": price_el.get_text(strip=True) if price_el else None,
            "date":  date_el.get("datetime") if date_el else None,
        })
    return out

listings = parse_listings(r.text)
print(len(listings), "listings on this page")

Dla bogatszych rekordów — przebieg samochodu, liczba sypialni w wynajmie — podążaj za każdym URL-em ogłoszenia i parsuj stronę szczegółów. To podwaja liczbę żądań, więc to dokładnie tam zaczyna mieć znaczenie tempo i rotacja.

Diagram rozkładający URL wyszukiwania Craigslist na subdomenę miasta, kod kategorii, zapytanie i parametr paginacji s
URL-e Craigslist są w pełni przewidywalne: subdomena miasta, kod kategorii, następnie zapytanie i parametr s w krokach co 120.

Skrót RSS, który większość przewodników pomija

Craigslist nie ma ogólnego publicznego API, ale udostępnia kanał RSS dla wyników wyszukiwania — dodaj &format=rss do dowolnego URL-a wyszukiwania, a otrzymasz ustrukturyzowany kanał XML zamiast HTML do parsowania. Jest lżejszy, mniej prawdopodobny do wywołania heurystyk antybotowych niż wielokrotne ładowanie pełnej strony wyników i idealny do monitorowania: sprawdzaj zapisane wyszukiwanie według harmonogramu i porównuj nowe pozycje. Zwraca mniej pól niż strona HTML (tytuł, link, znacznik czasu), więc używaj go do monitorowania świeżości i wracaj do HTML, gdy potrzebujesz ceny i szczegółów.

import feedparser

# Any Craigslist search becomes a feed with &format=rss
feed_url = build_url("sfbay", "apa", "loft", max_price=3500) + "&format=rss"
raw = requests.get(feed_url, headers={"User-Agent": UA}, proxies=PROXIES, timeout=20)
feed = feedparser.parse(raw.content)

for entry in feed.entries[:5]:
    print(entry.updated, entry.title, entry.link)

Dlaczego Craigslist cię banuje i jak nie zostać zbanowanym

Craigslist stosuje kilka obron, ale wszystkie mają jedno źródło: śledzi żądania według adresu IP i blokuje adresy, które uderzają zbyt mocno. Konkretne środki to ograniczanie szybkości IP, wyzwania CAPTCHA na podejrzanym ruchu, monitorowanie User-Agent, śledzenie sesji i tymczasowe bany IP. Każdy z nich można pokonać, wyglądając jak wielu zwykłych odwiedzających, a nie jedna nieustępliwa maszyna.

Ponieważ bany są oparte na IP, wyjściowe IP wykonuje większość pracy. Czysta pula proxy rezydencyjnych wygląda jak prawdziwe połączenia domowe, a rotacja na żądanie rozkłada wielomiejskie przeszukiwanie tak cienko, że liczniki per-IP Craigslist nigdy się nie uruchamiają. Jeśli zbierasz dane z wielu miast, nasz przewodnik o naprawianiu limitów 429 obejmuje stronę tempa i budżetu współbieżności, a lista kontrolna antybanowa łączy wszystko w całość.

Zeskrob Craigslist na czystych rezydencyjnych IP

Skalowanie przez miasta

Prawdziwa moc danych Craigslist to porównanie między miastami — ten sam używany samochód lub wynajem wyceniony w kilkunastu metropoliach. Przejdź przez listę miast, przypisz świeże rotacyjne wyjście na miasto, ogranicz współbieżność i przechowuj miasto wraz z każdym rekordem. Dla badań nad pojazdami i wynajmem, te same wzory zasilają pipeline porównań; zobacz nasze przewodniki o zeskrobywaniu ogłoszeń samochodowych i danych nieruchomości w celu przekształcenia surowych ogłoszeń w sygnały rynkowe.

Lista kontrolna mapująca obrony antyskrobania Craigslist, takie jak ograniczanie szybkości IP i CAPTCHA, na rozwiązania takie jak rotacja rezydencyjna i tempo
Każda obrona Craigslist to problem IP i tempa — rotuj rezydencyjne wyjścia i trzymaj się poniżej 1-2 żądań na sekundę.

Często zadawane pytania

Czy można zeskrobać Craigslist?

Tak — publiczne strony wyszukiwania i ogłoszeń są możliwe do zeskrobania, a Craigslist nawet udostępnia kanał RSS dla wyszukiwań. Przeszkodą jest agresywne ograniczanie szybkości per-IP, a nie parsowanie. Rotuj rezydencyjne IP, ustal tempo żądań na 1-2 na sekundę, a będziesz mógł zbierać dane o pojazdach, wynajmie, zleceniach i sprzedaży niezawodnie. Szanuj warunki Craigslist i skrob tylko dane publiczne.

Czy Craigslist ma API?

Nie ma ogólnego publicznego API danych, ale każdy URL wyszukiwania może zwrócić kanał RSS przez dodanie &format=rss. To daje ustrukturyzowany kanał XML z tytułami, linkami i znacznikami czasu — idealny do monitorowania nowych ogłoszeń — podczas gdy strony HTML zawierają pełniejsze pola, takie jak cena i opis.

Jak uniknąć bana IP podczas skrobania Craigslist?

Craigslist banuje według szybkości IP, więc rozwiązania dotyczą rozkładania i spowalniania obciążenia: rotuj rezydencyjne IP na żądanie, trzymaj się 1-2 żądań na sekundę z jitterem, rotuj User-Agent, używaj świeżej sesji na miasto i wycofaj się natychmiast, gdy zobaczysz CAPTCHA lub 403. IP centrum danych uderzające w jedno miasto zostaje zbanowane najszybciej.

Jak działa paginacja w Craigslist?

Craigslist pokazuje 120 wyników na stronę i paginuje za pomocą parametru zapytania s jako przesunięcia. Strona pierwsza pomija s, strona druga to s=120, strona trzecia s=240, i tak dalej. Zwiększaj w krokach co 120, aż strona zwróci mniej niż 120 wyników, co oznacza koniec.

Craigslist jest łatwy do odczytania i łatwy do zbanowania — a drugi problem to całkowicie kwestia higieny IP. Opanuj wzór URL, używaj RSS do monitorowania, paginuj w krokach co 120 i kieruj wszystko przez rotacyjne rezydencyjne IP w ludzkim tempie. Zrób to, a CAPTCHA po prostu przestaną się pojawiać.

Zacznij od rotacyjnych rezydencyjnych proxy