5.18 Recap
이전 게시물에서 extractors 폴더안에 wwr.py 와 indeed.py 파일을 만들어서
각 웹사이트에 맞는 웹스크래퍼 코드를 작성해서 저장했다.
이번 게시물은 사용자에게 입력받는걸 해본다.
사용자는 keyword 를 입력하고,
검색한 결과를 내가 만든 2개의 함수를 모두 호출해서 사용자에게 반환한다.
먼저 indeed로 부터 extractors 를 가져온다.
아래의 코드는 indeed 와 weworkremotely 웹사이트에서 구인공고를
스크래핑하는 코드를 불러오는 작업이다.
두 함수는 리스트에 저장되기 때문에 아래처럼 사용이 가능하다.
from extractors.indeed import extract_indeed_jobs
from extractors.wwr import extract_wwr_jobs
keyword = input('What do you want to search for?')
indeed = extract_indeed_jobs(keyword)
wwr = extract_wwr_jobs(keyword)
jobs = indeed + wwr
for job in jobs:
print(job)
print('/////\n/////')
출력값:
what do you want to search for? 라는 문구가 나오면 python 을 입력하고 엔터를 누른다.
indeed 와 weworkremotely 웹사이트의 구인공고를 스크래핑한 결과가 출력된다.
지금까지 했던걸 복습해보면,
extractors 폴더안의 indeed.py 파일의 코드에
def get_page_count 라는 함수를 만들어서
키워드의 첫 번째 검색 페이지를 요청하는 기능을 만들었다.
def get_page_count(keyword):
options = Options()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
browser = webdriver.Chrome(options=options)
base_url = 'https://kr.indeed.com/jobs?q='
browser.get(f'{base_url}{keyword}')
soup = BeautifulSoup(browser.page_source,'html.parser')
search_count = soup.find('div',class_='jobsearch-JobCountAndSortPane-jobCount')
if search_count == None:
print('검색 결과 없음')
else:
search_count2 = search_count.find('span')
print(search_count2.string)
beautifulsoup를 이용해서 class 이름이 jobsearch-JobCountAndSortPane-jobCount 인 div를 찾아서
search_count 라는 변수에 저장했다.
→ 채용공고가 총 몇 개인지 알려주는 코드
if search_count == None: → 검색결과가 없으면, '검색 결과 없음 출력'
( 검색 결과가 없는 경우 span 태그가 없고 jobsearch-jobcount~ 클래스도 없다. )
else: → search_count변수에서 span 을 찾아서 search_count2 라는 변수에 저장하고 출력.
( 검색결과 몇개의 채용공고가 있는지 span 태그에 나와있다. )
다음은 페이지 개수를 count 해주는 코드이다.
pagination = soup.find('nav',{'aria-label':'pagination'})
pages = pagination.select('div a')
count = len(pages)+1 # 현재 페이지에는 a 태그가 없어서 개수를 1개 추가해준다.
for page in pages:
if page['aria-label'] == "Previous Page":
count -= 1 # 이전 페이지가 존재한다면 a 태그를 빼준다.
if page['aria-label'] == "Next Page":
count -= 1 # 다음 페이지가 존재한다면 a 태그를 빼준다.
if count >= 5:
return 5
else:
return count
beautifulsoup를 이용해서 aira-label이 pagination인 nav를 찾아서 pagination 변수에 저장.
pagination 에서 div 를 선택한다음, 안으로 들어가서 a 를 찾아서 pages 변수에 저장.
페이지 a태그와 이전페이지,다음페이지 a태그의 존재유무에 따라 페이지 수를 count 해준다.
(자세한 설명은 여기를 참고)
그리고 이 get_page_count 함수는 extract_indeed_jobs 함수에 사용되고 있다.
키워드를 입력하면 그에 맞게 스크랩할 페이지 개수를 count 해주고,
페이지수는 1,2,3,4,5 까지 count 하며 5가 최대이다.
사용자가 찾은 페이지 수만큼 코드들을 실행시키기 위해 range를 사용해서 범위를 지정해준다.
기존에는 for문 사용해서 5번 반복해줬지만,
for x in [1,2,3,4,5]:
print(x)
range 를 사용하면 간단하게 반복할 수 있다.
( range는 리스트 같은 걸 즉석으로 만들 수 있게 해준다. )
( range는 내가 원하는 만큼의 리스트를 만들어주는 일종의 단축키 이다. )
for i in range(5):
print(i)
출력값:
0
1
2
3
4
extract_indeed_jobs 함수로 키워드에 맞는 채용공고 정보들을 검색해서 스크랩해준다.
def extract_indeed_jobs(keyword):
options = Options()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
browser = webdriver.Chrome(options=options)
pages = get_page_count(keyword)
print("Found", pages, "pages")
results = []
for page in range(pages):
base_url = 'https://kr.indeed.com/jobs'
final_url = f'{base_url}?q={keyword}&start={page*10}'
print('Requesting', final_url)
browser.get(final_url)
전체적으로 보면 indeed 웹사이트에 맞게 페이지를 개수를 count 해주는 함수를 제작하고,
그에 맞게 채용공고 정보들을 스크랩하는 함수를 제작해서 같이 사용한다.
weworkremotely 웹사이트에는 채용공고 정보들은 스크랩하는 함수만 제작해서 사용하며,
이 2개의 웹사이트의 구인공고들을 합쳐서 result 리스트로 출력하는 것이
main.py 파일에서 작성한 코드이다.
indeed.py → 페이지 개수 count , indeed 웹사이트 채용공고 스크랩.
wwr.py → weworkremotely 웹사이트 채용공고 스크랩.
main.py → indeed.py 와 wwr.py 파일의 스크랩 결과를 합쳐주는 파일.
chromedriver.exe → indeed 스크래핑을 위한 selenium 작동을 위한 파일.
extractors 폴더안에 indeed.py 와 wwr.py 파일이 있어야 하며,
위 두 파일을 합쳐서 출력해주는 main.py 파일,
selenium 작동을 위한 chromedriver.exe 파일이 있어야 한다.
< indeed.py >
from requests import get
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def get_page_count(keyword):
options = Options()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
browser = webdriver.Chrome(options=options)
base_url = 'https://kr.indeed.com/jobs?q='
browser.get(f'{base_url}{keyword}')
soup = BeautifulSoup(browser.page_source,'html.parser')
search_count = soup.find('div',class_='jobsearch-JobCountAndSortPane-jobCount')
if search_count == None:
print('검색 결과 없음')
else:
search_count2 = search_count.find('span')
print(search_count2.string)
pagination = soup.find('nav',{'aria-label':'pagination'})
pages = pagination.select('div a')
count = len(pages)+1
for page in pages:
if page['aria-label'] == "Previous Page":
count = count - 1
if page['aria-label'] == "Next Page":
count = count - 1
if count >= 5:
return 5
else:
return count
def extract_indeed_jobs(keyword):
options = Options()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
browser = webdriver.Chrome(options=options)
pages = get_page_count(keyword)
print("Found", pages, "pages")
results = []
for page in range(pages):
base_url = 'https://kr.indeed.com/jobs'
final_url = f'{base_url}?q={keyword}&start={page*10}'
print('Requesting', final_url)
browser.get(final_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')
title = anchor['aria-label']
link = anchor['href']
company = job.find('span',class_='companyName')
location = job.find('div',class_='companyLocation')
job_data = {
'link':f'https://kr.indeed.com{link}',
'company': company.string,
'location': location.string,
'position': title
}
results.append(job_data)
return results
< wwr.py >
from requests import get
from bs4 import BeautifulSoup
def extract_wwr_jobs(keyword):
base_url = "https://weworkremotely.com/remote-jobs/search?utf8=%E2%9C%93&term="
response = get(f'{base_url}{keyword}')
if response.status_code != 200:
print("Can't request website")
else:
results =[]
soup = BeautifulSoup(response.text,'html.parser')
jobs = soup.find_all('section', class_="jobs")
for job_section in jobs:
job_posts = job_section.find_all('li')
job_posts.pop(-1)
for post in job_posts:
anchors = post.find_all('a')
anchor = anchors[1]
link = anchor['href']
company, kind, region = anchor.find_all('span',class_='company')
title = anchor.find('span', class_='title')
job_data = {
'link': f"https://weworkremotely.com/{link}" ,
'company': company.string,
'time': kind.string,
'location': region.string,
'position': title.string
}
results.append(job_data)
return results
< main.py >
from extractors.indeed import extract_indeed_jobs
from extractors.wwr import extract_wwr_jobs
keyword = input('What do you want to search for?')
indeed = extract_indeed_jobs(keyword)
wwr = extract_wwr_jobs(keyword)
jobs = indeed + wwr
for job in jobs:
print(job)
print('/////\n/////')
python 웹 스크래퍼 참고 강의
https://nomadcoders.co/python-for-beginners/lobby
selenium 참고 강의
'Programming > Python 웹 스크래퍼 만들기' 카테고리의 다른 글
Python Flask Introduction (0) | 2022.12.27 |
---|---|
Python webscrapper 완성 (0) | 2022.12.08 |
Python selenium 활용해서 webscrapper 기초 제작 6 (0) | 2022.12.06 |
Python selenium 활용해서 webscrapper 기초 제작 5 (0) | 2022.12.05 |
Python selenium 활용해서 webscrapper 기초 제작 4 (0) | 2022.12.02 |