파이썬/크롤링

[python-파이썬] 6 네이버에서 종목뉴스 크롤링 (crawling) - 1탄

모두의 실험실 2022. 4. 21. 21:02
728x90

 

 

 

안녕하세요. 모두의 파이썬입니다. 네이버에서 종목뉴스 크롤링을 진행하겠습니다. 스스로 문제를 해결하는 항상 우리의 목표입니다. 수학공식을 외우는 것이 아니라, 수학공식을 유도해 내는 것이 우리의 목표입니다. 다른 사람이 해 놓은 것이 정답이 아니라, 여러분이 해결하는 것이 곧 정답입니다. 항상 해낼 수 있다. 그리고 포기란 없다는 마인드를 가지고 시작해 보겠습니다.

전체 글을 요약하면, 1탄에서는 네이버에서 원하는 주식 종목 뉴스를 크롤링 하기 위해서, 지금부터 3시간 전 종목뉴스 결과를 갖고 있는 네이버 뉴스 검색 결과 url을 얻는 과정입니다

저는 코드로 구현하기 전에 매뉴얼(manual), 수동으로 먼저 진행을 해 봅니다. 목표를 정해보겠습니다. 삼성전자 뉴스 기사를 가져오는데, 5시간 전 기사를 모두 가져오고 최신 순서대로 검색을 한 뒤, 뉴스 제목에 삼성전자가 포함된 것만 크롤링 해보겠습니다.

 

우선, 네이버 뉴스검색을 해보겠습니다. 주소창의 주소는 다음과 같습니다. https://search.naver.com/search.naver?where=nexearch&sm=top_sug.pre&fbm=1&acr=1&acq=삼성&qdt=0&ie=utf8&query=삼성전자 

 

ⓒ삼성전자 검색결과, 출처 네이버검색

 

그리고 뉴스를 클릭합니다. 그러면 또 주소창의 주소가 바뀝니다. https://search.naver.com/search.naver?where=news&sm=tab_jum&query=삼성전자 

ⓒ삼성전자 뉴스 검색결과, 출처 네이버검색

 

그리고 옵션을 클릭하고, 최신순을 클릭한 뒤 3시간을 클릭한 뒤에 주소창의 주소를 확인합니다.  https://search.naver.com/search.naver?where=news&sm=tab_pge&query=삼성전자&sort=1&photo=0&field=0&pd=9&ds=2022.04.21.21.12&de=2022.04.22.00.12&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=1 주소와 페이지 정보를 보면서 해석하겠습니다. 

우선 'https://search.naver.com/search.naver?where=news&sm=tab_pge&query=삼성전자&sort=1&photo=0&field=0&pd=9&ds=' 는 기본적 정보입니다. 그뒤에 보면 '2022.04.21.21.12&de=2022.04.22.00.12' 은 시간정보입니다. 현재 22.04.22 00시 12분입니다. 그래서 3시간전 설정을 해야하기 때문에 2022.04.21.21.12이 됩니다. 그리고 '&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=' 이 부분도 기본적 정보입니다. 

ⓒ삼성전자 뉴스 검색결과, 출처 네이버검색

 

마지막에 start=1이 첫 페이지이고 start=11은 두 번째 페이지입니다 네이버 검색창은 한 페이지에 10개씩 뉴스를 배치하고 있습니다. 변수는 종목 면(검색어)/현재 시간/3시간 전 시간/페이지 정보입니다.

url = 'https://search.naver.com/search.naver?where=news&sm=tab_pge&query=' +  stock_name + '&sort=1&photo=0&field=0&pd=9&ds=' + start_time +'&de=' + now_time '&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=' + str((page_num-1)*10 + 1) 은 변수가 포함된 url입니다. start_time은 현재 시간에서 3시간 전 시간입니다. 수식을 만들어 보면 다음과 같습니다.

now_time = datetime.now().strftime('%Y.%m.%d.%H.%M') 

start_time = (datetime.now()-timedelta(hours=3)).strftime('%Y.%m.%d.%H.%M')

두 가지 변수가 정상 동작을 하기 위해서는 package 설치와 선언이 선행되어야 합니다. 필요한 pakage를 선언해 보겠습니다. 코드로 구현하면 다음과 같습니다

 

 

 

 

 

In [5]:
#네이버에서 종목뉴스 크롤링 (crawling)
## datetime은 날짜 시간을 다루는 package
from datetime import datetime, timedelta
## strftime을 사용하여 string형태로 변환
now_time = datetime.now().strftime('%Y.%m.%d.%H.%M') 
##timedelta사용하여 해당 시간단위를 이동, 아래예제는 3일을 이동
start_time = (datetime.now()-timedelta(hours=3)).strftime('%Y.%m.%d.%H.%M') 
print(start_time)
print(now_time)
 
2022.04.22.04.20
2022.04.22.07.20

 

 

url주소를 시작시간/ 현재시간/ 종목정보/ 페이지정보 변수를 포함하는 형태로 구현 하겠습니다

 

 

 

 

 

 

