5.19 Write to File
이번에는 Python 에서 파일을 열고 파일에 내용을 쓰는 것을 해본다.
기존에 사용했던 indeed 와 wwr 스크랩하는 코드는 잠시 주석처리하고 시작.
open 이라는 빌트인 함수(print, input 과 비슷하다) 를 사용한다.
csv 는 comma-separated-value 라는 파일 포맷이다.
w 는 write 의 약자로 쓰기전용이다. 읽기 전용( read-only ) 도 있다.
from extractors.indeed import extract_indeed_jobs
from extractors.wwr import extract_wwr_jobs
keyword = input('What do you want to search for?')
file = open(f'{keyword}.csv','w')
# 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 을 입력하면
위와 같이 python.csv 파일이 생성된다.
방금 생성한 python.csv를 삭제하고,
이제 파일의 헤더를 작성한다.
csv 파일은 엑셀 파일과 비슷하게 열(column)을 사용한다.
열을 쉼표로 구분해서 적어준다.
회사 직책, 회사 이름, 위치 ,URL 을 입력해준다.
from extractors.indeed import extract_indeed_jobs
from extractors.wwr import extract_wwr_jobs
keyword = input('What do you want to search for?')
file = open(f'{keyword}.csv','w')
file.write('Postition,Company,Location,URL')
file.close()
출력값:
아까와 동일하게 python.csv 를 생성하면 위와 같이 Postion,Company,Location,URL 이 입력된다.
python.csv 파일에서 아래와 같이 입력해본다.
Postition,Company,Location,URL
Developer,LG,Seoul,lglglglg
이건 보는것과 마찬가지로 쉼표로 구분된 값이다.
사용자는 쉼표로 구분된 값만 적으면된다.
이제 구인공고 정보를 얻기위해 python.csv 파일을 다시 삭제해준다.
( python.csv 파일이 존재하면 python 입력시 값이 저장되지 않는다. )
이제 기존에 주석처리 했던 웹스크래핑 코드를 주석 해제하고
모든 구인공고 정보를 수집한다.
그리고 csv 파일을 열고,
헤더를 작성한 다음 각 작업의 내용들을 파일 안에 넣는다.
extract_indeed_jobs 와 extract_wwr_jobs 는 2개의 리스트로 나온다.
이 2개의 리스트들을 받은 후 1개로 합쳐서 jobs 변수에 저장했다.
2 extractor 모두 같은 키를 사용해 딕셔너리를 만들고 있다.
( company,location,position,link )
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
file = open(f'{keyword}.csv','w')
file.write('Postition,Company,Location,URL\n')
for job in jobs:
file.write(f"{job['position']},{job['company']},{job['location']},{job['link']}\n")
file.close()
만약 아래와 같은 에러가 발생한다면 코드를 추가해준다.
( 한글이 깨지는 경우 )
< encoding = 'utf-8' 추가 코드 >
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
file = open(f'{keyword}.csv','w',encoding='utf-8')
file.write('Postition,Company,Location,URL\n')
for job in jobs:
file.write(f"{job['position']},{job['company']},{job['location']},{job['link']}\n")
file.close()
출력값:
이제 저장된 python.csv 파일을 열어본다.
근데 또 아래와 같이 한글이 깨져서 열렸다.
encoding = 'utf-8-sig' 코드로 변경해준다.
< encoding = 'utf-8-sig' 추가 코드 >
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
file = open(f'{keyword}.csv','w',encoding='utf-8-sig')
file.write('Postition,Company,Location,URL\n')
for job in jobs:
file.write(f"{job['position']},{job['company']},{job['location']},{job['link']}\n")
file.close()
저장된 python.csv 파일을 열어보면 아래와 같이 구인정보들이 저장되어 있다.
근데 결과를 보다보니 location 과 url 에 엉킨 항목이 있다.
csv 파일은 콤마를 중요하게 여기는데, 위 데이터에는 쉼표( , )가 있어서
가져올 때 엉킬수 있다. ( url 항목에 서울 과 구인공고 url 이 섞여서 저장된다. )
python.csv 파일에서 ctrl + F 로 google을 검색해본다.
위치가 Google 서울인데 가운데 쉼표( , )가 있어서 csv가 헷갈려하는거 같다.
그래서 csv 파일에 저장하기 전에 쉼표를 없애줘야한다.
쉼표는 csv 파일에서 열( coloumn )의 분할을 의미한다.
회사 이름이나 위치 또는 직책과 같이 데이터에 쉼표가 있는 경우에는
csv 파일의 새로운 열을 의미한다.
extractors 폴더의 indeed.py 파일로 들어가서 쉼표를 스페이스 바( 공백 ) 으로 바꿔준다.
extractors 폴더의 wwr.py 파일로 들어가서 extractors 폴더의 indeed.py 파일로 들어가서
replace(","," ") 사용
< indeed.py 파일 >
job_data = {
'link':f'https://kr.indeed.com{link}',
'company': company.string.replace(","," "),
'location': location.string.replace(","," "),
'position': title.replace(","," ")
}
results.append(job_data)
< wwr.py 파일 >
job_data = {
'link': f"https://weworkremotely.com/{link}" ,
'company': company.string.replace(","," "),
'location': region.string.replace(","," "),
'position': title.string.replace(","," ")
}
results.append(job_data)
wwr.py 파일은 원래 'time': kind.stinrg 코드가 중간에 있었는데 일관성을 위해 삭제했다.
다시 main.py 로 돌아와서 실행 후 python 입력 한다.
( 매번 실행 하기 전에는 python.csv 파일 삭제 후 실행 )
csv 파일을 열면 url 에 1열만 있고 깔끔하게 출력되었다.
최종정리
extractors 폴더안에 indeed.py 와 wwr.py 파일이 있고,
2 개 파일 모두 각 웹사이트에서 구인공고를 스크랩하는 extractor 함수가 정의된 파일이다.
indeed.py 를 실행하기 위해 ( selenium 을 활용하기 때문에 )
크롬 버전에 맞는 혹은 비슷한 chromedriver.exe 를 설치해야하며,
main.py 에서 indeed.py 와 wwr.py 파일을 실행시킨다.
최종적으로 csv 파일로 회사이름, 직책, 위치, URL 정보가 저장된다.
최종코드
< 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.replace(","," "),
'location': location.string.replace(","," "),
'position': title.replace(","," ")
}
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.replace(","," "),
'location': region.string.replace(","," "),
'position': title.string.replace(","," ")
}
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
file = open(f'{keyword}.csv','w',encoding='utf-8-sig')
file.write('Postition,Company,Location,URL\n')
for job in jobs:
file.write(f"{job['position']},{job['company']},{job['location']},{job['link']}\n")
file.close()
python 웹 스크래퍼 참고 강의
https://nomadcoders.co/python-for-beginners/lobby
selenium 참고 강의
'Programming > Python 웹 스크래퍼 만들기' 카테고리의 다른 글
Python Flask Render Template (0) | 2022.12.28 |
---|---|
Python Flask Introduction (0) | 2022.12.27 |
Python webscrapper 파일 2개 합치기 (0) | 2022.12.07 |
Python selenium 활용해서 webscrapper 기초 제작 6 (0) | 2022.12.06 |
Python selenium 활용해서 webscrapper 기초 제작 5 (0) | 2022.12.05 |