[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-ja-got-scraping-nodejs-purokishi":3},{"success":4,"payload":5,"related":63,"errors":127},true,{"id":6,"slug":7,"title":8,"excerpt":9,"body_html":10,"meta_title":11,"meta_description":12,"canonical_url":13,"canonical_override":14,"og_title":11,"og_description":15,"og_image_url":16,"faq_json":17,"key_takeaways":14,"allow_index":4,"noindex_google_only":30,"allow_follow":4,"published_at":31,"updated_at":31,"content_updated_at":32,"featured_image_url":33,"featured_image_alt":34,"card_image_url":35,"reading_time_minutes":36,"author":37,"categories":41,"tags":48,"alternates":49,"locale_paths":57,"views":62},176,"got-scraping-nodejs-purokishi","Node.jsでgot-scrapingを使ったプロキシ連携の完全ガイド","got-scrapingのheader-generatorとProxyHatレジデンシャルプロキシを組み合わせ、Node.jsでブロックされないスクレイピングを構築する方法を解説。実践的なコード例付き。","\u003Cp>Node.jsでスクレイピングを本格的に始めると、ほぼ確実に「403 Forbidden」やCAPTCHAページに直面します。Node.jsでgot-scrapingを活用すれば、ブラウザと同等のヘッダーとTLSフィンガープリントを自動生成し、プロキシ統合もシームレスに実現できます。本記事では、got-scrapingをProxyHatのレジデンシャルプロキシと組み合わせて本番運用するための実践的なパターンを解説します。\u003C\u002Fp>\n\n\u003Cblockquote>\u003Cstrong>注意:\u003C\u002Fstrong> 本記事は公開データの収集を前提としています。CFAA（Computer Fraud and Abuse Act）やGDPRなど、対象サイトの利用規約と適用法令を遵守してください。robots.txtとレート制限を尊重し、公式APIが利用可能な場合はそちらを優先してください。詳細は\u003Ca href=\"https:\u002F\u002Fwww.ftc.gov\u002Fbusiness-guidance\u002Fprivacy-security\" rel=\"noopener noreferrer\">FTCのプライバシーガイダンス\u003C\u002Fa>も参照してください。\u003C\u002Fblockquote>\n\n\u003Ch2>Node.jsでgot-scrapingが解決するヘッダーとTLSの課題\u003C\u002Fh2>\n\n\u003Cp>生の\u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fgot\" rel=\"noopener noreferrer\">got\u003C\u002Fa>やaxiosでリクエストを送ると、ヘッダーの並び順がNode.jsのHTTPクライアント特有のパターンになります。ChromeやFirefoxはヘッダーを特定の順序で送信し、\u003Ccode>sec-ch-ua\u003C\u002Fcode>や\u003Ccode>accept-language\u003C\u002Fcode>などのブラウザ固有ヘッダーを含めます。アンチボットシステムは、これらのヘッダーが欠落していたり、順序が不自然だったりするリクエストを即座にフラグ付けします。\u003C\u002Fp>\n\n\u003Cp>具体的には、以下の要因でリクエストがブロックされます：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>ヘッダー順序の不整合:\u003C\u002Fstrong> ブラウザは\u003Ccode>Host\u003C\u002Fcode>、\u003Ccode>Connection\u003C\u002Fcode>、\u003Ccode>sec-ch-ua\u003C\u002Fcode>、\u003Ccode>accept\u003C\u002Fcode>の順で送信しますが、Node.jsクライアントは異なる順序になります。\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTTP\u002FReference\u002FHeaders\u002FSec-CH-UA\" rel=\"noopener noreferrer\">MDNのドキュメント\u003C\u002Fa>によれば、\u003Ccode>sec-ch-ua\u003C\u002Fcode>はClient Hints仕様の一部で、モダンブラウザが必ず送信するヘッダーです。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>ブラウザヘッダーの欠落:\u003C\u002Fstrong> \u003Ccode>sec-ch-ua\u003C\u002Fcode>、\u003Ccode>sec-fetch-dest\u003C\u002Fcode>、\u003Ccode>sec-fetch-mode\u003C\u002Fcode>などが存在しないと、非ブラウザトラフィックとして判定されます。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>TLSフィンガープリント:\u003C\u002Fstrong> Node.jsのTLSハンドシェイクはJA3\u002FJA4フィンガープリントでブラウザと異なります。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>HTTP\u002F2の未使用:\u003C\u002Fstrong> モダンブラウザはHTTP\u002F2を使用しますが、多くのクライアントはHTTP\u002F1.1のみです。\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fgot-scraping\" rel=\"noopener noreferrer\">got-scraping\u003C\u002Fa>は、これらの課題を解決するためにApifyが開発したgotベースのHTTPクライアントです。header-generatorライブラリを内蔵し、リアルなブラウザヘッダーセットを生成します。HTTP\u002F2も標準でサポートし、TLSフィンガープリントの不一致を軽減します。\u003C\u002Fp>\n\n\u003Ch2>got-scrapingのheader-generatorによる解決策\u003C\u002Fh2>\n\n\u003Cp>got-scrapingの中核は、\u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fheader-generator\" rel=\"noopener noreferrer\">header-generator\u003C\u002Fa>ライブラリです。このライブラリは、指定したブラウザ・OS・デバイスの組み合わせに応じて、整合性のあるヘッダーセットを生成します。「整合性」という点が重要で、Chrome 120 on Windows 11のヘッダーセットには、その環境固有の\u003Ccode>sec-ch-ua\u003C\u002Fcode>値や\u003Ccode>user-agent\u003C\u002Fcode>文字列が含まれます。\u003C\u002Fp>\n\n\u003Ch3>headerGeneratorOptionsの設定\u003C\u002Fh3>\n\n\u003Cp>\u003Ccode>headerGeneratorOptions\u003C\u002Fcode>で、ブラウザ・デバイス・OSを指定します。これにより、生成されるヘッダーが常に整合性を保ちます。例えば\u003Ccode>browsers: ['chrome']\u003C\u002Fcode>と\u003Ccode>operatingSystems: ['windows']\u003C\u002Fcode>を指定すれば、Chrome on Windowsのヘッダーセットが生成されます。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\n\nconst response = await gotScraping({\n  url: &apos;https:\u002F\u002Fexample.com&apos;,\n  headerGeneratorOptions: {\n    browsers: [&apos;chrome&apos;],\n    devices: [&apos;desktop&apos;],\n    operatingSystems: [&apos;windows&apos;],\n    locales: [&apos;ja-JP&apos;, &apos;en-US&apos;],\n  },\n});\n\nconsole.log(response.body);\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>この例では、Chrome on Windowsのデスクトップヘッダーセットが生成され、\u003Ccode>ja-JP\u003C\u002Fcode>と\u003Ccode>en-US\u003C\u002Fcode>の\u003Ccode>accept-language\u003C\u002Fcode>ヘッダーが付与されます。ヘッダーの順序もブラウザと一致するため、アンチボットシステムをより確実に通過できます。\u003C\u002Fp>\n\n\u003Ch2>got.extendを使った慣用的なセットアップ\u003C\u002Fh2>\n\n\u003Cp>got-scrapingはgotの拡張であるため、\u003Ccode>got.extend()\u003C\u002Fcode>を使ってデフォルトオプションを設定できます。これにより、全リクエストで共通のヘッダー生成設定とプロキシを適用できます。\u003Ccode>useHeaderGenerator\u003C\u002Fcode>オプションを\u003Ccode>true\u003C\u002Fcode>に設定すると、header-generatorが全リクエストで自動的に機能します。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\n\nconst client = gotScraping.extend({\n  useHeaderGenerator: true,\n  headerGeneratorOptions: {\n    browsers: [&apos;chrome&apos;, &apos;firefox&apos;],\n    devices: [&apos;desktop&apos;],\n    operatingSystems: [&apos;windows&apos;, &apos;macos&apos;],\n    locales: [&apos;ja-JP&apos;, &apos;en-US&apos;],\n  },\n  timeout: { request: 30000 },\n  retry: { limit: 3 },\n});\n\n\u002F\u002F 全リクエストでブラウザヘッダーが自動生成される\nconst res = await client.get(&apos;https:\u002F\u002Fhttpbin.org\u002Fheaders&apos;);\nconsole.log(JSON.parse(res.body).headers);\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>\u003Ccode>got.extend()\u003C\u002Fcode>で作成したクライアントインスタンスは、全リクエストで共通の設定を継承します。個別リクエストで\u003Ccode>headerGeneratorOptions\u003C\u002Fcode>を上書きすることも可能で、例えばモバイルヘッダーが必要なリクエストだけ\u003Ccode>devices: ['mobile']\u003C\u002Fcode>を指定できます。\u003C\u002Fp>\n\n\u003Ch2>got-scraping プロキシ統合とProxyHatレジデンシャルプロキシ\u003C\u002Fh2>\n\n\u003Cp>ヘッダーとTLSが本物らしくなっても、IPアドレスがデータセンターに属していると、多くのアンチボットシステムでフラグ付けされます。got-scraping プロキシ統合は、\u003Ccode>proxyUrl\u003C\u002Fcode>オプションでシンプルに実装できます。ProxyHatの\u003Ca href=\"\u002Fja\u002Fproxy\u002Fresidential\">レジデンシャルプロキシ\u003C\u002Fa>を使用すれば、ISPに割り当てられた実際の住宅IPアドレスからのリクエストとして認識されます。\u003Ca href=\"\u002Fja\u002Fuse-cases\u002Fweb-scraping\">Webスクレイピングのユースケース\u003C\u002Fa>でも詳しく解説しています。\u003C\u002Fp>\n\n\u003Ctable>\n  \u003Cthead>\n    \u003Ctr>\n      \u003Cth>プロキシタイプ\u003C\u002Fth>\n      \u003Cth>検知リスク\u003C\u002Fth>\n      \u003Cth>平均レイテンシ\u003C\u002Fth>\n      \u003Cth>適した用途\u003C\u002Fth>\n    \u003C\u002Ftr>\n  \u003C\u002Fthead>\n  \u003Ctbody>\n    \u003Ctr>\n      \u003Ctd>レジデンシャル\u003C\u002Ftd>\n      \u003Ctd>低\u003C\u002Ftd>\n      \u003Ctd>~200ms\u003C\u002Ftd>\n      \u003Ctd>SERPスクレイピング、e-commerce監視\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd>データセンター\u003C\u002Ftd>\n      \u003Ctd>高\u003C\u002Ftd>\n      \u003Ctd>~50ms\u003C\u002Ftd>\n      \u003Ctd>制限の緩いAPI、社内システム\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd>モバイル\u003C\u002Ftd>\n      \u003Ctd>極低\u003C\u002Ftd>\n      \u003Ctd>~300ms\u003C\u002Ftd>\n      \u003Ctd>高度なアンチボット環境\u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>got-scrapingはHTTP\u002F1.1プロキシとHTTP\u002F2プロキシの両方をサポートします。\u003Ccode>proxyUrl\u003C\u002Fcode>オプションにProxyHatのゲートウェイを指定するだけで、全リクエストがプロキシ経由で送信されます。ProxyHatは\u003Ca href=\"\u002Fja\u002Flocations\">世界中のロケーション\u003C\u002Fa>でレジデンシャルIPを提供しています。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\n\nconst client = gotScraping.extend({\n  useHeaderGenerator: true,\n  headerGeneratorOptions: {\n    browsers: [&apos;chrome&apos;],\n    operatingSystems: [&apos;windows&apos;],\n    locales: [&apos;ja-JP&apos;, &apos;en-US&apos;],\n  },\n  proxyUrl: &apos;http:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:8080&apos;,\n});\n\nconst res = await client.get(&apos;https:\u002F\u002Fhttpbin.org\u002Fip&apos;);\nconsole.log(JSON.parse(res.body).origin); \u002F\u002F 米国のIP\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>SOCKS5プロキシの使用\u003C\u002Fh3>\n\n\u003Cp>HTTPプロキシがブロックされる環境では、SOCKS5プロトコルが代替として機能します。ProxyHatではポート\u003Ccode>1080\u003C\u002Fcode>でSOCKS5を提供しています。got-scrapingは\u003Ccode>socks5:\u002F\u002F\u003C\u002Fcode>スキームをサポートしています。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>const client = gotScraping.extend({\n  useHeaderGenerator: true,\n  proxyUrl: &apos;socks5:\u002F\u002Fuser-country-DE:pass@gate.proxyhat.com:1080&apos;,\n});\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>実践例：セッションローテーションとリトライフック\u003C\u002Fh2>\n\n\u003Cp>本番環境では、リクエストごとに異なるIPとセッションを使用することが重要です。ProxyHatのユーザー名に\u003Ccode>sid-\u003C\u002Fcode>プレフィックスを含めることで、スティッキーセッションを制御できます。各セッションは異なるIPにマッピングされ、同じセッションIDを使い続ける限り同じIPが保持されます。詳細な設定については\u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHatドキュメント\u003C\u002Fa>を参照してください。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\nimport { randomUUID } from &apos;crypto&apos;;\n\nfunction createClient(countryCode) {\n  return gotScraping.extend({\n    useHeaderGenerator: true,\n    headerGeneratorOptions: {\n      browsers: [&apos;chrome&apos;],\n      operatingSystems: [&apos;windows&apos;],\n      devices: [&apos;desktop&apos;],\n      locales: [&apos;ja-JP&apos;, &apos;en-US&apos;],\n    },\n    timeout: { request: 30000 },\n    retry: {\n      limit: 5,\n      statusCodes: [403, 429, 500, 502, 503],\n    },\n    hooks: {\n      beforeRequest: [\n        (options) =&gt; {\n          const sessionId = randomUUID().slice(0, 8);\n          const username = `user-country-${countryCode}-sid-${sessionId}`;\n          options.proxy = `http:\u002F\u002F${username}:pass@gate.proxyhat.com:8080`;\n        },\n      ],\n      afterResponse: [\n        (response, retryWithMergedOptions) =&gt; {\n          if (response.statusCode === 403) {\n            const newSession = randomUUID().slice(0, 8);\n            const newProxy = `http:\u002F\u002Fuser-country-${countryCode}-sid-${newSession}:pass@gate.proxyhat.com:8080`;\n            return retryWithMergedOptions({ proxy: newProxy });\n          }\n          return response;\n        },\n      ],\n    },\n  });\n}\n\nconst usClient = createClient(&apos;US&apos;);\nconst res = await usClient.get(&apos;https:\u002F\u002Fhttpbin.org\u002Fip&apos;);\nconsole.log(JSON.parse(res.body).origin);\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>このパターンでは、\u003Ccode>beforeRequest\u003C\u002Fcode>フックでリクエストごとに新しいセッションIDを生成し、\u003Ccode>afterResponse\u003C\u002Fcode>フックで403応答時に自動的に新しいIPでリトライします。これにより、IPブロックを動的に回避できます。\u003C\u002Fp>\n\n\u003Ch2>プロダクションパターン\u003C\u002Fh2>\n\n\u003Ch3>p-limitによる並行制御\u003C\u002Fh3>\n\n\u003Cp>大量のリクエストを送信する場合、並行数を制限しないと対象サーバーに負荷をかけ、ブロックの原因になります。\u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fp-limit\" rel=\"noopener noreferrer\">p-limit\u003C\u002Fa>を使えば、同時実行数を簡単に制御できます。100並行でリクエストを送ると対象サイトにDDoSに近い負荷をかける可能性がありますが、10並行に制限すれば安全な範囲で収集できます。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import pLimit from &apos;p-limit&apos;;\nimport { gotScraping } from &apos;got-scraping&apos;;\nimport { randomUUID } from &apos;crypto&apos;;\n\nconst limit = pLimit(10); \u002F\u002F 最大10並行\n\nconst client = gotScraping.extend({\n  useHeaderGenerator: true,\n  headerGeneratorOptions: {\n    browsers: [&apos;chrome&apos;],\n    operatingSystems: [&apos;windows&apos;],\n    locales: [&apos;ja-JP&apos;, &apos;en-US&apos;],\n  },\n});\n\nconst urls = [\n  &apos;https:\u002F\u002Fexample.com\u002Fpage1&apos;,\n  &apos;https:\u002F\u002Fexample.com\u002Fpage2&apos;,\n  &apos;https:\u002F\u002Fexample.com\u002Fpage3&apos;,\n];\n\nconst results = await Promise.all(\n  urls.map((url) =&gt;\n    limit(async () =&gt; {\n      const sessionId = randomUUID().slice(0, 8);\n      const proxyUrl = `http:\u002F\u002Fuser-country-US-sid-${sessionId}:pass@gate.proxyhat.com:8080`;\n      try {\n        const res = await client.get(url, { proxyUrl });\n        return { url, status: res.statusCode, body: res.body };\n      } catch (err) {\n        return { url, error: err.message };\n      }\n    })\n  )\n);\n\nconsole.log(results);\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Cookie Jarによるセッション維持\u003C\u002Fh3>\n\n\u003Cp>ログインが必要なサイトや、セッションCookieに依存するサイトでは、\u003Ccode>tough-cookie\u003C\u002Fcode>ベースのCookie Jarを使用してリクエスト間でCookieを維持できます。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\nimport { CookieJar } from &apos;tough-cookie&apos;;\n\nconst cookieJar = new CookieJar();\n\nconst client = gotScraping.extend({\n  useHeaderGenerator: true,\n  cookieJar,\n  proxyUrl: &apos;http:\u002F\u002Fuser-country-US-sid-login01:pass@gate.proxyhat.com:8080&apos;,\n});\n\n\u002F\u002F 1回目のリクエストでCookieを取得\nawait client.get(&apos;https:\u002F\u002Fexample.com\u002Flogin&apos;);\n\n\u002F\u002F 2回目のリクエストではCookieが自動的に送信される\nconst res = await client.get(&apos;https:\u002F\u002Fexample.com\u002Fdashboard&apos;);\nconsole.log(res.body);\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>Cookie Jarとスティッキーセッションを組み合わせることで、ログイン状態を維持したままスクレイピングできます。セッションIDを固定すれば、同じIPとCookieセットが継続して使用されます。\u003C\u002Fp>\n\n\u003Ch3>CrawleeのCheerioCrawlerへの統合\u003C\u002Fh3>\n\n\u003Cp>got-scrapingは\u003Ca href=\"https:\u002F\u002Fcrawlee.dev\u002Fjs\u002Fdocs\u002Fintroduction\" rel=\"noopener noreferrer\">Crawlee\u003C\u002Fa>の一部として設計されており、CheerioCrawlerにシームレスに統合できます。Crawleeを使えば、キュー管理、自動リトライ、プロキシローテーションを宣言的に処理できます。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import { CheerioCrawler } from &apos;crawlee&apos;;\n\nconst crawler = new CheerioCrawler({\n  useHeaderGenerator: true,\n  headerGeneratorOptions: {\n    browsers: [&apos;chrome&apos;],\n    operatingSystems: [&apos;windows&apos;],\n    locales: [&apos;ja-JP&apos;, &apos;en-US&apos;],\n  },\n  proxyConfiguration: {\n    newUrlFunction: () =&gt; {\n      const session = Math.random().toString(36).slice(2, 10);\n      return `http:\u002F\u002Fuser-country-US-sid-${session}:pass@gate.proxyhat.com:8080`;\n    },\n  },\n  maxRequestsPerMinute: 60,\n  requestHandler: async ({ $, request }) =&gt; {\n    const title = $(&apos;title&apos;).text();\n    console.log(`${request.url}: ${title}`);\n  },\n});\n\nawait crawler.run([\n  &apos;https:\u002F\u002Fexample.com\u002Fpage1&apos;,\n  &apos;https:\u002F\u002Fexample.com\u002Fpage2&apos;,\n]);\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>CheerioCrawlerは、\u003Ccode>maxRequestsPerMinute\u003C\u002Fcode>でレート制限を自動管理し、失敗したリクエストを自動的にリトライします。プロキシローテーションは\u003Ccode>proxyConfiguration\u003C\u002Fcode>で宣言的に設定でき、各リクエストで新しいセッションIPを取得できます。\u003Ca href=\"\u002Fja\u002Fuse-cases\u002Fserp-tracking\">SERPトラッキング\u003C\u002Fa>のユースケースでもCrawleeパターンが有効です。\u003C\u002Fp>\n\n\u003Ch2>ヘッドレスブラウザが必要なケース\u003C\u002Fh2>\n\n\u003Cp>got-scrapingは強力ですが、JavaScriptレンダリングが必要なページ（SPA、動的コンテンツ）では限界があります。以下のケースでは、PlaywrightやPuppeteerなどのヘッドレスブラウザが必要です：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>コンテンツがクライアントサイドでレンダリングされる（React、Vue、Angular）\u003C\u002Fli>\n\u003Cli>Cloudflare TurnstileやreCAPTCHA v3などのチャレンジが存在する\u003C\u002Fli>\n\u003Cli>WebSocketやXHRリクエストでデータを読み込むページ\u003C\u002Fli>\n\u003Cli>マウス操作やスクロールで遅延読み込みされるコンテンツ\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>ヘッドレスブラウザを使用する場合でも、プロキシは同様に機能します。Playwrightの\u003Ccode>--proxy-server\u003C\u002Fcode>フラグや、Puppeteerの\u003Ccode>page.authenticate()\u003C\u002Fcode>でProxyHatのゲートウェイを指定できます。ヘッドレスブラウザのTLSフィンガープリントは実際のブラウザと同一なため、プロキシIPが適切であれば、非常に高い成功率が期待できます。コンテナ化する場合は、ブラウザインスタンスごとに独立したプロキシセッションを割り当てるアーキテクチャを推奨します。\u003C\u002Fp>\n\n\u003Ch2>エシックスと法務\u003C\u002Fh2>\n\n\u003Cp>スクレイピングは強力な技術ですが、法的・倫理的境界を守ることが不可欠です。以下のガイドラインを推奨します：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>公開データのみを収集: ログイン背後のデータや、明確に非公開とマークされたデータは収集しないでください。\u003C\u002Fli>\n\u003Cli>robots.txtを尊重: 対象サイトのrobots.txtで禁止されているパスはスクレイピングしないでください。\u003C\u002Fli>\n\u003Cli>レート制限の遵守: 対象サーバーに過度な負荷をかけないよう、適切な遅延と並行制限を設定してください。\u003C\u002Fli>\n\u003Cli>利用規約の確認: 多くのサイトが利用規約でスクレイピングを制限しています。CFAAやGDPRの下で法的リスクが生じる可能性があります。\u003C\u002Fli>\n\u003Cli>公式APIを優先: 対象サイトが公式APIを提供している場合は、スクレイピングよりAPIを使用してください。\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cblockquote>スクレイピングの合法性は管轄区域や対象サイトによって異なります。本記事の内容は法的助言ではなく、実装前に適格な法律専門家に相談することを推奨します。\u003C\u002Fblockquote>\n\n\u003Ch2>Key Takeaways\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>got-scrapingはヘッダー問題を解決: header-generatorがブラウザと整合性のあるヘッダーセットを自動生成し、\u003Ccode>sec-ch-ua\u003C\u002Fcode>や\u003Ccode>accept-language\u003C\u002Fcode>を適切に設定します。\u003C\u002Fli>\n\u003Cli>got.extendで慣用的な設定: \u003Ccode>useHeaderGenerator\u003C\u002Fcode>と\u003Ccode>headerGeneratorOptions\u003C\u002Fcode>を\u003Ccode>got.extend()\u003C\u002Fcode>で設定すれば、全リクエストで一貫したヘッダーが生成されます。\u003C\u002Fli>\n\u003Cli>レジデンシャルプロキシが鍵: ヘッダーとTLSが本物らしくても、データセンターIPは検知されます。ProxyHatのレジデンシャルプロキシ（\u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>）でISPベースのIPを使用してください。\u003C\u002Fli>\n\u003Cli>セッションローテーションで回避: \u003Ccode>beforeRequest\u003C\u002Fcode>フックでリクエストごとに新しいセッションIDを生成し、\u003Ccode>afterResponse\u003C\u002Fcode>フックで403時に自動リトライしてください。\u003C\u002Fli>\n\u003Cli>並行制御は必須: p-limitやCrawleeの\u003Ccode>maxRequestsPerMinute\u003C\u002Fcode>で並行数を制限し、対象サーバーへの負荷を抑えてください。\u003C\u002Fli>\n\u003Cli>Crawleeでスケール: CheerioCrawlerを使えば、キュー管理、自動リトライ、プロキシローテーションを宣言的に処理できます。\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>ProxyHatのレジデンシャルプロキシを今すぐお試しいただけます。\u003Ca href=\"\u002Fja\u002Fpricing\">料金プラン\u003C\u002Fa>をご確認いただくか、上記のコード例を参考に実装を始めてください。\u003C\u002Fp>","Node.jsでgot-scrapingのプロキシ連携ガイド | ProxyHat","Node.jsでgot-scrapingを使ったスクレイピングの完全ガイド。header-generatorでブラウザヘッダーを自動生成し、ProxyHatのレジデンシャルプロキシでブロックを回避する実装パターンを解説。","\u002Fja\u002Fblog\u002Fgot-scraping-nodejs-purokishi",null,"Node.jsでgot-scrapingを使ったスクレイピングの完全ガイド。header-generatorとレジデンシャルプロキシでブロックを回避。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fgot-scraping-nodejs-purokishi-og.webp",[18,21,24,27],{"question":19,"answer":20},"Node.jsでgot-scrapingとは何ですか？","got-scrapingは、Apifyが開発したgotベースのHTTPクライアントで、ブラウザと同等のヘッダーとTLSフィンガープリントを自動生成します。header-generatorライブラリを内蔵し、sec-ch-uaやaccept-languageなどのブラウザ固有ヘッダーを整合性のある順序で付与します。HTTP\u002F2も標準サポートし、プロキシ統合がシームレスに行えるため、Node.jsでのスクレイピングに最適です。",{"question":22,"answer":23},"got-scrapingを使う際、なぜプロキシが重要なのですか？","ヘッダーとTLSフィンガープリントが本物らしくても、IPアドレスがデータセンターに属しているとアンチボットシステムで検知されます。レジデンシャルプロキシを使用すれば、ISPに割り当てられた実際の住宅IPからのリクエストとして認識され、ブロックされる確率が大幅に下がります。got-scrapingのproxyUrlオプションでgate.proxyhat.com:8080を指定するだけで簡単に統合できます。",{"question":25,"answer":26},"got-scrapingに最適なプロキシタイプは何ですか？","レジデンシャルプロキシが最適です。データセンタープロキシは高速ですが検知されやすく、モバイルプロキシは検知リスクが最も低いもののレイテンシが高くなります。SERPスクレイピングやe-commerce価格監視では、レジデンシャルプロキシが検知リスクとパフォーマンスのバランスが最も良い選択肢です。ProxyHatではgate.proxyhat.com:8080（HTTP）または:1080（SOCKS5）で利用できます。",{"question":28,"answer":29},"got-scrapingでブロックを回避するにはどうすればよいですか？","まずuseHeaderGeneratorでブラウザヘッダーを自動生成し、headerGeneratorOptionsでブラウザとOSを指定します。次にproxyUrlでレジデンシャルプロキシを設定し、beforeRequestフックでリクエストごとにセッションIDをローテーションします。afterResponseフックで403応答時に新しいIPでリトライし、p-limitで並行数を制限してください。robots.txtを尊重し、公式APIがあればそちらを優先してください。",false,"2026-08-04T16:05:06+00:00","2026-10-03T08:57:49+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fgot-scraping-nodejs-purokishi-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fgot-scraping-nodejs-purokishi-card.webp",12,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[42],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},4,"kaihatsusha-gaido","開発者ガイド","開発者ガイド | ProxyHat ブログ","プロキシをアプリケーションに統合するためのコードチュートリアルとSDKガイド。",[],{"ru":50,"en":51,"it":52,"zh":53,"fr":54,"pl":55,"ko":56,"ja":13,"x-default":51},"\u002Fru\u002Fblog\u002Fgot-scraping-nodejs-residential-proxies","\u002Fblog\u002Fgot-scraping-nodejs-residential-proxies","\u002Fit\u002Fblog\u002Fguida-got-scraping-nodejs-proxy","\u002Fcn\u002Fblog\u002Fgot-scraping-nodejs-proxy-guide","\u002Ffr\u002Fblog\u002Fgot-scraping-nodejs-proxy-residentiel-1","\u002Fpl\u002Fblog\u002Fgot-scraping-nodejs-proxy","\u002Fko\u002Fblog\u002Fgot-scraping-nodejs-proxy-guide-1",{"pt":58,"ru":50,"en":51,"it":52,"de":59,"es":60,"zh":53,"fr":54,"pl":55,"ko":56,"ja":13,"tr":61},"\u002Fpt\u002Fblog\u002Fguia-got-scraping-nodejs-proxies-residenciais","\u002Fde\u002Fblog\u002Fgot-scraping-nodejs-proxy-guide","\u002Fes\u002Fblog\u002Fguia-got-scraping-nodejs-proxy-residencial","\u002Ftr\u002Fblog\u002Fnodejs-got-scraping-proxy-rehberi",123,[64,79,95,111],{"id":65,"slug":66,"title":67,"excerpt":68,"featured_image_url":69,"featured_image_alt":70,"card_image_url":71,"og_image_url":72,"published_at":73,"updated_at":73,"content_updated_at":32,"reading_time_minutes":36,"is_featured":30,"indexable":30,"views":74,"author":75,"categories":76,"tags":78},175,"colly-purokushi-roteshon-gaido","Collyでのローテーティングプロキシ完全ガイド: Goスクレイパーの本番運用","Collyでのローテーティングプロキシの実装方法を解説。RoundRobinProxySwitcherとカスタムプロキシ関数でResidentialプロキシをリクエストごとに切り替え、ブロック回避と高スループットを実現する実践的なGoコード例を提供します。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fcolly-purokushi-roteshon-gaido-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fcolly-purokushi-roteshon-gaido-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fcolly-purokushi-roteshon-gaido-og.webp","2026-08-04T10:05:34+00:00",73,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[77],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[],{"id":80,"slug":81,"title":82,"excerpt":83,"featured_image_url":84,"featured_image_alt":85,"card_image_url":86,"og_image_url":87,"published_at":88,"updated_at":88,"content_updated_at":89,"reading_time_minutes":36,"is_featured":30,"indexable":4,"views":90,"author":91,"categories":92,"tags":94},195,"bybit-v5-market-api-proxy-scraping","暗号資産取引所の市場データをローテーションプロキシで収集する完全ガイド（Bybit V5 APIの例）","Bybit V5 Market APIのorderbook・tickers・klineエンドポイントをローテーションプロキシ経由でスクレイピングする方法を、Node.js・Pythonのコード例とともに解説。レート制限・地域制限の回避策もカバーします。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbybit-v5-market-api-proxy-scraping-master.webp","How to Scrape the Bybit V5 Market API with Rotating Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbybit-v5-market-api-proxy-scraping-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbybit-v5-market-api-proxy-scraping-og.webp","2026-08-03T16:09:16+00:00","2026-10-04T01:29:51+00:00",88,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[93],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[],{"id":96,"slug":97,"title":98,"excerpt":99,"featured_image_url":100,"featured_image_alt":101,"card_image_url":102,"og_image_url":103,"published_at":104,"updated_at":104,"content_updated_at":105,"reading_time_minutes":36,"is_featured":30,"indexable":30,"views":106,"author":107,"categories":108,"tags":110},194,"binance-api-scraping-proxy","Binance REST APIをプロキシでスクレイピングする完全ガイド","Binanceの公開マーケットデータREST APIをプロキシ経由で大規模収集する方法を、エンドポイント別のウェイト制限、IPローテーション、リトライ戦略まで含めて解説します。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbinance-api-scraping-proxy-master.webp","How to Scrape the Binance REST API with Proxies: A Developer Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbinance-api-scraping-proxy-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbinance-api-scraping-proxy-og.webp","2026-08-03T10:04:04+00:00","2026-10-03T08:21:25+00:00",82,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[109],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[],{"id":112,"slug":113,"title":114,"excerpt":115,"featured_image_url":116,"featured_image_alt":117,"card_image_url":118,"og_image_url":119,"published_at":120,"updated_at":120,"content_updated_at":121,"reading_time_minutes":36,"is_featured":30,"indexable":30,"views":122,"author":123,"categories":124,"tags":126},172,"swift-urlsession-proxy-guide","Swiftでプロキシを使用する完全ガイド：URLSessionで residential プロキシを活用する方法","iOS・macOS開発者向けに、SwiftのURLSessionでresidentialプロキシを設定・認証・活用する実践的なコードファーストガイド。ProxyHatゲートウェイを使ったHTTP\u002FSOCKS5構成、async\u002Fawait並行処理、本番運用のベストプラクティスまで網羅。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fswift-urlsession-proxy-guide-master.webp","Using Proxies in Swift: A Code-First Guide to URLSession, SOCKS5 & Residential IPs","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fswift-urlsession-proxy-guide-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fswift-urlsession-proxy-guide-og.webp","2026-07-26T16:03:44+00:00","2026-10-03T23:53:00+00:00",235,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[125],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[],[]]