Stage4 - 엑셀파일 저장하기(심화)

파이참 프로그램에서 키워드를 직접 입력해 뉴스 기사를 검색하고, 기존에 있던 파일을 가지고와서 파일을 저장하는 방법에 대해 공부해봅니다.

키워드를 직접 입력하는 뉴스 기사 수집기 만들기

지난 코드 불러오기(3주차 Stage4.)

3주차 Stage4의 코드(네이버 뉴스 기사 & 언론사 수집)를 불러옵니다. Challenge1에서 작성한 코드를 사용해도 됩니다.

week4_6.py
import requests
from bs4 import BeautifulSoup
# 반복1: 기사번호를 변경시키면서 데이터 수집을 반복하기
# 1 ~ 100까지 10단위로 반복(1, 11, ..., 91)
for n in range(1, 100, 10):
raw = requests.get("https://search.naver.com/search.naver?where=news&query=코알라&start="+str(n),
headers={'User-Agent':'Mozilla/5.0'})
html = BeautifulSoup(raw.text, "html.parser")
articles = html.select("ul.type01 > li")
# 반복2: 기사에 대해서 반복하면 세부 정보 수집하기
# 리스트를 사용한 반복문으로 모든 기사에 대해서 제목/언론사 출력
for ar in articles:
title = ar.select_one("a._sp_each_title").text
source = ar.select_one("span._sp_each_source").text
print(title, source)

입력문(input)을 활용해서 키워드 지정하기

week4_6.py
import requests
from bs4 import BeautifulSoup
# 입력문(input)을 활용해서 검색어를 입력받습니다.
keyword = input("검색어를 입력해주세요: ")
# 반복1: 기사번호를 변경시키면서 데이터 수집을 반복하기
# 1 ~ 100까지 10단위로 반복(1, 11, ..., 91)
for n in range(1, 100, 10):
raw = requests.get("https://search.naver.com/search.naver?where=news&query=코알라&start="+str(n),
headers={'User-Agent':'Mozilla/5.0'})
... 생략

먼저input함수를 활용해서 keyword라는 변수에 검색어를 입력받아 저장합니다.

"https://search.naver.com/search.naver?where=news&query=코알라&start="+str(n)
"https://search.naver.com/search.naver?where=news&query="+keyword+"&start="+str(n)

keyword변수를 활용해서 requests.get()의 안에 들어가는 URL을 바꿔줍니다. query의 요청값에 keyword 변수를 넣어줍니다.(문자열 더하기 활용)

*URL의 요청값 규칙 다시보기

위 코드처럼 검색어를 추가해주면 파이썬 프로그램 안에서 그때 그때 원하는 검색어에 대한 검색결과를 수집할 수 있습니다.

OpenPyXL을 활용해서 엑셀에 데이터 수집결과 저장하기

아래와 같이 코드를 수정해서 데이터 수집결과를 엑셀파일(navernews.xlsx)에 저장합니다.

week4_6.py
import requests
from bs4 import BeautifulSoup
#############################################
# 추가1
# openpyxl 패키지를 불러와서 새 워크북을 만듭니다.
# 헤더 부분을 채워줍니다.
import openpyxl
wb = openpyxl.Workbook()
sheet = wb.active
sheet.append(["제목", "언론사"])
#############################################
keyword = input("검색어를 입력해주세요: ")
# 반복1: 기사번호를 변경시키면서 데이터 수집을 반복하기
# 1 ~ 100까지 10단위로 반복(1, 11, ..., 91)
for n in range(1, 100, 10):
raw = requests.get("https://search.naver.com/search.naver?where=news&query=코알라&start="+str(n),
headers={'User-Agent':'Mozilla/5.0'})
html = BeautifulSoup(raw.text, "html.parser")
articles = html.select("ul.type01 > li")
# 반복2: 기사에 대해서 반복하면 세부 정보 수집하기
# 리스트를 사용한 반복문으로 모든 기사에 대해서 제목/언론사 출력
for ar in articles:
title = ar.select_one("a._sp_each_title").text
source = ar.select_one("span._sp_each_source").text
print(title, source)
#############################################
# 추가2
# 수집한 제목, 언론사를 엑셀 파일에 써줍니다.
sheet.append([title, source])
#############################################
#############################################
# 추가3
# 작성한 워크북(엑셀파일)을 navertv.xlsx로 저장합니다.
wb.save("navertv.xlsx")
#############################################

