Indeedの求人情報をスクレイピングする方法:構造、ブロック、SERPルート

Indeedはウェブ上で最大の求人掲示板であり、リアルタイムの労働市場シグナルです。また、Cloudflareの背後にあり、クラス名が毎週ローテーションされます。ここでは、耐久的に抽出する方法と、サイトを完全にスキップするタイミングについて説明します。

Indeedは月間約5億4200万回の訪問を引き付けており、そのリスティングは労働市場の最もクリーンなライブシグナルの1つです。役割別の採用需要、給与帯、どの企業が人員を増やしているかなどがわかります。また、Cloudflareで保護されたReactサイトであり、表示されるCSSクラス名が頻繁にローテーションされるため、単純なスクレイパーは数週間で壊れてしまいます。このガイドでは、Indeedの求人情報を耐久的にスクレイピングする方法、ページネーションと重複排除の方法、Cloudflareの現実、そして戦いを完全にスキップできる求人のSERP垂直について説明します。

検索ページを読み、安定した属性にアンカーを置く

Indeedデータの単位は検索結果ページです:クエリと場所を組み合わせると、求人カードのページが得られます。罠はIndeedが再生成するハッシュ化されたクラス名(eu4oa1w0のようなもの)を選択することです。代わりに、data-testid属性にアンカーを置きます。これらははるかに頻繁に変わりません:

import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
}
proxies = {"http": "http://USER:PASS@gate.quantumproxies.io:8000",
           "https": "http://USER:PASS@gate.quantumproxies.io:8000"}

url = "https://www.indeed.com/jobs?q=python&l=New+York%2C+NY"
html = requests.get(url, headers=headers, proxies=proxies, timeout=30).text
soup = BeautifulSoup(html, "html.parser")

jobs = []
for card in soup.select("div.job_seen_beacon"):
    title = card.find("a", class_="jcs-JobTitle")
    company = card.find("span", attrs={"data-testid": "company-name"})
    location = card.find("div", attrs={"data-testid": "text-location"})
    jobs.append({
        "title": title.get_text(strip=True) if title else None,
        "company": company.get_text(strip=True) if company else None,
        "location": location.get_text(strip=True) if location else None,
        "jk": title["href"].split("jk=")[-1][:16] if title else None,
    })
print(len(jobs), "jobs on page 1")

各カードには求人キー(jk)があり、ページや実行間で重複排除するために使用する安定したIDです。URLではなくjkに保存してください。同じ投稿が異なるトラッキングパラメータで表示されるためです。

ページネーションと国別サイト

Indeedは10ずつ増加するstartパラメータでページを分けています。そして、それは1つのサイトではありません。各国はサブドメインです:米国はwww.indeed.com、英国はuk.indeed.comなどです。プロキシ出口をクエリしている国に合わせて、リクエストが地理的に一貫性があるようにします:

def crawl(query, location, country="www", pages=5):
    base = f"https://{country}.indeed.com/jobs"
    for start in range(0, pages * 10, 10):
        params = {"q": query, "l": location, "start": start}
        html = requests.get(base, params=params, headers=headers,
                            proxies=proxies, timeout=30).text
        # parse as above, yield rows
        yield html

# freshness filter: fromage accepts only 1, 3, 7 or 14 days
# .../jobs?q=python&l=NYC&fromage=7

知っておくべき特異点:Indeedの「投稿からの経過日数」フィルター(fromage)は1、3、7、14日のみを受け入れます。他の値は無視されるため、これらのバケットに基づいて新鮮さのロジックを構築してください。

Indeed検索ページをスクレイピングするためのパイプライン:住宅用出口を通じてクエリURLを取得し、data-testidでカードを解析し、startでページネーションし、求人キーで重複排除
data-testidと求人キーにアンカーを置き、10ずつのstartインクリメントでページネーションし、完全な結果セットをキャプチャするために重複排除します。

Cloudflareの現実

IndeedはCloudflareの背後にあるため、データセンターIPでの単純なリクエストでは結果の代わりにチャレンジを受けることがよくあります。修正策は通常のアンチボットスタックです:一貫したブラウザUser-Agentとヘッダーセット、そして最大のレバーである事前に自動化としてスコアされていない住宅用出口です。住宅用プロキシは実際のユーザーの接続として提示され、Cloudflareがページを提供し続ける理由です。チャレンジが発生した場合、ブラウザのフィンガープリントを一致させることがIPと同じくらい重要です。2026年にCloudflareを回避する方法に関するガイドでは、どこで線が引かれるかを説明しています。

