indeed 홈페이지 스크래퍼 만들기
indeed 홈페이지 상에서 봇이 크롤링하면 막아뒀기 때문에(403 error) 읽어올 수가 없다.
Selenium 을 사용한 우회
봇이라서 크롤링을 막아뒀다면 봇이 아닌 브라우저라고 우회하여 읽어오게 해준다. 이를 위한 Selenium 을 사용해본다
브라우저의 자동화를 가능하게 해준다.
pip install selenium
pip install webdriver_manager
드라이버와 셀레니움을 설치해준다.
강의의 덧글을 참고하여 사용법을 알아 보았다... 나는 정상 작동 됐고
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
브라우저가 꺼지는 걸 방지해주기 위한 옵션도 추가해주었다.
options = Options()
options.add_experimental_option('detach', True) # 브라우저 꺼짐 방지
browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()),
options=options)
base_url = f'https://kr.indeed.com/jobs?q={keyword}'
browser.get(base_url)
이렇게 셀레니움과 크롬을 사용하여 자동화되는 브라우저를 실행시키고 그 브라우저 상에서 get 메서드로 이동해준다.
스크래핑 해주기
혼자 HTML 구조를 보며 작성해보았다.
results = []
soup = BeautifulSoup(browser.page_source, 'html.parser')
jobs = soup.find_all('ul', class_='jobsearch-ResultsList')
for job in jobs:
contents = job.find_all('td', class_='resultContent')
for content in contents:
infos = content.find_all('span')
anchor = content.find('a')
link = anchor['href']
title = infos[0]
company = infos[1]
job_info = {
'title': title.string,
'company': company.string,
'link': f"https://kr.indeed.com/viewjob?{link}",
}
print(job_info)
results.append(job_info)
print('///////////')
None
무언가 없을 때 사용하는 자료형
이건 강의 내용대로 스크래퍼를 작성해준 것
.select_one() 은 CSS Selector 를 사용하여 DOM에 접근하여 크롤링할 수 있게 해준다.
def extract_indeed_jobs(keyword):
options = Options()
options.add_experimental_option('detach', True) # 브라우저 꺼짐 방지
browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()),
options=options)
base_url = f'https://kr.indeed.com/jobs?q={keyword}'
browser.get(base_url)
soup = BeautifulSoup(browser.page_source, 'html.parser')
job_list = soup.find('ul', class_='jobsearch-ResultsList')
jobs = job_list.find_all('li', recursive=False)
results = []
for job in jobs:
zone = job.find('div', class_='mosaic-zone')
if zone == None:
anchor = job.select_one('h2 a')
link = anchor['href']
title = anchor['aria-label']
company = job.find('span', class_='companyName')
location = job.find('div', class_='companyLocation')
job_data = {
'link': f"https://kr.indeed.com/viewjob?{link}",
'company': company.string,
'location': location.string,
'position': title,
}
results.append(job_data)
for result in results:
print(result)
print('/////')
return results
extract_indeed_jobs('python')
페이지별로 스크래핑 하기
pagination 을 보면
총 5개의 페이지와 > 다음 버튼이 존재
페이지를 이동하여 스크래핑을 해야하는데 저 페이지 범위 내로 스크래핑 하도록 하기 위해 일단 pagination 정보를 가져와준다.
def get_page_count(keyword):
options = Options()
options.add_experimental_option('detach', True) # 브라우저 꺼짐 방지
browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()),
options=options)
base_url = f'https://kr.indeed.com/jobs?q={keyword}'
browser.get(base_url)
soup = BeautifulSoup(browser.page_source, 'html.parser')
paginations = soup.find('nav', attrs={'aria-label': 'pagination'})
if paginations == None:
return 1
pages = paginations.select('div a')
count = len(pages)
if count >= total_pages:
return total_pages
else:
return count
위의 조건문을 살펴보자면 pagination 이 None 이란 것은 원하는 nav 태그를 찾지 못했을 경우이므로, 이는 pagination 이 없이 검색 결과가 1페이지로 이루어져 있다는 의미이다.
그다음 select 로 CSS 선택자를 사용하여 안의 div a 를 찾아준다. 그 개수가 페이지의 개수이므로 페이지의 수가 5보다 크거나 같으면 5개로, 그 이하면 현재 페이지 개수만큼 반환하게 해주는 함수를 작성해준다.
def extract_indeed_jobs(keyword):
results = []
pages = get_page_count(keyword)
for page in range(pages):
options = Options()
options.add_experimental_option('detach', True) # 브라우저 꺼짐 방지
browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()),
options=options)
base_url = f'https://kr.indeed.com/jobs?q={keyword}&start={page * onepage_list_count}'
browser.get(base_url)
soup = BeautifulSoup(browser.page_source, 'html.parser')
job_list = soup.find('ul', class_='jobsearch-ResultsList')
jobs = job_list.find_all('li', recursive=False)
for job in jobs:
zone = job.find('div', class_='mosaic-zone')
if zone == None:
anchor = job.select_one('h2 a')
link = anchor['href']
title = anchor['aria-label']
company = job.find('span', class_='companyName')
location = job.find('div', class_='companyLocation')
job_data = {
'link': f"https://kr.indeed.com/viewjob?{link}",
'company': company.string,
'location': location.string,
'position': title,
}
results.append(job_data)
for result in results:
print(result)
print('/////\n/////')
return results
페이지의 개수를 가져와서 url 부분에 넣어주고, 각 페이지마다 자동화 반복시켜서 스크래핑 시켜주는 함수를 완성했다.
wwr 과 indeed 크롤링 해주기 예시
from extractors.wwr import extract_wwr_jobs
from extractors.indeed import extract_indeed_jobs
keyword = input('What do you want to search for?')
indeed = extract_indeed_jobs(keyword)
wwr = extract_wwr_jobs(keyword)
jobs = indeed + wwr # list 끼리 합치기
for job in jobs:
print(job)
print('////////////\n////////////')
정상적으로 크롤링 해왔음을 알 수 있다!
'Web Study > 노마드코더' 카테고리의 다른 글
노마드코더 python 웹스크래퍼 만들기 - 2 (0) | 2023.06.15 |
---|---|
노마드코더 python 웹 스크래퍼 만들기 - 1 (0) | 2023.06.14 |
노마드코더 JS로 그림 앱 만들기 - 마지막 (2) | 2023.06.10 |
노마드코더 JS로 그림 앱 만들기 - 2 (0) | 2023.06.09 |
노마드코더 JS로 그림 앱 만들기 - 1 (0) | 2023.06.08 |