JobSpy를 이용한 LinkedIn 데이터 스크래핑: 프록시 풀 활용 심층 가이드

JobSpy는 LinkedIn, Indeed, Glassdoor 등 다양한 웹사이트에서 채용 정보를 수집하는 데 유용한 라이브러리입니다. 특히 LinkedIn에서 대량의 데이터를 스크래핑할 경우, IP 주소 제한은 흔히 발생하는 문제입니다. 본 글에서는 JobSpy의 프록시 풀 기능을 활용하여 LinkedIn의 제한을 우회하고 효율적이며 안정적인 데이터 수집을 수행하는 방법에 대해 설명합니다.

LinkedIn 프록시 풀 사용 이유

LinkedIn은 세계 최대 규모의 직업 관련 소셜 네트워크 서비스로서, 봇이나 자동화된 스크립트의 활동을 감지하고 차단하기 위한 강력한 보안 조치를 적용하고 있습니다. 동일한 IP 주소에서 짧은 시간 내에 과도한 요청이 발생하면, 해당 IP는 일시적으로 차단될 수 있어 데이터 스크래핑 작업이 중단될 위험이 있습니다. 프록시 풀은 여러 IP 주소를 번갈아 사용하여 요청을 분산시키므로, IP 차단의 위험을 현저히 낮추고 안정적인 데이터 수집을 가능하게 합니다.

JobSpy의 LinkedIn 스크래퍼는 jobspy/linkedin/__init__.py 파일에서 초기화 시 프록시 설정을 지원합니다:


def __init__(self, proxies: list[str] | str | None = None, ca_cert: str | None = None, user_agent: str | None = None)

이는 프록시 풀을 설정하기 위한 기본적인 구조를 제공합니다.

프록시 풀 구축 방법

1. 프록시 리소스 확보

먼저, 사용 가능한 프록시 IP 주소 목록을 준비해야 합니다. 프록시 소스는 다음과 같습니다:

  • 유료 프록시 서비스 제공업체
  • 무료 프록시 웹사이트 (안정성이 낮아 운영 환경에는 부적합)
  • 자체 구축 프록시 서버

프록시는 다음과 같은 형식으로 제공될 수 있습니다:

  • http://ip:port
  • https://ip:port
  • socks5://ip:port
  • ip:port (JobSpy가 자동으로 HTTP 프로토콜을 추가)

2. 프록시 풀 설정

JobSpy의 프록시 풀 기능은 주로 jobspy/util.py 파일의 RotatingProxySession 클래스를 통해 구현됩니다. 이 클래스는 제공된 프록시 목록을 순환하며 요청 IP를 자동으로 변경합니다.

사용 방법은 간단합니다. LinkedIn 스크래퍼 인스턴스를 생성할 때 프록시 목록을 전달하면 됩니다:


from jobspy import scrape_jobs
from jobspy.linkedin import LinkedInScraper

# 사용할 프록시 IP 목록
proxy_list = [
    "http://your_proxy_ip1:port",
    "socks5://your_proxy_ip2:port",
    "your_proxy_ip3:port"  # JobSpy가 자동으로 http 프로토콜을 추가합니다.
]

# 프록시 풀을 포함한 LinkedIn 스크래퍼 생성
linkedin_scraper = LinkedInScraper(proxies=proxy_list)

# 데이터 스크래핑 시작
scraped_data = linkedin_scraper.scrape(
    query="data scientist",
    location="New York, NY",
    results_wanted=150
)

3. 프록시 풀 작동 확인

프록시 풀이 제대로 작동하는지 확인하려면, 상세 로깅을 활성화하여 프록시 전환 과정을 살펴보세요. jobspy/util.py 파일에서 로깅 수준을 설정할 수 있습니다:


from jobspy.util import set_logger_level

# 로깅 수준을 INFO로 설정하여 프록시 전환 정보 확인
set_logger_level(verbose=2)

스크립트 실행 시, 콘솔에 다음과 유사한 로그 메시지가 출력되는지 확인하면 프록시가 자동으로 전환되고 있음을 알 수 있습니다:


2023-10-26 11:00:00 - INFO - JobSpy:linkedin - Using proxy: http://your_proxy_ip1:port
2023-10-26 11:00:02 - INFO - JobSpy:linkedin - Using proxy: socks5://your_proxy_ip2:port
2023-10-26 11:00:04 - INFO - JobSpy:linkedin - Using proxy: http://your_proxy_ip3:port

고급 프록시 풀 최적화 전략

1. 비활성 프록시 처리

실제 사용 시 일부 프록시가 작동하지 않을 수 있습니다. JobSpy는 자동으로 비활성 프록시를 감지하고 건너뜁니다. 관련 오류 메시지는 로그에서 확인할 수 있습니다:


2023-10-26 11:00:06 - ERROR - JobSpy:linkedin - LinkedIn: Bad proxy

프록시 풀의 안정성을 높이기 위해, 주기적으로 프록시 목록을 갱신하고 비활성 프록시는 제거하는 것이 좋습니다.

2. 요청 빈도 제어

프록시 풀을 사용하더라도 과도하게 빠른 요청은 LinkedIn에 의해 감지될 수 있습니다. 요청 간 지연 시간을 설정하여 위험을 줄일 수 있습니다:


scraped_data = linkedin_scraper.scrape(
    query="data scientist",
    location="New York, NY",
    results_wanted=150,
    delay=3  # 각 요청 간 지연 시간 (초)
)

3. 사용자 에이전트(User-Agent)와 함께 사용

IP 주소 외에도 사용자 에이전트는 웹사이트가 스크래핑 시도를 식별하는 중요한 요소입니다. 다양한 사용자 에이전트를 함께 사용하면 익명성을 더욱 높일 수 있습니다:


from jobspy.linkedin import LinkedInScraper
from jobspy.util import set_logger_level
import random

# 로깅 설정
set_logger_level(verbose=2)

# 사용할 프록시 IP 목록
proxy_list = [
    "http://proxy_ip_a:port",
    "socks5://proxy_ip_b:port",
    "proxy_ip_c:port"
]

# 사용자 에이전트 목록
user_agents_pool = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15",
    # ... 추가 사용자 에이전트 ...
]

# 무작위로 사용자 에이전트 선택
selected_user_agent = random.choice(user_agents_pool)

# 스크래퍼 인스턴스 생성
linkedin_scraper = LinkedInScraper(
    proxies=proxy_list,
    user_agent=selected_user_agent
)

# 데이터 스크래핑
scraped_data = linkedin_scraper.scrape(
    query="software engineer",
    location="San Francisco, CA",
    results_wanted=100,
    delay=2
)

# 결과 처리 (예: CSV로 저장)
print(f"총 {len(scraped_data)}개의 채용 정보를 수집했습니다.")
scraped_data.to_csv("linkedin_jobs_data.csv", index=False)

종합 예제 코드

다음은 프록시 풀을 사용하여 LinkedIn 채용 정보를 스크래핑하는 전체 예제 코드입니다:


from jobspy.linkedin import LinkedInScraper
from jobspy.util import set_logger_level
import random

# 상세 로깅 활성화
set_logger_level(verbose=2)

# 사용할 프록시 IP 목록
proxy_server_list = [
    "http://192.168.1.100:8888",
    "socks5://10.0.0.5:1080",
    "172.16.0.1:8080",
    # ... 더 많은 프록시 추가 ...
]

# 사용자 에이전트 목록
user_agent_list = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
]

# 스크래퍼 인스턴스 생성 (프록시 및 무작위 사용자 에이전트 적용)
scraper_instance = LinkedInScraper(
    proxies=proxy_server_list,
    user_agent=random.choice(user_agent_list)
)

# 채용 정보 스크래핑
jobs_data = scraper_instance.scrape(
    query="data analyst",
    location="Chicago, IL",
    results_wanted=200,
    delay=4  # 4초 지연 설정
)

# 결과 저장
print(f"총 {len(jobs_data)}개의 채용 정보를 성공적으로 수집했습니다.")
jobs_data.to_csv("chicago_data_analyst_jobs.csv", index=False)

결론

프록시 풀을 효과적으로 구성하면 JobSpy를 사용하여 LinkedIn에서 데이터를 수집하는 효율성과 안정성을 크게 향상시킬 수 있습니다. 핵심 사항은 다음과 같습니다:

  1. 고품질의 프록시 리소스를 확보해야 합니다.
  2. jobspy/util.py에 있는 프록시 순환 기능을 활용합니다.
  3. 요청 지연 시간 및 사용자 에이전트 순환을 함께 사용합니다.
  4. 프록시 풀을 정기적으로 업데이트하고 관리합니다.

이러한 기법들을 통해 JobSpy의 잠재력을 최대한 활용하여 LinkedIn 채용 정보 수집 작업을 성공적으로 완료하시기를 바랍니다. 사용 중 문제가 발생하면 프로젝트 공식 문서를 참조하거나 이슈를 제출하여 도움을 요청할 수 있습니다.

JobSpy를 시작하려면 먼저 저장소를 복제하세요:


git clone https://gitcode.com/gh_mirrors/jo/JobSpy

태그: LinkedIn 스크래핑 python 프록시 데이터 수집

10월 4일 22:36에 게시됨