본문 바로가기

[일상봇 만들기] 나의 하루하루를 도와줄 친구!

level_04_part_2

 

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