Level 04 |
02_인터넷 시대를 살아가는 우리를 위한 자동화 |
1_파이썬에게 '나 대신 일 시키기'
1) 자동화? 그게 뭐지요?
[뉴스 클리핑]
회사에서는 '뉴스 클리핑' 이라는 가장 대표적인 반복 작업이 있습니다.
이를 한 단계씩 풀어보며, 반복적인 요소가 어떻게 있는지 알아볼게요.
본인 회사 또는 경쟁사가 언급이 되어있거나, 업계의 동향과 관련된 최신 뉴스
등을 시장 동향을 알기 위해 매일매일 주기적으로 수집하는 것입니다.
이 업무의 단계는 아래와 같습니다.
1 - 네이버나 구글과 같은 검색 사이트에서 '키워드 입력'
2 - 특정 기간에 작성된 뉴스의 제목과 내용을 가져오기
3 - 제목과 내용을 엑셀로 정리해서 업무 관계자에게 메일 보내기
알고자 하는 키워드가 100 가지라면 100 번 반복,
매일 수행한다면 출근한 횟수 만큼 반복합니다.
학력 / 경력 등 자격요건이 필요하지 않은 업무임에도 불구하고
제가 구인구직 사이트에서 확인했을 때만 하더라도
최저임금 대비 2배 이상 받는 고수익 직종이었습니다.
이러한 업무를 자동화할 수 있는 사람은 고부가가치 인력이 될 것입니다.
[업무 자동화 사례]
2018년 말 경에 인터넷을 뜨겁게 달구었던 사건이 하나 있습니다.
'코딩하는 공익' 이라는 필명으로 활동한 분이 쓴 글이 화제가 되었는데요
뉴스기사로도 많이 소개가 되었지만
요약하면
'하루 8 시간씩 6개월, 총 1000 시간 걸리는 단순 반복 작업을 파이썬으로 30분 만에 끝냈다.'
입니다.
이러한 사례를 보면 알 수 있듯,
나 대신 파이썬이 일 하게 만들수만 있다면
돈으로 환산하기 어려운 정도의 부가가치를 창출해 낼 수 있답니다.
2) 인터넷으로 하는 작업을 파이썬으로 자동화하기
'느낌 아니까'
우리는 이미 그 느낌을 어느정도 알고 있습니다.
requests.get() 으로 실시간 뉴스나 날씨 정보들을 이미 가져와 다뤄보았죠.
그런데, 기존 단계를 진행하며 조금 아쉬운 부분을 느끼셨나요?
뉴스 데이터를 다뤘을 때를 생각해볼게요
'정보가 50개밖에 없었습니다 !'
1 - 우리가 직접 홈페이지에 들어가서
2 - 키워드를 입력하고
3 - 검색 버튼을 눌렀을 때
나오는 결과는 많게는 10만 건 이상일 것입니다.
직접 접속해야지만 비로소 나오는 정보들이 있다는 것이지요.
그 이외에도 직접 접속해야만 얻을 수 있는 정보들의 예시들은 다음과 같습니다.
1 - '더 보기' , '다음' 과 같이 버튼을 눌러야 보이는 경우
2 - 버튼 위치에 마우스를 올려야만 버튼이 보이는 경우
3 - 검색어 또는 아이디/비밀번호로 로그인 해야 볼 수 있는 경우
4 - 접속시 3 ~ 5 초간 기다려야 화면을 보여주는 경우
위 4 가지 경우 중 하나라도 해당이 된다면...
requests.get() 방식으로 정보를 가져오는 것이 불가능합니다.
요즘에는 많은 사이트들이 한 번에 모든 것을 보여주는 것이 아닌,
사용자의 마우스 움직임이나 클릭 등에 반응해서 정보를 보여주는데요
이런 사용자의 행동을 파이썬으로 구현할 수 있다면?
인터넷으로 하는 반복작업을 대부분 파이썬이 나 대신 하게 만들 수 있을 겁니다.
[예제문제]
앞서 다루었던, 뉴스 검색 정보를 RSS 가 아닌, 직접 접속한 직후부터
뉴스 제목을 가져오는 것 까지의 코드는 아래와 같습니다.
import bs4 as bs
from selenium import webdriver
path = 'C:/Users/one/Desktop/chromedriver/chromedriver.exe'
url = 'https://search.naver.com/search.naver?where=news&query= 손흥민'
driver = webdriver.Chrome(path)
driver.get(url)
data = driver.page_source # 현재 크롬으로 접속한 페이지의 전체 정보를 가져옵니다.
parsed_data = bs.BeautifulSoup(data) # 페이지 정보를 우리가 사용할 수 있게끔 파싱 해 줍니다.
article_pack = parsed_data.find('ul', class_="type01") # (ul 태그와 type01 클래스) 라는 키 안에
# 우리가 원하는 제목들이 들어있습니다.
articles = article_pack.find_all('li') # 뉴스들은 각각 (li 태그) 라는 키 안에 들어있습니다.
# find_all 로 결과들을 리스트에 넣어줍니다.
for article in articles: # 하나씩 뽑으면, li 태그로 감싸져 있는 결과가 나올 겁니다.
try:
title = article.find('dt').find('a') # 제목은 dt 태그 안에서, 또다시 a 태그 안에 있습니다.
title_text = title.text # 제목은 태그 안의 텍스트이므로 .text 로 구합니다.
print(title_text)
except:
pass
[예제문제]
한 페이지 안의 모든 제목을 가져오는 코드를 만들었습니다!
이제는, 페이지를 뒤로 넘길 수 있게 클릭만 해주면 뒤의 많은 페이지들의 정보를 가져올 수 있을 겁니다.
페이지가 선택된 이후, 제목을 가져오는 부분을 함수로 바꿔서, 반복해서 사용할 수 있게 하면?
import bs4 as bs
from selenium import webdriver
path = 'C:/Users/one/Desktop/chromedriver/chromedriver.exe'
url = 'https://search.naver.com/search.naver?where=news&query= 손흥민'
driver = webdriver.Chrome(path)
driver.get(url)
def title_grab():
data = driver.page_source # 현재 크롬으로 접속한 페이지의 전체 정보를 가져옵니다.
parsed_data = bs.BeautifulSoup(data) # 페이지 정보를 우리가 사용할 수 있게끔 파싱 해 줍니다.
article_pack = parsed_data.find('ul', class_="type01") # (ul 태그와 type01 클래스) 라는 키 안에
# 우리가 원하는 제목들이 들어있습니다.
articles = article_pack.find_all('li') # 뉴스들은 각각 (li 태그) 라는 키 안에 들어있습니다.
# find_all 로 결과들을 리스트에 넣어줍니다.
for article in articles: # 하나씩 뽑으면, li 태그로 감싸져 있는 결과가 나올 겁니다.
try:
title = article.find('dt').find('a') # 제목은 dt 태그 안에서, 또다시 a 태그 안에 있습니다.
title_text = title.text # 제목은 태그 안의 텍스트이므로 .text 로 구합니다.
print(title_text)
except:
pass
page_grab()
[예제문제]
이제 여기에 다음 페이지로 넘어가는 함수 next_page() 를 구현한다면?
for i in range(10):
next_page()
page_grab()
이와 같은 반복문으로, 이후 많은 페이지들의 제목 정보를 가져올 수 있어요.
next_page() 를 만들어볼게요.
import bs4 as bs
from selenium import webdriver
path = 'C:/Users/one/Desktop/chromedriver/chromedriver.exe'
url = 'https://search.naver.com/search.naver?where=news&query= 손흥민'
driver = webdriver.Chrome(path)
driver.get(url)
def title_grab():
data = driver.page_source # 현재 크롬으로 접속한 페이지의 전체 정보를 가져옵니다.
parsed_data = bs.BeautifulSoup(data) # 페이지 정보를 우리가 사용할 수 있게끔 파싱 해 줍니다.
article_pack = parsed_data.find('ul', class_="type01") # (ul 태그와 type01 클래스) 라는 키 안에
# 우리가 원하는 제목들이 들어있습니다.
articles = article_pack.find_all('li') # 뉴스들은 각각 (li 태그) 라는 키 안에 들어있습니다.
# find_all 로 결과들을 리스트에 넣어줍니다.
for article in articles: # 하나씩 뽑으면, li 태그로 감싸져 있는 결과가 나올 겁니다.
try:
title = article.find('dt').find('a') # 제목은 dt 태그 안에서, 또다시 a 태그 안에 있습니다.
title_text = title.text # 제목은 태그 안의 텍스트이므로 .text 로 구합니다.
print(title_text)
except:
pass
'''
다음 페이지 버튼을 크롬 개발자 화면에서 보면, x_path 라는 성분을 알 수 있습니다.
x_path 라는 것은, 쉽게 말하면 해당 부품의 좌표를 나타냅니다.
맨 처음 페이지에서 '다음 페이지' 버튼의 x_path 성분은
'//*[@id="main_pack"]/div[2]/div[2]/a[10]'
입니다.
두 번째 페이지에서는 '다음 페이지' 버튼의 x_path 성분이
'//*[@id="main_pack"]/div[2]/div[2]/a[11]'
가 되는데요, 여기서 인덱싱 번호가 10 -> 11 로 바뀌었습니다.
첫 번째 페이지에서 인덱싱 번호를 11 로 하면 에러가 나는데요,
try ~ except 를 사용해서 11 일 때 에러가 나면 10 으로 동작하게 만들어줍니다.
이렇게 구성하면 모든 페이지에서 '다음 페이지' 버튼을 누를 수 있게 됩니다.
'''
def next_page():
try:
driver.find_element_by_xpath('//*[@id="main_pack"]/div[2]/div[2]/a[11]').click()
except:
driver.find_element_by_xpath('//*[@id="main_pack"]/div[2]/div[2]/a[10]').click()
page_grab()
next_page()
[연습문제]
자, 이제 다음 페이지로 넘어가는 함수도 구현했으니
for 문으로 처음부터 20 페이지까지의 모든 뉴스 정보를 가져와 볼까요?
'[일상봇 만들기] 나의 하루하루를 도와줄 친구!' 카테고리의 다른 글
200%_part_01 (0) | 2019.08.01 |
---|---|
level_04_part_3 (0) | 2019.07.23 |
level_04_part_1 (0) | 2019.07.05 |
level_03_part_2 (0) | 2019.07.03 |
level_03_part_1 (0) | 2019.07.02 |