블로그로 돌아가기

hh.ru, Superjob 및 LinkedIn에서 채용 공고 크롤링을 위한 프록시: 완벽 가이드

직업 게시판 파싱을 위한 프록시 설정에 대한 자세한 가이드: 프록시 유형 선택, hh.ru 및 Superjob 보호 우회, IP 회전 설정 및 캡차 처리.

📅2026년 3월 12일
```html

채용 공고 파싱은 HR 분석, 노동 시장 모니터링 및 채용 자동화를 위한 데이터 수집 시나리오 중 가장 수요가 많은 것 중 하나입니다. 그러나 채용 사이트는 자동 데이터 수집을 적극적으로 방어하고 있습니다: 50-100개의 요청 후 IP를 차단하고, CAPTCHA를 표시하며, 의심스러운 계정을 차단합니다. 이 기사에서는 hh.ru, Superjob, LinkedIn 및 기타 플랫폼에서 차단 없이 안정적인 파싱을 위해 프록시를 올바르게 설정하는 방법을 살펴보겠습니다.

채용 공고 사이트가 파싱을 차단하는 이유와 보호 작동 방식

채용 사이트는 파싱으로 인해 손실을 입습니다: 데이터가 경쟁자에게 판매되고, 라이센스 없이 집계기가 생성되며, 고용주가 유료 게시를 우회합니다. 따라서 모든 주요 플랫폼은 자동 데이터 수집에 대한 다단계 보호를 도입했습니다.

채용 공고 사이트의 주요 보호 방법:

  • IP별 속도 제한 — hh.ru는 시간당 80-120개의 요청 후 IP를 차단하고, Superjob은 50-70개의 요청 후 차단합니다. 차단은 1시간에서 하루까지 지속될 수 있습니다.
  • 브라우저 지문 인식 — 사이트는 User-Agent, HTTP 헤더, 화면 해상도, 설치된 글꼴을 분석합니다. 데이터가 실제 브라우저와 일치하지 않으면 요청이 차단됩니다.
  • JavaScript 검사 — 많은 사이트가 Cloudflare 또는 자체 스크립트를 사용하여 요청이 실제 브라우저에서 오는지 확인합니다.
  • 허니팟 트랩 — 파서만 볼 수 있는 숨겨진 링크와 필드입니다. 봇이 이 링크를 클릭하면 IP가 블랙리스트에 올라갑니다.
  • 의심스러운 활동 시 CAPTCHA — 빠른 요청 시리즈 후 또는 데이터 센터 IP를 사용할 때 나타납니다.

프록시 없이 최대 100-200개의 채용 공고를 파싱할 수 있으며, 그 후에는 IP가 차단됩니다. 대규모 데이터 수집(매일 수천 개의 채용 공고)을 위해 프록시는 필수 도구가 됩니다.

중요: 파싱은 사이트의 이용 약관에 부합해야 합니다. 많은 채용 공고 사이트는 데이터에 대한 합법적인 접근을 위한 공식 API를 제공합니다. 예를 들어, hh.ru는 대부분의 작업에 적합한 요청 한도가 있는 무료 API를 제공합니다.

채용 공고 파싱을 위한 프록시 유형 선택

프록시 유형 선택은 파싱 규모, 예산 및 속도 요구 사항에 따라 다릅니다. 세 가지 주요 옵션을 특정 사용 시나리오와 함께 살펴보겠습니다.

프록시 유형 속도 차단 위험 언제 사용해야 하는가
데이터 센터 프록시 높음 (50-200 ms) 높음 파서 테스트, 인증 없이 공개 데이터 수집
주거용 프록시 중간 (200-800 ms) 낮음 IP 회전과 함께 hh.ru, Superjob 대규모 파싱
모바일 프록시 중간 (300-1000 ms) 매우 낮음 인증이 필요한 파싱, LinkedIn의 강력한 보호 우회

채용 공고 파싱을 위한 데이터 센터 프록시

이것은 가장 빠르고 저렴한 옵션이지만 제한이 있습니다. 데이터 센터 IP는 사이트에서 쉽게 인식되므로 인증 없이 채용 공고 목록 파싱, 공개 데이터 수집, 주거용 프록시로 실행하기 전에 파서 테스트와 같은 간단한 작업에만 적합합니다.

데이터 센터 프록시가 작동하는 경우:

  • 소량의 데이터 파싱 (하루 500개 이하의 채용 공고)
  • 강력한 보호가 없는 사이트에서 데이터 수집 (소규모 지역 채용 공고 사이트)
  • 속도 제한을 우회하기 위한 IP 회전과 함께 공식 API 사용
  • RSS 피드 및 XML 파일의 채용 공고 파싱

hh.ru 및 Superjob의 경우 데이터 센터 프록시는 불안정하게 작동합니다: 20-30개의 요청 후 CAPTCHA가 나타나고, 많은 IP가 이미 이 사이트의 블랙리스트에 올라 있습니다.

주거용 프록시 — 채용 공고 사이트에 최적의 선택

주거용 프록시는 실제 가정 사용자의 IP 주소를 사용하므로 사이트는 이를 일반 방문자로 인식합니다. 이는 채용 공고 파싱을 위한 가격과 품질의 최적의 균형입니다.

채용 공고 사이트 파싱의 장점:

  • 차단 위험 낮음 — hh.ru 및 Superjob은 주거용 IP를 실제 사용자와 구별할 수 없습니다.
  • 광범위한 IP 풀 — 각 요청마다 또는 5-10분마다 IP 회전 설정 가능
  • 지리적 연결성 — 특정 도시의 채용 공고를 해당 지역의 IP를 사용하여 파싱 가능
  • 안정성 — 하나의 주거용 IP는 차단 없이 200-500개의 요청을 처리할 수 있습니다.

대규모 파싱(하루 1000개 이상의 채용 공고)의 경우 IP 회전이 있는 주거용 프록시는 표준 솔루션입니다. IP를 5-10분마다 변경하고 요청 간에 임의의 지연(3-7초)을 추가하여 차단 없이 안정적인 데이터 수집을 할 수 있습니다.

LinkedIn 및 인증이 필요한 파싱을 위한 모바일 프록시

모바일 프록시는 모바일 운영자의 IP를 사용합니다. 이들의 주요 장점은 하나의 IP가 수백 명의 실제 사용자에 의해 동시에 사용되므로 사이트는 이러한 주소를 차단할 위험 없이 일반 방문자를 차단할 수 없습니다.

모바일 프록시가 필요한 경우:

  • LinkedIn 파싱 — 이 플랫폼은 봇에 대한 가장 강력한 보호를 가지고 있으며 데이터 센터 및 주거용 IP를 적극적으로 차단합니다.
  • 인증이 필요한 작업 — 비공개 채용 공고 또는 프로필 데이터를 파싱해야 하는 경우 모바일 IP는 계정 차단 위험을 줄입니다.
  • 해외 채용 공고 사이트 파싱 — Indeed, Glassdoor, Monster는 고급 보호 시스템을 사용하며 모바일 IP가 더 안정적으로 작동합니다.
  • 강력한 차단 우회 — 주거용 프록시가 CAPTCHA를 받기 시작하면 모바일로 전환하면 문제를 해결할 수 있습니다.

모바일 프록시의 단점은 높은 가격과 낮은 속도입니다. 그러나 차단이 허용되지 않는 중요한 작업에는 최선의 선택입니다.

hh.ru 파싱의 특징: 보호 및 우회 방법

hh.ru는 국내 채용 공고 사이트 중 가장 발전된 파싱 방어를 가진 러시아 최대 채용 사이트입니다. 이 사이트는 봇을 식별하기 위해 속도 제한, 지문 인식 및 행동 분석의 조합을 사용합니다.

hh.ru의 보호 작동 방식

1. IP 주소에 대한 제한: 한 IP에서 시간당 80-120개의 요청 후 사이트는 CAPTCHA를 표시하거나 HTTP 429(Too Many Requests)를 반환합니다. 차단은 파싱의 공격성에 따라 1시간에서 6시간까지 지속됩니다.

2. User-Agent 및 헤더 검사: hh.ru는 HTTP 요청의 헤더를 분석합니다. User-Agent가 실제 브라우저와 일치하지 않거나 표준 헤더(Accept-Language, Accept-Encoding)가 없으면 요청이 차단됩니다.

3. JavaScript 검사: hh.ru의 일부 페이지는 데이터를 로드하기 위해 JavaScript 실행을 요구합니다. 단순한 HTTP 파서는 headless 브라우저 없이 전체 콘텐츠를 얻을 수 없습니다.

4. 허니팟 링크: 페이지에는 파서만 볼 수 있는 숨겨진 요소가 있습니다. 스크립트가 이러한 링크를 클릭하면 IP가 24시간 동안 블랙리스트에 올라갑니다.

프록시를 통한 hh.ru 보호 우회 전략

차단 없이 hh.ru를 안정적으로 파싱하려면 다음 구성을 사용하세요:

hh.ru 파싱을 위한 최적의 설정:

  • 프록시 유형: IP를 5-10분마다 회전하는 주거용 프록시
  • 요청 간 지연: 4-8초 (임의 값)
  • User-Agent: 최신 브라우저(Chrome, Firefox, Safari)의 실제 User-Agent 회전
  • 헤더: 브라우저의 표준 헤더 전체 세트(Accept, Accept-Language, Accept-Encoding, Referer)
  • 쿠키: 동일 세션 내 요청 간 쿠키 저장 및 전송
  • 요청 제한: 하나의 IP에서 60-80개 요청 후 프록시 변경

안전한 행동 순서 예시:

  1. 필요한 지역의 IP를 가진 주거용 프록시에 연결합니다 (예: 모스크바)
  2. hh.ru의 메인 페이지에 첫 요청을 하고 쿠키를 받아 저장합니다.
  3. 5-7초 기다립니다 (페이지 읽기 시뮬레이션)
  4. 필요한 필터로 채용 공고 검색 페이지에 요청합니다.
  5. 채용 공고 목록을 파싱합니다 (보통 페이지당 20-50개)
  6. 각 채용 공고에 대해 4-6초 지연을 두고 상세 페이지에 요청합니다.
  7. 60-70개의 요청 후 프록시를 변경하고 주기를 반복합니다.

이러한 전략을 따르면 하루에 1000-2000개의 채용 공고를 차단 없이 파싱할 수 있습니다. 더 많은 양이 필요하다면 여러 개의 병렬 스트림을 실행하여 다른 프록시를 사용하세요.

조언: hh.ru는 채용 공고에 접근하기 위한 무료 API를 제공합니다. 대부분의 작업(노동 시장 분석, 급여 모니터링)에 대해 API는 HTML 파싱보다 더 안정적인 솔루션이 될 것입니다. 프록시는 API 작업 시 IP 회전을 위해 사용하여 속도 제한을 우회할 수 있습니다.

Superjob, LinkedIn 및 해외 플랫폼 파싱

Superjob: 보호의 특징

Superjob은 hh.ru에 비해 덜 강력한 보호를 가지고 있지만 여전히 파싱에 적극적으로 대응하고 있습니다. 주요 차이점은 다음과 같습니다:

  • 더 낮은 속도 제한: 시간당 50-70개의 요청 후 차단됩니다 (hh.ru의 80-120에 비해)
  • 헤더 검사 덜 엄격: 간소화된 헤더 세트를 사용할 수 있습니다.
  • JavaScript 보호 없음: 대부분의 데이터는 headless 브라우저 없이 간단한 HTTP 요청을 통해 접근할 수 있습니다.
  • 지역 차단: 일부 채용 공고는 특정 지역의 IP에서만 접근 가능합니다.

Superjob의 경우 10-15분마다 회전하는 주거용 프록시와 요청 간 3-5초의 지연이 충분합니다. 이를 통해 하루에 500-1000개의 채용 공고를 안정적으로 파싱할 수 있습니다.

LinkedIn: 가장 강력한 보호

LinkedIn은 별도의 이야기입니다. 이 플랫폼은 봇을 식별하기 위해 고급 머신 러닝 알고리즘을 사용하며 모든 소셜 네트워크 및 채용 공고 사이트 중에서 가장 공격적인 보호 시스템을 가지고 있습니다.

LinkedIn 보호의 특징:

  • 필수 인증: 대부분의 데이터는 인증된 사용자에게만 접근 가능합니다.
  • 행동 분석: LinkedIn은 스크롤 속도, 마우스 움직임, 페이지 체류 시간을 분석합니다.
  • 계정 차단: 의심스러운 활동이 감지되면 IP뿐만 아니라 계정 자체도 차단됩니다.
  • 프로필 조회 제한: 무료 계정은 월별로 제한된 수의 프로필만 조회할 수 있습니다.
  • JavaScript 실행 필수: headless 브라우저 없이는 파싱이 불가능합니다.

LinkedIn 파싱 전략:

  1. 모바일 프록시 사용 — 가장 낮은 차단 위험을 제공합니다. 하나의 모바일 IP는 하루에 100-200개의 프로필 조회에 사용될 수 있습니다.
  2. headless 브라우저 필수 — Puppeteer 또는 Playwright를 사용하여 실제 브라우저의 지문을 설정합니다 (화면 해상도, WebGL, Canvas).
  3. 느린 파싱 속도 — 하나의 계정으로 시간당 20-30개의 프로필 이상 조회하지 않습니다. 조회 간 10-20초의 지연을 추가합니다.
  4. 실제 행동 시뮬레이션 — 페이지 스크롤, 임의 클릭, 프로필 섹션 간 이동.
  5. 계정 준비 — 새로운 LinkedIn 계정은 즉시 파싱에 사용할 수 없습니다. 일반 사용자 활동을 1-2주 동안 시뮬레이션해야 합니다.
  6. 계정 회전 — 여러 계정을 사용하여 부하를 분산합니다.

LinkedIn 파싱은 모든 채용 공고 사이트 중 가장 복잡한 작업입니다. 이 플랫폼에서 데이터가 필요하다면 공식 Sales Navigator API 또는 데이터를 합법적으로 제공하는 제3자 서비스를 사용하는 것을 고려하세요.

해외 채용 공고 사이트: Indeed, Glassdoor, Monster

해외 플랫폼은 일반적으로 러시아 사이트보다 더 강력한 보호를 가지고 있습니다 (hh.ru 제외). 주요 특징은 다음과 같습니다:

  • Indeed — Cloudflare와 JavaScript 검사를 사용합니다. 파싱하는 국가의 주거용/모바일 프록시와 함께 headless 브라우저가 필요합니다.
  • Glassdoor — 대부분의 데이터 조회를 위해 인증이 필요합니다. 데이터 센터 IP를 적극적으로 차단합니다. 주거용 프록시와 느린 파싱 속도(8-12초 지연)를 사용하세요.
  • Monster — 파트너를 위한 API가 있지만 HTML 파싱을 위해서는 필요한 국가에 대한 지리적 연결이 있는 주거용 프록시가 필요합니다.

모든 해외 플랫폼에서 프록시의 지리적 연결성이 매우 중요합니다. 미국의 채용 공고를 파싱하는 경우 미국 주거용 IP를 사용하세요. 다른 국가의 IP에서 요청하면 의심을 받을 수 있으며 차단될 수 있습니다.

IP 회전 및 요청 간 지연 설정

프록시 회전을 올바르게 설정하는 것은 차단 없이 안정적인 파싱의 핵심입니다. 두 가지 주요 전략을 살펴보겠습니다: 요청마다 회전 및 시간에 따른 회전.

요청마다 회전 (Rotating Proxies)

이 접근 방식에서는 각 HTTP 요청이 새로운 IP 주소로 전송됩니다. 이는 가장 안전한 방법이지만 제한이 있습니다:

장점:

  • 하나의 IP의 활동을 추적할 수 없습니다.
  • 단위 시간당 더 많은 요청을 할 수 있습니다.
  • 각 IP에 대한 제한을 추적할 필요가 없습니다.

단점:

  • 세션을 저장할 수 없습니다 (IP 변경 시 쿠키가 사라집니다).
  • 인증이 필요한 파싱에는 적합하지 않습니다.
  • 일부 사이트는 IP가 너무 자주 변경되면 요청을 차단합니다.

요청마다 회전은 인증 없이 hh.ru 및 Superjob의 공개 페이지 파싱에 적합합니다. 이는 프록시 공급자의 매개변수를 통해 설정됩니다 (일반적으로 자동 회전을 위한 특별한 엔드포인트입니다).

시간에 따른 회전 (Sticky Sessions)

이 접근 방식에서는 하나의 IP가 특정 시간(5-30분) 동안 사용되며, 그 후 자동으로 변경됩니다. 이는 대부분의 채용 공고 사이트 파싱 작업에 최적의 옵션입니다.

권장 회전 간격:

사이트 회전 간격 IP당 최대 요청 수 요청 간 지연
hh.ru 5-10분 60-80 4-8초
Superjob 10-15분 50-70 3-5초
LinkedIn 30-60분 20-40 10-20초
Indeed 10-20분 40-60 5-10초
Glassdoor 15-30분 30-50 8-12초

임의의 지연 설정

요청 간 고정 지연(예: 정확히 5초)은 보호 시스템에 의심스럽게 보입니다. 실제 사용자는 그렇게 정확하게 행동할 수 없습니다. 항상 범위 내에서 임의의 지연을 사용하세요.

임의 지연 구현 예시:

// Python
import time
import random

# 4초에서 8초 사이의 지연
delay = random.uniform(4, 8)
time.sleep(delay)

# 더 복잡한 로직: 때때로 긴 지연을 둡니다.
if random.random() < 0.1:  # 10% 확률
    time.sleep(random.uniform(15, 30))  # 사용자가 방해받는 것처럼 시뮬레이션
else:
    time.sleep(random.uniform(4, 8))
// JavaScript / Node.js
const sleep = (min, max) => {
  const delay = Math.random() * (max - min) + min;
  return new Promise(resolve => setTimeout(resolve, delay * 1000));
};

// 사용 예
await sleep(4, 8);  // 4-8초 지연

// 긴 지연 확률
if (Math.random() < 0.1) {
  await sleep(15, 30);  // 긴 지연의 10% 확률
} else {
  await sleep(4, 8);
}

임의의 긴 지연(15-30초)을 5-10% 확률로 추가하면 파서의 행동이 실제 사용자와 더욱 유사해져, 전화 통화나 다른 작업으로 방해받을 수 있습니다.

CAPTCHA 및 기타 차단 처리

프록시 및 지연을 올바르게 설정하더라도 CAPTCHA 또는 기타 차단에 직면할 수 있습니다. 이러한 상황에 올바르게 대응하는 방법을 살펴보겠습니다.

채용 공고 사이트의 차단 유형

1. HTTP 429 Too Many Requests — 가장 일반적인 차단 유형입니다. 사이트는 명확하게 요청 한도를 초과했음을 알립니다. 일반적으로 응답 헤더에는 Retry-After가 포함되어 있으며, 이는 몇 초 후에 요청을 반복할 수 있는지를 나타냅니다.

처리 방법: 즉시 프록시를 변경하고 현재 IP를 Retry-After에 명시된 시간 동안 블랙리스트에 추가합니다 (일반적으로 1-6시간). Retry-After가 없으면 IP를 2시간 동안 블랙리스트에 추가합니다.

2. HTTP 403 Forbidden — IP가 서버 수준에서 차단되었습니다. 이는 몇 시간에서 하루까지 지속될 수 있는 더 심각한 차단입니다.

처리 방법: 프록시를 변경하고 IP를 장기 블랙리스트에 추가합니다 (24시간). 로그를 분석하세요: 너무 공격적으로 파싱하고 있거나 주거용 IP가 필요한 곳에서 데이터 센터 IP를 사용하고 있을 수 있습니다.

3. CAPTCHA — 사이트가 "나는 로봇이 아닙니다" 검사를 표시합니다. 이는 귀하의 행동이 의심스럽게 보였지만 IP는 아직 완전히 차단되지 않았음을 의미합니다.

처리 방법: 세 가지 옵션이 있습니다:

  • 프록시 변경 — 가장 간단한 방법입니다. 현재 IP는 6-12시간 동안 블랙리스트에 추가됩니다.
  • 자동 CAPTCHA 해결 — 2Captcha, Anti-Captcha, CapSolver와 같은 서비스를 사용합니다. 이들은 1000개의 해결에 대해 $1-3의 비용이 듭니다.
  • 수동 해결 — 파싱이 시간적으로 중요하지 않은 경우, CAPTCHA를 수동으로 해결하기 위해 운영자에게 전송할 수 있습니다.

4. Cloudflare Challenge — 브라우저에서 코드를 실행해야 하는 JavaScript 검사입니다. 일반 HTTP 라이브러리는 이 검사를 통과하지 못합니다.

처리 방법: headless 브라우저(Puppeteer, Playwright, Selenium)를 사용하여 실제 지문을 설정합니다. puppeteer-extra-plugin-stealth와 같은 라이브러리는 headless 모드 감지를 우회하는 데 도움이 됩니다.

CAPTCHA 해결 서비스 통합

CAPTCHA를 자동으로 해결하기로 결정한 경우, 인기 있는 서비스 2Captcha와의 통합 예시는 다음과 같습니다:

// Python 2captcha-python 라이브러리 사용
from twocaptcha import TwoCaptcha
import requests

solver = TwoCaptcha('YOUR_API_KEY')

try:
    # reCAPTCHA v2 해결
    result = solver.recaptcha(
        sitekey='6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
        url='https://hh.ru/search/vacancy',
        proxy={
            'type': 'HTTPS',
            'uri': 'login:password@ip:port'
        }
    )
    
    # 해결 토큰 받기
    captcha_token = result['code']
    
    # 토큰과 함께 요청 전송
    response = requests.post(
        'https://hh.ru/search/vacancy',
        data={
            'g-recaptcha-response': captcha_token,
            # 기타 폼 매개변수
        },
        proxies={
            'http': 'http://login:password@ip:port',
            'https': 'http://login:password@ip:port'
        }
    )
    
except Exception as e:
    print(f'CAPTCHA 해결 오류: {e}')

CAPTCHA 하나를 해결하는 데 10-30초가 소요되며 약 $0.001-0.003의 비용이 듭니다. 대규모 파싱의 경우 비용이 많이 들 수 있으므로 CAPTCHA가 가능한 한 적게 발생하도록 파싱을 설정하는 것이 좋습니다.

모니터링 및 알림 시스템

파서의 안정적인 작동을 위해 차단 모니터링 및 자동 알림을 설정하는 것이 중요합니다:

모니터링할 항목:

  • 성공적인 요청 비율 — 90% 이하로 떨어지면 프록시 및 설정을 확인해야 합니다.
  • 시간당 CAPTCHA 수 — 5-10개 이상이면 너무 공격적으로 파싱하고 있습니다.
  • 프록시 응답 평균 속도 — 급격히 증가하면 프록시가 과부하 상태일 수 있습니다.
  • 429/403 오류 수 — 프록시 품질 및 설정의 정확성을 나타내는 지표입니다.
  • 차단된 IP 목록 — 동일한 IP가 지속적으로 차단되면 해당 IP를 풀에서 제외하세요.

성공적인 요청 비율이 임계값 이하로 떨어지면 알림(텔레그램, 이메일, 슬랙)을 설정하세요. 이를 통해 문제에 신속하게 대응하고 파싱 시간을 낭비하지 않을 수 있습니다.

인기 파싱 도구에서 프록시 설정

Python(requests, Scrapy), Node.js(axios, Puppeteer) 및 완성된 솔루션에서 채용 공고 사이트 파싱을 위한 프록시 설정 방법을 살펴보겠습니다.

Python: requests 및 Scrapy

Python은 requests, BeautifulSoup 및 Scrapy 라이브러리 덕분에 파싱을 위한 가장 인기 있는 언어입니다.

requests 라이브러리 예시:

import requests
import random
import time

# 프록시 목록 (제공업체에서 받으세요)
PROXIES = [
    'http://user:[email protected]:8080',
    'http://user:[email protected]:8080',
    'http://user:[email protected]:8080'
]

# 회전을 위한 User-Agent 목록
USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
]

def parse_vacancy(url):
    proxy = random.choice(PROXIES)
    user_agent = random.choice(USER_AGENTS)
    
    headers = {
        'User-Agent': user_agent,
        'Accept': 'text/html,application/xhtml+xml',
        'Accept-Language': 'ru-RU,ru;q=0.9,en;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Connection': 'keep-alive'
    }
    
    proxies = {
        'http': proxy,
        'https': proxy
    }
    
    try:
        response = requests.get(
            url,
            headers=headers,
            proxies=proxies,
            timeout=30
        )
        
        if response.status_code == 200:
            return response.text
        elif response.status_code == 429:
            print(f'{proxy}에 대한 속도 제한, 프록시를 변경합니다.')
            # 프록시를 임시로 목록에서 제거합니다.
            return None
        else:
            print(f'오류 {response.status_code}')
            return None
            
    except Exception as e:
        print(f'요청 오류: {e}')
        return None

# 사용 예
for i in range(100):
    html = parse_vacancy('https://hh.ru/vacancy/123456')
    if html:
        # 데이터 처리
        pass
    
    # 임의의 지연
    time.sleep(random.uniform(4, 8))

Scrapy 설정 예시:

# settings.py

# 프록시 지원 활성화
DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
    'scrapy_rotating_proxies.middlewares.RotatingProxyMiddleware': 610,
    'scrapy_rotating_proxies.middlewares.BanDetectionMiddleware': 620,
}

# 프록시 목록
ROTATING_PROXY_LIST = [
    'http://user:[email protected]:8080',
    'http://user:[email protected]:8080',
    'http://user:[email protected]:8080'
]

# 차단 자동 감지
ROTATING_PROXY_BAN_POLICY = 'scrapy_rotating_proxies.policy.BanDetectionPolicy'

# 요청 간 지연
DOWNLOAD_DELAY = 5
RANDOMIZE_DOWNLOAD_DELAY = True  # ±50% 임의 지연

# User-Agent 회전
DOWNLOADER_MIDDLEWARES.update({
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
    'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400,
})

# 최대 동시 요청 수
CONCURRENT_REQUESTS = 4
CONCURRENT_REQUESTS_PER_DOMAIN = 1

Node.js: Puppeteer와 프록시

JavaScript가 있는 사이트(LinkedIn, Indeed)를 파싱하려면 headless 브라우저가 필요합니다. Puppeteer는 Node.js를 위한 가장 인기 있는 솔루션입니다.

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

// headless 브라우저 감지 우회 플러그인
puppeteer.use(StealthPlugin());

async function parseWithProxy() {
  const proxy = 'http://user:[email protected]:8080';
  
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      `--proxy-server=${proxy}`,
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage',
      '--disable-blink-features=AutomationControlled'
    ]
  });
  
  const page = await browser.newPage();
  
  // 실제 User-Agent 설정
  await page.setUserAgent(
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  );
  
  // 페이지 로드 및 데이터 파싱 코드 추가
}

Puppeteer 설정 예시:

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

// headless 브라우저 감지 우회 플러그인
puppeteer.use(StealthPlugin());

async function parseWithProxy() {
  const proxy = 'http://user:[email protected]:8080';
  
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      `--proxy-server=${proxy}`,
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage',
      '--disable-blink-features=AutomationControlled'
    ]
  });
  
  const page = await browser.newPage();
  
  // 실제 User-Agent 설정
  await page.setUserAgent(
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  );
  
  // 페이지 로드 및 데이터 파싱 코드 추가
}
```