ショートカット:求人のSERP垂直

もしあなたが本当に欲しいのが労働市場データであって、IndeedのHTMLそのものではない場合、よりクリーンなパスがあります。Googleの求人垂直はIndeedや他の多くのボードからの投稿を集約し、SERP APIはその求人垂直を解析されたJSONとして返します:タイトル、会社、場所、投稿日、ソース、維持するCSSセレクタなし、Cloudflareと戦う必要もありません。多くのボードにわたる安定した構造化フィードを得るために、フィールドレベルの制御を少し犠牲にしますが、集約された採用分析のためには通常これがより良い取引です。これは、求人ボードアグリゲーターを1つのスクレイパーではなくSERPフィードで構築する理由と同じです。

求人垂直をクリーンなJSONとして取得する

データが役立つ用途

求人検索を超えて、このデータは実際の分析を推進します:役割と都市ごとの給与ベンチマーク、特定のスキルの需要追跡、競合他社の採用シグナル(ライバルが新しいチームを編成しているのは戦略の兆候)、およびエンリッチメント—企業のオープンロールをファーモグラフィックスとペアリングしてアウトバウンドに活用します。Glassdoorの給与データと組み合わせると、どちらのソース単独よりも完全な報酬の全体像が得られます。

Indeedを直接スクレイピングするのとGoogleの求人SERP垂直から同じ求人データを構造化JSONとして取得することの比較
Indeedをスクレイピングすると完全なフィールド制御が得られます。求人SERP垂直は多くのボードにわたる構造化JSONを提供し、セレクタの維持は不要です。

よくある質問

Indeedの求人情報を合法的にスクレイピングできますか?

求人情報は公開データであり、公開されているリスティングを収集することは広く防御可能ですが、Indeedの利用規約は自動アクセスを制限しており、個人データを避け、レート制限を尊重する必要があります。多くのチームは、Indeedを直接スクレイピングする代わりに、集約された求人SERP垂直を使用することで利用規約の問題を回避しています。これは一般的な情報であり、法的アドバイスではありません。大規模なプロジェクトの前に現在の利用規約を確認してください。

なぜ私のIndeedスクレイパーは壊れ続けるのですか?

2つの理由があります。まず、Indeedはハッシュ化されたCSSクラス名をローテーションするため、それに固定されたセレクタは数週間で失敗します。代わりにdata-testid属性と求人キーにアンカーを置いてください。次に、CloudflareはIPがフラグされるとチャレンジを開始します。住宅用出口と一貫したブラウザフィンガープリントが実際のページを読み込むのを維持します。両方を修正すれば、スクレイパーは安定します。

複数の国から求人をスクレイピングするにはどうすればよいですか?

Indeedは各国を独自のサブドメイン(www.indeed.comuk.indeed.comde.indeed.comなど)から提供しています。正しいサブドメインをクエリし、その国のプロキシ出口を通じてルートを設定して、リクエストが地理的に一貫しているようにします。そうしないと、不一致またはリダイレクトされた結果を得る可能性があります。求人SERP垂直も国パラメータを受け入れるため、サブドメインを管理したくない場合に便利です。

Googleの求人SERPはIndeedをスクレイピングするよりも良いですか?

集約された労働市場分析のためには、通常はそうです。求人垂直はIndeedや他の多くのボードからの投稿を構造化JSONとして返し、ローテーションするセレクタやCloudflareのチャレンジを処理する必要がありません。Indeed固有のフィールドをいくつか失いますが、安定したマルチソースフィードを得ることができ、メンテナンスもはるかに少なくなります。Indeedの独自ページにあるフィールドが必要な場合にのみ、Indeedを直接スクレイピングしてください。

Indeedは耐久性のあるアプローチを報いる:安定した属性にアンカーを置き、求人キーで重複排除し、10ずつページネーションし、住宅用IPでノックしてCloudflareがページを提供するようにします。そして、Indeedの正確なHTMLではなく労働市場のシグナルだけが必要な場合、求人SERP垂直はそれをJSONとして提供します。どれだけのフィールド制御が実際に必要かに応じてパスを選択してください。

Cloudflareをクリアする住宅用IPを取得する