[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-ko-got-scraping-nodejs-proxy-guide-1":3},{"success":4,"payload":5,"related":62,"errors":156},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":12,"og_image_url":15,"faq_json":16,"key_takeaways":14,"allow_index":4,"noindex_google_only":29,"allow_follow":4,"published_at":30,"updated_at":30,"content_updated_at":31,"featured_image_url":32,"featured_image_alt":33,"card_image_url":34,"reading_time_minutes":35,"author":36,"categories":40,"tags":47,"alternates":48,"locale_paths":56,"views":61},176,"got-scraping-nodejs-proxy-guide-1","Node.js에서 got-scraping과 주거 프록시로 웹 스크래핑하기","got-scraping의 헤더 생성기와 HTTP\u002F2 지원을 활용해 차단을 우회하는 방법, ProxyHat 주거 프록시 라우팅, 그리고 Crawlee 통합까지 다루는 실전 가이드입니다.","\u003Ch2>got-scraping nodejs로 차단을 우회하는 완벽한 가이드\u003C\u002Fh2>\n\u003Cp>Node.js 개발자라면 \u003Cstrong>got-scraping\u003C\u002Fstrong>이라는 이름을 들어본 적이 있을 것입니다. 이 라이브러리는 Apify가 \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fsindresorhus\u002Fgot\" rel=\"noopener noreferrer\">got\u003C\u002Fa>을 기반으로 만든 HTTP 클라이언트로, 브라우저와 거의 구별할 수 없는 요청을 생성하도록 설계되었습니다. 일반적인 \u003Ccode>got\u003C\u002Fcode>이나 \u003Ccode>axios\u003C\u002Fcode> 호출은 단 몇 번의 요청 만에 봇 감지 시스템에 노출되지만, got-scraping은 일관된 헤더 세트, HTTP\u002F2 지원, 그리고 프록시 라우팅을 통해 그 간극을 메워줍니다.\u003C\u002Fp>\n\u003Cp>이 글에서는 got-scraping을 프록시 미들웨어로 다루는 방법, ProxyHat \u003Ca href=\"\u002Fko\u002Fproxy\u002Fresidential\">주거 프록시\u003C\u002Fa>를 \u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>에 연결하는 방법, 그리고 Crawlee로 확장하는 패턴까지 실전 코드와 함께 살펴봅니다.\u003C\u002Fp>\n\u003Cblockquote>\u003Cstrong>법적 주의사항:\u003C\u002Fstrong> 이 글은 공개 데이터 수집을 전제로 합니다. 미국의 CFAA(컴퓨터 사기 및 남용법)과 EU의 GDPR은 비공개 데이터나 ToS 위반 수집에 강력한 제재를 가할 수 있습니다. \u003Ccode>robots.txt\u003C\u002Fcode>를 준수하고, 속도 제한을 존중하며, 공식 API가 있다면 그것을 먼저 사용하세요.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\n\u003Ch2>왜 일반 got\u002Faxios 요청이 감지되는가\u003C\u002Fh2>\n\u003Cp>대부분의 스크래핑 차단은 TLS 지문, 헤더 순서, 그리고 IP 평판이라는 세 가지 축에서 발생합니다. 순수 \u003Ccode>got\u003C\u002Fcode>은 기본적으로 \u003Ccode>User-Agent\u003C\u002Fcode> 하나만 설정하면 끝이라고 착각하기 쉽지만, 현대 봇 감지 시스템은 훨씬 더 깊이 들여다봅니다.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>헤더 순서:\u003C\u002Fstrong> Chrome, Firefox, Safari는 각자 고유한 헤더 순서를 사용합니다. \u003Ccode>accept\u003C\u002Fcode>가 \u003Ccode>accept-encoding\u003C\u002Fcode>보다 먼저 오는지, \u003Ccode>sec-ch-ua\u003C\u002Fcode>가 \u003Ccode>user-agent\u003C\u002Fcode>보다 먼저 오는지가 중요합니다.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>sec-ch-ua 계열:\u003C\u002Fstrong> Chromium 기반 브라우저는 \u003Ccode>sec-ch-ua\u003C\u002Fcode>, \u003Ccode>sec-ch-ua-mobile\u003C\u002Fcode>, \u003Ccode>sec-ch-ua-platform\u003C\u002Fcode> 헤더를 보냅니다. 이 값들이 \u003Ccode>user-agent\u003C\u002Fcode>와 일치하지 않으면 즉시 의심을 받습니다.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>accept-language 일관성:\u003C\u002Fstrong> \u003Ccode>en-US,en;q=0.9\u003C\u002Fcode> 같은 값이 IP의 지역과 어울리지 않으면 신호가 됩니다.\u003C\u002Fli>\n\u003Cli>HTTP\u002F2 사용 여부: 실제 Chrome은 HTTP\u002F2를 사용하지만, 많은 스크래퍼가 여전히 HTTP\u002F1.1로 요청을 보냅니다.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>got-scraping의 header-generator는 이 문제를 근본적으로 해결합니다. 브라우저, 운영체제, 기기 조합을 입력하면 그에 맞는 일관된 헤더 세트 전체를 생성합니다. 단순히 \u003Ccode>user-agent\u003C\u002Fcode>만 바꾸는 것이 아니라, \u003Ccode>accept\u003C\u002Fcode>, \u003Ccode>accept-encoding\u003C\u002Fcode>, \u003Ccode>accept-language\u003C\u002Fcode>, \u003Ccode>sec-ch-ua\u003C\u002Fcode> 계열, \u003Ccode>upgrade-insecure-requests\u003C\u002Fcode>까지 브라우저 프로필에 맞춰 정확한 순서로 배치합니다.\u003C\u002Fp>\n\u003Cp>이것이 got scraping header generator가 다른 헤더 위장 기법보다 신뢰할 수 있는 이유입니다. 직접 헤더를 하드코딩하면 한 글자만 틀려도 지문이 어긋나지만, header-generator는 수천 개의 실제 브라우저 프로필을 기반으로 일관성을 보장합니다.\u003C\u002Fp>\n\n\u003Ch2>got-scraping의 관용적 사용법\u003C\u002Fh2>\n\u003Cp>got-scraping은 got의 확장이므로, got의 모든 옵션을 그대로 사용할 수 있습니다. 핵심은 \u003Ccode>got.extend()\u003C\u002Fcode>로 커스텀 인스턴스를 만들고 \u003Ccode>useHeaderGenerator\u003C\u002Fcode> 옵션을 켜는 것입니다.\u003C\u002Fp>\n\n\u003Ch3>기본 인스턴스 구성\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\nimport { HeaderGenerator } from &apos;got-scraping&apos;;\n\nconst headerGenerator = new HeaderGenerator({\n  browsers: [&apos;chrome&apos;],\n  devices: [&apos;desktop&apos;],\n  operatingSystems: [&apos;windows&apos;, &apos;macos&apos;],\n});\n\nconst client = gotScraping.extend({\n  useHeaderGenerator: true,\n  headerGeneratorOptions: {\n    browsers: [&apos;chrome&apos;],\n    devices: [&apos;desktop&apos;],\n    operatingSystems: [&apos;windows&apos;, &apos;macos&apos;],\n  },\n  http2: true,\n  timeout: { request: 30000 },\n  retry: { limit: 3 },\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>headerGeneratorOptions\u003C\u002Fcode>는 \u003Ccode>HeaderGenerator\u003C\u002Fcode> 생성자와 동일한 스키마를 받습니다. \u003Ccode>browsers\u003C\u002Fcode>, \u003Ccode>devices\u003C\u002Fcode>, \u003Ccode>operatingSystems\u003C\u002Fcode> 배열을 조합해 원하는 브라우저 프로필을 만듭니다. \u003Ccode>http2: true\u003C\u002Fcode>는 가능한 경우 HTTP\u002F2를 사용하도록 강제합니다.\u003C\u002Fp>\n\n\u003Ch3>proxyUrl 옵션\u003C\u002Fh3>\n\u003Cp>got-scraping은 \u003Ccode>proxyUrl\u003C\u002Fcode> 옵션을 통해 HTTP\u002F1.1과 HTTP\u002F2 프록시를 모두 지원합니다. 이 옵션은 got의 \u003Ccode>agent\u003C\u002Fcode>를 직접 만지는 것보다 훨씬 안전합니다. HTTP\u002F2 프록시를 사용할 때는 \u003Ccode>proxyUrl\u003C\u002Fcode>이 \u003Ccode>https:\u002F\u002F\u003C\u002Fcode> 스킴을 사용해야 하며, got-scraping이 자동으로 \u003Ccode>CONNECT\u003C\u002Fcode> 터널을 설정합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>const res = await client(&apos;https:\u002F\u002Fexample.com&apos;, {\n  proxyUrl: &apos;http:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:8080&apos;,\n});\nconsole.log(res.statusCode, res.body.slice(0, 200));\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>이것이 got-scraping proxy의 기본 형태입니다. \u003Ccode>proxyUrl\u003C\u002Fcode>에 ProxyHat 게이트웨이를 넣기만 하면 됩니다.\u003C\u002Fp>\n\n\u003Ch2>ProxyHat 주거 프록시로 라우팅하기\u003C\u002Fh2>\n\u003Cp>헤더와 TLS가 완벽해도 IP 평판이 나쁘면 차단은 피할 수 없습니다. 데이터센터 IP는 Cloudflare, Akamai, PerimeterX 같은 시스템에서 거의 즉시 플래그됩니다. 주거 프록시는 실제 ISP가 할당한 주거 IP를 사용하므로, 헤더와 IP가 일관된 지역을 가리킬 때 가장 강력한 조합이 됩니다.\u003C\u002Fp>\n\u003Cp>ProxyHat 주거 프록시는 \u003Ccode>gate.proxyhat.com\u003C\u002Fcode> 게이트웨이를 통해 접근합니다. HTTP는 포트 \u003Ccode>8080\u003C\u002Fcode>, SOCKS5는 포트 \u003Ccode>1080\u003C\u002Fcode>을 사용합니다. 사용자 이름에 국가, 도시, 세션 플래그를 넣어 지역 타겟팅과 세션 고정을 제어합니다.\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>연결 유형\u003C\u002Fth>\u003Cth>URL 형식\u003C\u002Fth>\u003Cth>사용 사례\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>HTTP (기본)\u003C\u002Ftd>\u003Ctd>\u003Ccode>http:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:8080\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>대부분의 HTTP\u002FHTTPS 스크래핑\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>HTTP + 세션\u003C\u002Ftd>\u003Ctd>\u003Ccode>http:\u002F\u002Fuser-country-US-sid-abc123:pass@gate.proxyhat.com:8080\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>로그인 상태 유지, 다단계 폼\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>HTTP + 도시\u003C\u002Ftd>\u003Ctd>\u003Ccode>http:\u002F\u002Fuser-country-DE-region-state_of_berlin-city-berlin:pass@gate.proxyhat.com:8080\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>지역별 가격\u002F콘텐츠 차이 분석\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>SOCKS5\u003C\u002Ftd>\u003Ctd>\u003Ccode>socks5:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:1080\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>TCP 레벨 터널링, 특수 프로토콜\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>SOCKS5는 HTTP 프록시가 차단되는 일부 환경에서 유용하지만, 대부분의 웹 스크래핑에서는 HTTP 게이트웨이가 충분합니다. SOCKS5는 \u003Ccode>socks5:\u002F\u002F\u003C\u002Fcode> 스키마를 사용하며 got-scraping의 \u003Ccode>proxyUrl\u003C\u002Fcode>에 그대로 넣을 수 있습니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>const res = await client(&apos;https:\u002F\u002Fexample.com&apos;, {\n  proxyUrl: &apos;socks5:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:1080&apos;,\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>요청별 세션 회전 예제\u003C\u002Fh2>\n\u003Cp>이제 실제로 동작하는 Node.js 예제를 봅시다. 이 예제는 ProxyHat 사용자 이름을 요청마다 생성하고, got의 \u003Ccode>hooks\u003C\u002Fcode>로 재시도 로직을 추가합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\nimport { randomUUID } from &apos;node:crypto&apos;;\n\nconst PROXYHAT_USER = &apos;user&apos;;\nconst PROXYHAT_PASS = &apos;pass&apos;;\nconst GATEWAY = &apos;gate.proxyhat.com:8080&apos;;\n\nfunction buildProxyUrl({ country = &apos;US&apos;, session } = {}) {\n  const sid = session ?? randomUUID().slice(0, 12);\n  const username = `${PROXYHAT_USER}-country-${country}-sid-${sid}`;\n  const encoded = encodeURIComponent(username);\n  return `http:\u002F\u002F${encoded}:${PROXYHAT_PASS}@${GATEWAY}`;\n}\n\nconst client = gotScraping.extend({\n  useHeaderGenerator: true,\n  headerGeneratorOptions: {\n    browsers: [&apos;chrome&apos;],\n    devices: [&apos;desktop&apos;],\n    operatingSystems: [&apos;windows&apos;],\n  },\n  http2: true,\n  timeout: { request: 30000 },\n  retry: { limit: 3, statusCodes: [403, 429, 500, 502, 503] },\n  hooks: {\n    beforeRequest: [\n      (options) =&gt; {\n        \u002F\u002F 매 요청마다 새 세션 ID로 새 IP 할당\n        options.proxyUrl = buildProxyUrl({ country: &apos;US&apos; });\n      },\n    ],\n    afterResponse: [\n      async (response, retryWithMergedOptions) =&gt; {\n        if (response.statusCode === 403 || response.statusCode === 429) {\n          \u002F\u002F IP가 차단된 것으로 보이면 새 세션으로 재시도\n          return retryWithMergedOptions({\n            proxyUrl: buildProxyUrl({ country: &apos;US&apos; }),\n          });\n        }\n        return response;\n      },\n    ],\n  },\n});\n\n\u002F\u002F 사용 예\nconst targets = [\n  &apos;https:\u002F\u002Fexample.com\u002Fpage-1&apos;,\n  &apos;https:\u002F\u002Fexample.com\u002Fpage-2&apos;,\n  &apos;https:\u002F\u002Fexample.com\u002Fpage-3&apos;,\n];\n\nfor (const url of targets) {\n  const res = await client(url);\n  console.log(res.statusCode, url, res.body.slice(0, 80));\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>beforeRequest\u003C\u002Fcode> 훅은 매 요청마다 \u003Ccode>proxyUrl\u003C\u002Fcode>을 새로 설정하므로, 각 요청이 다른 주거 IP에서 나갑니다. \u003Ccode>afterResponse\u003C\u002Fcode> 훅은 403\u002F429를 받으면 새 세션으로 재시도합니다. 이 패턴은 nodejs scraping proxy 운영에서 가장 자주 쓰이는 형태입니다.\u003C\u002Fp>\n\u003Cp>더 많은 엔드포인트 옵션은 \u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHat 공식 문서\u003C\u002Fa>에서 확인할 수 있습니다.\u003C\u002Fp>\n\n\u003Ch2>프로덕션 패턴\u003C\u002Fh2>\n\n\u003Ch3>제한된 동시성\u003C\u002Fh3>\n\u003Cp>수백 개의 요청을 동시에 보내면 ProxyHat 게이트웨이는 잘 버텨도 타겟 서버가 막히거나 차단합니다. \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fsindresorhus\u002Fp-limit\" rel=\"noopener noreferrer\">p-limit\u003C\u002Fa>로 동시성을 묶으세요.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>import pLimit from &apos;p-limit&apos;;\n\nconst limit = pLimit(20); \u002F\u002F 동시 20개 요청\n\nconst results = await Promise.all(\n  urls.map((url) =&gt; limit(() =&gt; client(url)))\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>20~50 동시 요청이 주거 프록시 스크래핑의 무난한 시작점입니다. 응답 시간이 200ms 이하로 유지된다면 점차 올리되, 429 비율이 5%를 넘으면 줄이세요.\u003C\u002Fp>\n\n\u003Ch3>쿠키 jar\u003C\u002Fh3>\n\u003Cp>세션 고정이 필요한 경우 (예: 로그인 후 페이지네이션), \u003Ccode>cookieJar\u003C\u002Fcode> 옵션과 ProxyHat 세션 플래그를 함께 사용하세요. got은 \u003Ccode>tough-cookie\u003C\u002Fcode> 기반 jar를 지원합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>import { gotScraping } from &apos;got-scraping&apos;;\nimport { CookieJar } from &apos;tough-cookie&apos;;\n\nconst jar = new CookieJar();\nconst session = &apos;login-flow-001&apos;;\n\nconst proxyUrl = `http:\u002F\u002F${encodeURIComponent(\n  `user-country-US-sid-${session}`\n)}:pass@gate.proxyhat.com:8080`;\n\nconst client = gotScraping.extend({\n  cookieJar: jar,\n  useHeaderGenerator: true,\n  http2: true,\n});\n\n\u002F\u002F 같은 세션 IP + 쿠키로 다단계 폼 진행\nawait client.post(&apos;https:\u002F\u002Fexample.com\u002Flogin&apos;, {\n  proxyUrl,\n  json: { user: &apos;foo&apos;, pass: &apos;bar&apos; },\n});\nawait client.get(&apos;https:\u002F\u002Fexample.com\u002Fdashboard&apos;, { proxyUrl });\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>세션 ID가 같으면 ProxyHat은 같은 출구 IP를 유지하므로, 쿠키와 IP가 일관되게 유지됩니다.\u003C\u002Fp>\n\n\u003Ch3>Crawlee CheerioCrawler로 확장\u003C\u002Fh3>\n\u003Cp>수천 페이지를 크롤링해야 한다면 \u003Ca href=\"https:\u002F\u002Fcrawlee.dev\u002F\" rel=\"noopener noreferrer\">Crawlee\u003C\u002Fa>의 \u003Ccode>CheerioCrawler\u003C\u002Fcode>가 자연스러운 다음 단계입니다. Crawlee는 got-scraping을 내부적으로 사용하므로, 프록시 설정이 그대로 적용됩니다.\u003C\u002Fp>\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    devices: [&apos;desktop&apos;],\n    operatingSystems: [&apos;windows&apos;],\n  },\n  proxyConfiguration: {\n    newUrlFunction: () =&gt;\n      `http:\u002F\u002F${encodeURIComponent(\n        `user-country-US-sid-${randomUUID().slice(0, 12)}`\n      )}:pass@gate.proxyhat.com:8080`,\n  },\n  maxConcurrency: 20,\n  requestHandler: async ({ $, request }) =&gt; {\n    const title = $(&apos;title&apos;).text();\n    console.log(request.url, title);\n  },\n});\n\nawait crawler.run([&apos;https:\u002F\u002Fexample.com\u002Fpage-1&apos;, &apos;https:\u002F\u002Fexample.com\u002Fpage-2&apos;]);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>proxyConfiguration.newUrlFunction\u003C\u002Fcode>은 각 요청마다 새 프록시 URL을 반환합니다. 이것이 Crawlee에서 got-scraping proxy를 회전시키는 관용적 방법입니다.\u003C\u002Fp>\n\n\u003Ch3>컨테이너화\u003C\u002Fh3>\n\u003Cp>스케일아웃이 필요하면 각 컨테이너가 독립적인 세션 풀을 가지도록 설계하세요. 예를 들어 10개 컨테이너가 각각 50 동시 요청을 처리하면 총 500 동시 세션이 됩니다. 컨테이너 간 세션 ID 충돌을 피하려면 호스트명이나 컨테이너 ID를 세션 접두사로 사용하세요.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>const containerId = process.env.HOSTNAME ?? &apos;local&apos;;\nconst session = `${containerId}-${randomUUID().slice(0, 8)}`;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>헤드리스 브라우저가 불가피한 순간\u003C\u002Fh2>\n\u003Cp>got-scraping은 강력하지만, 다음 상황에서는 한계가 있습니다.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>JavaScript 렌더링 필수: 콘텐츠가 클라이언트 사이드에서 로드되는 SPA.\u003C\u002Fli>\n\u003Cli>복잡한 CAPTCHA: hCaptcha, reCAPTCHA v3가 챌린지를 강제하는 경우.\u003C\u002Fli>\n\u003Cli>행동 지문: 마우스 이동, 스크롤 패턴을 검사하는 고급 시스템.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>이때는 Playwright나 Puppeteer로 헤드리스 Chrome을 띄우고, ProxyHat 주거 프록시를 브라우저 수준에서 설정하세요. Crawlee의 \u003Ccode>PlaywrightCrawler\u003C\u002Fcode>는 got-scraping과 같은 \u003Ccode>proxyConfiguration\u003C\u002Fcode> 인터페이스를 사용하므로 전환 비용이 낮습니다.\u003C\u002Fp>\n\u003Cp>다만 헤드리스 브라우저는 메모리와 CPU 비용이 got-scraping의 수십 배입니다. 가능하면 got-scraping으로 먼저 시도하고, 진짜 렌더링이 필요한 페이지만 헤드리스로 라우팅하는 하이브리드 전략이 비용 효율적입니다.\u003C\u002Fp>\n\n\u003Ch2>윤리와 컴플라이언스\u003C\u002Fh2>\n\u003Cp>기술적으로 가능하다고 해서 합법적인 것은 아닙니다. 스크래핑 전 다음을 확인하세요.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>공개 데이터만: 로그인 없이 접근할 수 없는 페이지는 CFAA 위반 소지가 있습니다.\u003C\u002Fli>\n\u003Cli>GDPR: EU 거주자 개인 데이터를 수집하면 동의 기반 또는 정당한 이익 근거가 필요합니다.\u003C\u002Fli>\n\u003Cli>robots.txt: \u003Ccode>Disallow\u003C\u002Fcode>된 경로는 수집하지 마세요. 법적 강제력은 약하지만, ToS 위반 주장의 근거가 됩니다.\u003C\u002Fli>\n\u003Cli>속도 제한: 타겟 서버에 부하를 주지 않는 속도를 유지하세요. 분당 60~600 요청이 일반적인 안전 범위입니다.\u003C\u002Fli>\n\u003Cli>공식 API 우선: 공식 API가 있다면 스크래핑보다 안정적이고 합법적입니다.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>핵심 요약\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>got-scraping은 header-generator로 일관된 브라우저 헤더 세트를 생성하고 HTTP\u002F2를 지원해 차단을 줄입니다.\u003C\u002Fli>\n\u003Cli>\u003Ccode>got.extend()\u003C\u002Fcode> + \u003Ccode>useHeaderGenerator\u003C\u002Fcode> + \u003Ccode>headerGeneratorOptions\u003C\u002Fcode>가 관용적 구성 패턴입니다.\u003C\u002Fli>\n\u003Cli>ProxyHat 주거 프록시는 \u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>(HTTP) 또는 \u003Ccode>:1080\u003C\u002Fcode>(SOCKS5)로 연결하며, 사용자 이름에 국가\u002F세션 플래그를 넣습니다.\u003C\u002Fli>\n\u003Cli>\u003Ccode>beforeRequest\u003C\u002Fcode> 훅에서 요청마다 새 세션 ID를 생성해 IP를 회전시키세요.\u003C\u002Fli>\n\u003Cli>동시성은 \u003Ccode>p-limit\u003C\u002Fcode>로 묶고, 대규모 크롤링은 Crawlee \u003Ccode>CheerioCrawler\u003C\u002Fcode>로 넘기세요.\u003C\u002Fli>\n\u003Cli>헤드리스 브라우저는 JavaScript 렌더링이 진짜 필요할 때만 사용하세요.\u003C\u002Fli>\n\u003Cli>공개 데이터, robots.txt, 속도 제한을 존중하고 공식 API를 먼저 확인하세요.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>ProxyHat 주거 프록시로 바로 시작하려면 \u003Ca href=\"\u002Fko\u002Fpricing\">프라이싱 페이지\u003C\u002Fa>를 확인하고, \u003Ca href=\"\u002Fko\u002Fuse-cases\u002Fweb-scraping\">웹 스크래핑 사용 사례\u003C\u002Fa>와 \u003Ca href=\"\u002Fko\u002Fuse-cases\u002Fserp-tracking\">SERP 추적 사용 사례\u003C\u002Fa>에서 더 많은 패턴을 살펴보세요. 사용 가능한 지역은 \u003Ca href=\"\u002Fko\u002Flocations\">위치 페이지\u003C\u002Fa>에서 확인할 수 있습니다.\u003C\u002Fp>","got-scraping nodejs 프록시 가이드 | ProxyHat","got-scraping nodejs로 브라우저 헤더 생성, ProxyHat 주거 프록시 라우팅, Crawlee 확장까지 실전 코드로 배우는 차단 우회 가이드입니다.","\u002Fko\u002Fblog\u002Fgot-scraping-nodejs-proxy-guide-1",null,"https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fgot-scraping-nodejs-proxy-guide-1-og.webp",[17,20,23,26],{"question":18,"answer":19},"got-scraping in Node.js란 무엇인가요?","got-scraping은 Apify가 got를 기반으로 만든 HTTP 클라이언트로, 브라우저와 구별하기 어려운 요청을 생성하도록 설계되었습니다. 핵심은 header-generator가 일관된 헤더 세트(순서, sec-ch-ua, accept-language)를 생성하고, HTTP\u002F2를 지원하며, proxyUrl 옵션으로 프록시 라우팅을 단순화한다는 점입니다. 일반 got나 axios와 달리 봇 감지 시스템을 통과하기 위한 기본 기능이 내장되어 있습니다.",{"question":21,"answer":22},"got-scraping에 어떤 프록시 유형이 가장 적합한가요?","주거 프록시가 가장 적합합니다. 데이터센터 IP는 Cloudflare, Akamai 같은 시스템에서 즉시 플래그되는 반면, 주거 IP는 실제 ISP 할당이므로 헤더와 IP 지역이 일치할 때 가장 자연스럽습니다. ProxyHat 주거 프록시는 gate.proxyhat.com:8080(HTTP) 또는 :1080(SOCKS5)로 연결하며, 사용자 이름에 국가와 세션 플래그를 넣어 지역 타겟팅과 세션 고정을 제어합니다.",{"question":24,"answer":25},"got-scraping으로 차단을 피하려면 어떻게 하나요?","세 가지를 함께 사용하세요. 첫째, header-generator로 브라우저 프로필을 일관되게 생성합니다. 둘째, 주거 프록시로 IP 평판을 확보하고, 요청마다 세션 ID를 바꿔 IP를 회전시킵니다. 셋째, p-limit로 동시성을 20~50으로 묶고, got의 afterResponse 훅에서 403\u002F429 응답을 새 세션으로 재시도합니다. 이 조합이 대부분의 중간 수준 봇 감지를 통과합니다.",{"question":27,"answer":28},"got-scraping과 Crawlee는 어떤 관계인가요?","Crawlee는 Apify가 만든 크롤링 프레임워크로, CheerioCrawler와 PlaywrightCrawler 내부에서 got-scraping을 사용합니다. 따라서 got-scraping의 header-generator, proxyUrl, HTTP\u002F2 지원이 Crawlee에 그대로 적용됩니다. 단일 페이지 요청은 got-scraping을 직접 쓰고, 수천 페이지 크롤링은 Crawlee로 넘어가는 것이 자연스러운 확장 경로입니다.",false,"2026-08-04T16:05:06+00:00","2026-10-03T08:29:58+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fgot-scraping-nodejs-proxy-guide-1-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fgot-scraping-nodejs-proxy-guide-1-card.webp",12,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[41],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},4,"gaebaljja-gaideu","개발자 가이드","개발자 가이드 | ProxyHat 블로그","프록시를 애플리케이션에 통합하기 위한 코드 튜토리얼 및 SDK 가이드.",[],{"en":49,"ru":50,"it":51,"zh":52,"fr":53,"pl":54,"ko":13,"ja":55,"x-default":49},"\u002Fblog\u002Fgot-scraping-nodejs-residential-proxies","\u002Fru\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","\u002Fja\u002Fblog\u002Fgot-scraping-nodejs-purokishi",{"en":49,"ru":50,"it":51,"de":57,"es":58,"pt":59,"zh":52,"fr":53,"pl":54,"ko":13,"ja":55,"tr":60},"\u002Fde\u002Fblog\u002Fgot-scraping-nodejs-proxy-guide","\u002Fes\u002Fblog\u002Fguia-got-scraping-nodejs-proxy-residencial","\u002Fpt\u002Fblog\u002Fguia-got-scraping-nodejs-proxies-residenciais","\u002Ftr\u002Fblog\u002Fnodejs-got-scraping-proxy-rehberi",121,[63,97,124,140],{"id":64,"slug":65,"title":66,"excerpt":67,"featured_image_url":68,"featured_image_alt":69,"card_image_url":70,"og_image_url":71,"published_at":72,"updated_at":73,"content_updated_at":74,"reading_time_minutes":75,"is_featured":29,"indexable":4,"views":76,"author":77,"categories":78,"tags":80},210,"ai-agent-proxy-seoljeong","AI 에이전트 프록시 설정: browser-use·Crawl4AI·MCP","클라우드 VM의 에이전트는 데이터센터 IP로 접속합니다. browser-use, Crawl4AI, MCP 서버에서 지금 작동하는 프록시 설정을 sticky와 로테이션 선택 표, 피해야 할 비용 함정과 함께 정리했습니다.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fai-agent-proxy-seoljeong-master.webp","Proxy Setup for AI Agents: browser-use, Crawl4AI and an MCP Server","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fai-agent-proxy-seoljeong-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fai-agent-proxy-seoljeong-og.webp","2026-10-24T09:00:00+00:00","2026-10-24T09:00:20+00:00","2026-10-03T09:41:40+00:00",14,15,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[79],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[81,85,89,93],{"id":82,"slug":83,"name":84},1,"web-scraping","웹 스크래핑",{"id":86,"slug":87,"name":88},2,"residential-proxies","주거용 프록시",{"id":90,"slug":91,"name":92},9,"python","Python",{"id":94,"slug":95,"name":96},22,"playwright","Playwright",{"id":98,"slug":99,"title":100,"excerpt":101,"featured_image_url":102,"featured_image_alt":103,"card_image_url":104,"og_image_url":105,"published_at":106,"updated_at":107,"content_updated_at":74,"reading_time_minutes":75,"is_featured":29,"indexable":4,"views":108,"author":109,"categories":110,"tags":112},206,"camoufox-residential-proxy-python-gaideu","Camoufox와 레지덴셜 프록시: 코드로 보는 Python 가이드","C++ 레벨에서 패치한 Firefox인 Camoufox를 레지덴셜 프록시 뒤에서 돌리는 방법. 최신 Python API, geoip에 스티키 세션이 필요한 이유, 핑거프린트 일관성 체크리스트, 그리고 Patchright나 nodriver가 더 맞는 경우를 정리했습니다.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcamoufox-residential-proxy-python-gaideu-master.webp","Camoufox with Residential Proxies: A Code-First Python Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcamoufox-residential-proxy-python-gaideu-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcamoufox-residential-proxy-python-gaideu-og.webp","2026-10-13T09:00:00+00:00","2026-10-13T09:00:22+00:00",31,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[111],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[113,114,115,119,120],{"id":82,"slug":83,"name":84},{"id":86,"slug":87,"name":88},{"id":116,"slug":117,"name":118},6,"anti-detection","안티 탐지",{"id":90,"slug":91,"name":92},{"id":121,"slug":122,"name":123},21,"headless-browser","헤드리스 브라우저",{"id":125,"slug":126,"title":127,"excerpt":128,"featured_image_url":129,"featured_image_alt":130,"card_image_url":131,"og_image_url":132,"published_at":133,"updated_at":133,"content_updated_at":134,"reading_time_minutes":35,"is_featured":29,"indexable":29,"views":135,"author":136,"categories":137,"tags":139},175,"colly-rotating-proxy-guide","Colly에서 로테이션 프록시 사용하기: Go 웹 스크래핑 완전 가이드","Go의 Colly 프레임워크에서 RoundRobinProxySwitcher와 SetProxyFunc를 활용해 ProxyHat 주거 프록시를 로테이션하는 방법을 코드 예제와 함께 다룹니다. 프로덕션 패턴, 재시도, 분산 스크래핑까지.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcolly-rotating-proxy-guide-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcolly-rotating-proxy-guide-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcolly-rotating-proxy-guide-og.webp","2026-08-04T10:05:34+00:00","2026-10-03T23:53:00+00:00",71,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[138],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],{"id":141,"slug":142,"title":143,"excerpt":144,"featured_image_url":145,"featured_image_alt":146,"card_image_url":147,"og_image_url":148,"published_at":149,"updated_at":149,"content_updated_at":150,"reading_time_minutes":35,"is_featured":29,"indexable":4,"views":151,"author":152,"categories":153,"tags":155},195,"bybit-v5-market-api-proxy-scraping","회전 프록시로 암호화폐 시장 데이터 수집하기 (Bybit V5 Market API 사례)","Bybit V5 Market API의 orderbook, tickers, kline, recent-trade 엔드포인트를 회전 프록시로 안정적으로 수집하는 개발자 가이드입니다. IP 레이트 리밋, 지역 제한, ProxyHat SDK 예제를 포함합니다.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\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\u002Fko\u002Fbybit-v5-market-api-proxy-scraping-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fbybit-v5-market-api-proxy-scraping-og.webp","2026-08-03T16:09:16+00:00","2026-10-04T01:29:51+00:00",87,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[154],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],[]]