In [12]:
#네이버에서 종목뉴스 크롤링 (crawling)
from datetime import datetime, timedelta 
## datetime은 날짜 시간을 다루는 package
## strftime을 사용하여 string형태로 변환
now_time = datetime.now().strftime('%Y.%m.%d.%H.%M') 
##timedelta사용하여 해당 시간단위를 이동, 아래예제는 3일을 이동
start_time = (datetime.now()-timedelta(hours=3)).strftime('%Y.%m.%d.%H.%M') 
#print(start_time)
#print(now_time)
page_num = 1
stock_name = '삼성전자'
url = 'https://search.naver.com/search.naver?where=news&sm=tab_pge&query=' +  stock_name + \
'&sort=1&photo=0&field=0&pd=9&ds=' + start_time +'&de=' + now_time + \
    '&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=' + \
        str((page_num-1)*10 + 1)
print(url)
 
https://search.naver.com/search.naver?where=news&sm=tab_pge&query=삼성전자&sort=1&photo=0&field=0&pd=9&ds=2022.04.22.04.25&de=2022.04.22.07.25&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=1

 

종목과 시간은 사용자가 지정해야 하는 항목이며, 페이지는 가변적입니다. 하기 그림을 보면, 6페이지로 나옵니다. 6페이지의 정보를 가져오는 것은 F12 또는 우 클릭>검사를 눌러서 'tag'를 찾은 다음, 어떻게 하면 될까요? 지난 기억을 떠올려 보십시오. find('div',{'class', 'sc_page_inner'})을 하면 전체 페이지 정보가 나오며 find('a')는 각 페이지 정보를 가지고 있습니다. 코드로 살펴보겠습니다.

 

ⓒ삼성전자 뉴스 3시간전 최신순 검색결과, 출처 네이버검색

 

 

 

 

In [33]:
#네이버에서 종목뉴스 크롤링 (crawling)
## datetime은 날짜 시간을 다루는 package
from datetime import datetime, timedelta
##HTTP를 호출하는 프로그램을 작성할 때 주로 사용한다
import requests
## html의 내용을 사용자가 활용하기 쉽게 하기위해 사용한다
from bs4 import BeautifulSoup 
## strftime을 사용하여 string형태로 변환
now_time = datetime.now().strftime('%Y.%m.%d.%H.%M') 
##timedelta사용하여 해당 시간단위를 이동, 아래예제는 3일을 이동
start_time = (datetime.now()-timedelta(hours=3)).strftime('%Y.%m.%d.%H.%M') 
page_num = 1
stock_name = '삼성전자'

url = 'https://search.naver.com/search.naver?where=news&sm=tab_pge&query=' +  stock_name + \
'&sort=1&photo=0&field=0&pd=9&ds=' + start_time +'&de=' + now_time + \
    '&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=' + \
        str((page_num-1)*10 + 1)

## 브라우저 호환을 위해서 설정
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '+ \
    '(KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
            } 

##해당 url에 htlm(정보) 요청에사용 / url은 사용자가 원하는 url
r = requests.get(url, headers=headers) 
## 해당 url의 html을 사용자가 활용하기 쉽게 변환
html = BeautifulSoup(r.content, 'html.parser')
tmp = []
## try/except 구문을 사용하여 예외처리
try:
    ## page주소 정보를 가지고 있는 'tag'
    tmp = html.find('div',{'class', 'sc_page_inner'}).find_all('a') 
except:
    pass

##저장될 비어있는 주소리스트 선언
l_address = []
##전체 주소리스트를 l_address에 저장
for i in tmp:
    tmp_add = 'https://search.naver.com/search.naver'+i.get('href')
    l_address.append(tmp_add)
    print(tmp_add)
 
https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90&sort=1&photo=0&field=0&pd=9&ds=2022.04.22.17.31&de=2022.04.22.20.31&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=1
https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90&sort=1&photo=0&field=0&pd=9&ds=2022.04.22.17.31&de=2022.04.22.20.31&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=11
https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90&sort=1&photo=0&field=0&pd=9&ds=2022.04.22.17.31&de=2022.04.22.20.31&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=21
https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90&sort=1&photo=0&field=0&pd=9&ds=2022.04.22.17.31&de=2022.04.22.20.31&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=31
https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90&sort=1&photo=0&field=0&pd=9&ds=2022.04.22.17.31&de=2022.04.22.20.31&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=41
https://search.naver.com/search.naver?where=news&sm=tab_pge&query=%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90&sort=1&photo=0&field=0&pd=9&ds=2022.04.22.17.31&de=2022.04.22.20.31&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:dd,p:all,a:all&start=51

 

1탄에서는 네이버 뉴스검색 결과페이지 url을 얻었습니다. 2탄에서는 결과에서 뉴스정보를 크롤링 하겠습니다.

 

print('모두의 파이썬')

※좋아요/댓글은 서로를 응원합니다!

 

 

 

 

 

728x90
반응형