저장된 엑셀파일에 덮어쓰기

지금까지 완성한 데이터수집기의 경우, 프로그램을 실행할 때마다 엑셀파일을 새로 만들기 때문에 기존에 수집된 데이터는 사라지게 됩니다.

기존 파일 불러오기

OpenPyXL 패키지의 load_workbook()을 활용하면 기존에 저장한 엑셀파일을 가져와서 데이터를 추가할 수 있습니다.

아래와 같이 기존의 openpyxl.Workbook()openpyxl.load_workbook()으로 바꿔줍니다.

wb = openpyxl.Workbook()
wb = openpyxl.load_workbook("navernews.xlsx")

바꾼 후 코드를 실행하면, 기존에 수집한 데이터가 그대로 남아있는 채로 아래에 추가적으로 데이터가 수집됩니다.

에러가 있는 경우 다른 코드 실행하기

error: No such file or directory: 'navertv.xlsx'

load_workbook()을 통해 엑셀파일 불러오기를 하는 경우 불러올 파일이 없다면 에러를 발생시킵니다.

위와 같이 파일이 없는 경우에는 새로운 엑셀파일을 만들고, 파일이 있는 경우에는 엑셀파일을 불러와서 데이터를 수집할 수 있다면 문제없이 파이썬을 통해 데이터를 수집할 수 있습니다.

앞에서 수집한 파일(navertv.xlsx)을 삭제한 후, 아래와 같이 코드를 수정합니다.

import requests
from bs4 import BeautifulSoup
import openpyxl
#############################################
# 수정
# 파일 불러오기를 시도합니다.
try:
# 워크북 불러오기, 현재 활성화된 시트 선택하기
wb = openpyxl.load_workbook("navernews.xlsx")
sheet = wb.active
print("불러오기 완료")
# 파일 불러오기에 실패하면, 새로운 워크북(엑셀파일)을 만듭니다.
except:
# 워크북 새로 만들기, 현재 활성화된 시트 선택하기
# 헤더 행 추가하기
wb = openpyxl.Workbook()
sheet = wb.active
sheet.append(["제목", "언론사"])
print("새로운 파일을 만들었습니다.")
#############################################
keyword = input("검색어를 입력해주세요: ")
# 반복1: 기사번호를 변경시키면서 데이터 수집을 반복하기
# 1 ~ 100까지 10단위로 반복(1, 11, ..., 91)
for n in range(1, 100, 10):
raw = requests.get("https://search.naver.com/search.naver?where=news&query=코알라&start="+str(n),
headers={'User-Agent':'Mozilla/5.0'})
html = BeautifulSoup(raw.text, "html.parser")
articles = html.select("ul.type01 > li")
# 반복2: 기사에 대해서 반복하면 세부 정보 수집하기
# 리스트를 사용한 반복문으로 모든 기사에 대해서 제목/언론사 출력
for ar in articles:
title = ar.select_one("a._sp_each_title").text
source = ar.select_one("span._sp_each_source").text
print(title, source)
# 수집한 제목, 언론사를 엑셀 파일에 써줍니다.
sheet.append([title, source])
# 작성한 워크북(엑셀파일)을 navertv.xlsx로 저장합니다.
wb.save("navertv.xlsx")

try / except 문을 활용하면 try에서 실행한 코드에서 에러가 발생했을 때, 에러 메시지가 출력되는 것이 아니라 except에 있는 예외 실행문을 실행하게 됩니다.

위 코드에서는 데이터 불러오기에 실패(에러발생) 했을 때는 새로운 파일을 만들어서 데이터를 수집합니다. 기본적으로 try에서 하는 일은 except에서 똑같이 해줘야하기 때문에 Workbook을 만들고, sheet를 설정해 줍니다. 헤더 행을 추가하는 행위는 아래 코드에 영향을 미치지 않기 때문에 신경쓰지 않아도 됩니다.

try:
# 실행문1
# 실행문2
# ...
except:
# 예외문1
# 예외문2
# ...

기본적으로 위와 같이 try: 아래 들여쓰기된 부분에서 에러가 발생하면, except: 아래 들여쓰기된 부분이 실행됩니다. try:를 사용하는 경우, except:가 꼭 있어야합니다.