구직자, 고용주 또는 고용 시장의 동향을 모니터링하는 모든 개인에게 인디드의 채용 공고 목록을 스크랩하는 것은 유용한 정보를 제공할 수 있습니다. 이 튜토리얼에서는 웹 스크래핑용 Playwright와 HTML 콘텐츠 구문 분석용 lxml을 결합하여 채용 공고의 제목, 채용 회사 이름, 위치, 직무 설명, 채용 공고 링크를 포함한 세부 정보를 수집하고, 마지막으로 정보를 CSV 파일에 저장하여 결과를 제시합니다.
스크래핑을 성공적으로 수행하려면 다음 Python 라이브러리를 설치해야 합니다.
브라우저 자동화를 위한 Playwright:
pip install playwright
HTML 구문 분석을 위한 lxml:
pip install lxml
팬더를 사용하여 데이터를 CSV 파일로 저장할 수 있습니다:
pip install pandas
Playwright 브라우저 설치:
Playwright를 설치한 후 이 명령을 실행하여 필요한 브라우저 바이너리를 설치합니다:
playwright install
Playwright를 사용하면 웹 브라우저를 자동화하고 상호 작용할 수 있습니다. 먼저 Chromium 브라우저를 실행하고 웹페이지를 방문하여 콘텐츠를 추출하도록 Playwright를 설정합니다. 여기서 플레이라이트를 통해 프록시를 전달할 수도 있습니다.
왜 프록시를 사용하나요?
웹사이트에는 동일한 IP 주소에서 반복되는 요청을 차단하기 위해 속도 제한 또는 스크래핑 방지 조치가 마련되어 있는 경우가 많습니다. 프록시를 사용하면 가능합니다:
import asyncio
from playwright.async_api import async_playwright
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy = {
'server': '',
'username': '',
'password': ''
}
) # 헤딩 브라우저
page = await browser.new_page()
await page.goto(url)
# 페이지 콘텐츠 추출
content = await page.content()
await browser.close() # 완료되면 브라우저를 닫습니다.
return content
이 코드에서 async_playwright는 헤딩 브라우저를 실행하고 지정된 URL로 이동한 다음 페이지의 콘텐츠를 가져옵니다.
다음으로 페이지 콘텐츠를 구문 분석하여 의미 있는 데이터를 추출합니다. 이 목적을 위해 XPath를 사용하여 HTML 콘텐츠 구문 분석 및 쿼리를 강력하게 지원하기 때문에 lxml이 사용됩니다.
from lxml import html
def parse_job_listings(content):
# HTML 콘텐츠 구문 분석
parser = html.fromstring(content)
# XPath를 사용하여 각 채용 공고 추출
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
jobs_data = []
for element in job_posting[:-1]: # 마지막 요소가 광고이거나 관련성이 없는 경우 건너뛰기
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# 추출된 데이터를 jobs_data 목록에 추가하기
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
이제 브라우저 자동화와 구문 분석 단계를 모두 설정했으므로 이를 결합하여 Indeed 페이지에서 채용 공고를 스크랩해 보겠습니다.
설명:
import pandas as pd
async def scrape_indeed_jobs(url):
# 1단계: Playwright를 사용하여 페이지 콘텐츠 가져오기
content = await get_page_content(url)
# 2단계: HTML을 구문 분석하고 작업 세부 정보 추출하기
jobs_data = parse_job_listings(content)
return jobs_data
# 스크랩할 URL
url = 'https://www.indeed.com/q-usa-jobs.html'
# 데이터 스크랩 및 저장
async def main():
# 지정된 URL에서 작업 데이터 스크랩
jobs = await scrape_indeed_jobs(url)
# 3단계: 판다를 사용하여 데이터를 CSV로 저장하기
df = pd.DataFrame(jobs)
df.to_csv('indeed_jobs.csv', index=False)
print("Data saved to indeed_jobs.csv")
# 주요 기능 실행
asyncio.run(main())
실제로 채용 공고의 페이지 매김을 지원하며, 스크래퍼를 쉽게 확장하여 여러 페이지를 처리할 수 있습니다. 페이지 URL은 새 페이지가 추가될 때마다 10씩 증가하는 쿼리 매개변수 start를 사용하여 조정됩니다.
여러 페이지에서 데이터를 수집하는 스크래퍼의 기능을 향상시키려면 scrape_multiple_pages라는 함수를 구현하면 됩니다. 이 함수는 시작 매개변수를 점진적으로 조정하여 기본 URL을 수정하여 후속 페이지에 액세스할 수 있도록 합니다. 각 페이지를 체계적으로 진행하면 공석과 같이 수집되는 데이터의 범위와 양을 확장하여 보다 포괄적인 데이터 세트를 확보할 수 있습니다.
async def scrape_multiple_pages(base_url, pages=3):
all_jobs = []
for page_num in range(pages):
# 페이지 매김을 위한 URL 업데이트
url = f"{base_url}&start={page_num * 10}"
print(f"Scraping page: {url}")
# 각 페이지에서 작업 데이터 스크랩
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# 모든 작업을 CSV로 저장
df = pd.DataFrame(all_jobs)
df.to_csv('indeed_jobs_all_pages.csv', index=False)
print("Data saved to indeed_jobs_all_pages.csv")
# 여러 페이지의 채용 공고 스크랩
asyncio.run(scrape_multiple_pages('https://www.indeed.com/jobs?q=usa', pages=3))
스크래핑 작업에서 특정 직책이나 키워드를 타겟팅하려면 Indeed에서 사용하는 URL에서 쿼리 검색 매개변수를 구성해야 합니다. 이 사용자 지정을 통해 스크래퍼는 특정 직종이나 분야에 특화된 데이터를 수집할 수 있습니다. 예를 들어 http://www.indeed.com 에서 파이썬 개발자 채용 공고를 검색하는 경우 쿼리 매개변수를 "파이썬+개발자" 또는 관련 키워드를 포함하도록 조정할 수 있습니다.
query = "python+developer"
base_url = f"https://www.indeed.com/jobs?q={query}"
asyncio.run(scrape_multiple_pages(base_url, pages=3))
데이터 수집 필요에 따라 이 매개변수를 수정하면 특정 작업에 스크래핑을 집중하여 데이터 수집 프로세스의 유연성과 효율성을 높일 수 있습니다. 이 접근 방식은 고용 시장의 역동적인 수요에 적응하는 데 특히 유용합니다.
import asyncio
from playwright.async_api import async_playwright
from lxml import html
import pandas as pd
# 1단계: Playwright를 사용하여 페이지 콘텐츠 가져오기
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False
proxy = {
'server': '',
'username': '',
'password': ''
}
) # 헤딩 모드에서 브라우저 실행
page = await browser.new_page()
await page.goto(url, wait_until='networkidle')
# 페이지 콘텐츠 추출
content = await page.content()
await browser.close() # 사용 후 브라우저 닫기
return content
# 2단계: lxml을 사용하여 HTML 콘텐츠 구문 분석하기
def parse_job_listings(content):
# Parse the HTML using lxml
parser = html.fromstring(content)
# XPath를 사용하여 개별 채용 공고 선택
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
# 작업 데이터 추출
jobs_data = []
for element in job_posting[:-1]:
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# 추출된 데이터를 jobs_data 목록에 추가하기
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
# 3단계: 단일 페이지에 대한 Indeed 채용 정보 스크랩하기
async def scrape_indeed_jobs(url):
# Playwright를 사용하여 페이지 콘텐츠 가져오기
content = await get_page_content(url)
# HTML 구문 분석 및 작업 데이터 추출
jobs_data = parse_job_listings(content)
return jobs_data
# 4단계: 페이지 매김 처리 및 여러 페이지 스크랩하기
async def scrape_multiple_pages(base_url, query, pages=3):
all_jobs = []
for page_num in range(pages):
# 페이지 매김을 처리하도록 URL을 업데이트하고 검색 쿼리를 추가합니다.
url = f"{base_url}?q={query}&start={page_num * 10}"
print(f"Scraping page: {url}")
# 현재 페이지의 스크랩 작업
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# 모든 작업을 CSV 파일로 저장
df = pd.DataFrame(all_jobs)
df.to_csv(f'indeed_jobs_{query}.csv', index=False)
print(f"Data saved to indeed_jobs_{query}.csv")
# 동적 쿼리 입력으로 스크레이퍼를 실행하는 기능
async def run_scraper():
# 5단계: 사용자에게 입력 쿼리와 스크랩할 페이지 수를 요청합니다.
query = input("Enter the job title or keywords to search (e.g., python+developer): ")
pages = int(input("Enter the number of pages to scrape: "))
# 쿼리를 기반으로 여러 페이지에 걸쳐 작업을 스크랩하세요.
base_url = 'https://www.indeed.com/jobs'
await scrape_multiple_pages(base_url, query, pages)
# 스크레이퍼 실행
asyncio.run(run_scraper())
원활한 스크래핑 프로세스를 보장하고 차단 및 캡차 표시의 위험을 줄이려면 올바른 프록시 서버를 선택하는 것이 중요합니다. 스크래핑에 가장 적합한 옵션은 빠른 속도와 연결 안정성을 제공할 뿐만 아니라 신뢰도가 높아 플랫폼에서 차단되는 경우가 거의 없는 ISP 프록시입니다. 이러한 유형의 프록시는 정적이므로 대규모 스크래핑의 경우 ISP 프록시 풀을 생성하고 정기적으로 변경되도록 IP 로테이션을 구성해야 합니다. 다른 옵션으로는 동적이며 다른 유형의 프록시 서버에 비해 지리적 범위가 가장 넓은 주거용 프록시가 있습니다.
댓글: 0