네이버 종목토론방 크롤링 2
지난 버전 링크
코드
version 9
저번 버전에서는 페이지 기반으로 크롤링을 했었고 이제 저번에 만든 날짜 찾기와 크롤러를 합쳐 날짜 기반으로 동시에 페이지를 찾아 크롤링 하는 코드를 만들었다. 입력은 YY.MM.DD형식으로 입력하고 시작 날짜가 끝 날짜보다 더 미래에 있어야 한다. (시작 날짜 > 끝 날짜)
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import crawler_bs4
import date_finder
print("찾고자 하는 날짜를 입력하시오\n 시작 날짜, 끝 날짜 ex) 2023.12.11")
start_date = input()
end_date = input()
print("타입(excel, csv, txt), 스텝")
type = int(input()) #타입 설정 엑셀, csv, 텍스트
start, end, url = date_finder.dfinder(start_date, end_date)#11월 5일
print(f"{start}에서 {end} 페이지 까지")
crawler_bs4.CWBS(start, end, type, url, start_date, end_date) #crawler_bs4파일의 CWBS함수에 전달
print("크롤링 끝 \n")
</br>
date_finder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import requests
from bs4 import BeautifulSoup as bs
from tqdm import tqdm #현제 크롤링 상황 체크
from fake_useragent import UserAgent
def dfinder(start_date, end_date):
find_first_date = False
find_end_date = False
crawled_url_4_date = []
print(f"{start_date}에서 까지의 {end_date} 날짜를 찾습니다.")
#크롤러
for t in tqdm(range(1, 100084)):
url = f'https://finance.naver.com/item/board.naver?code=005930&page={t}'#접속 링크
user_agent = UserAgent()#fake_useragent함수, useragent 렌덤값 설정하기 위해 UserAgent()불러옴
if(t <= 99): #99페이지 전까지는 참조할 필요 없음, 오히려 참조하면 접속 불가
headers = {
'User-Agent': user_agent.random #랜덤 agent 설정
}
else: #1페이지 이후 참조
headers = {
'Referer': f'https://finance.naver.com/item/board.naver?code=005930&page={t-1}', #Referer를 이용해서 다음 링크로 들어가기 전에 참조, 원래 100페이지 이후부터 참조 필요한데 굳이?
'User-Agent' : user_agent.random #랜덤 agent 설정
}
response = requests.get(url = url, headers = headers) #url접속
#print(response) # 접속 확인 (200 = 성공)
html_text = response.text #response에서 html값 텍스트만 가져오기
html = bs(html_text, 'html.parser') #beautifulsoup로 HTML 문서를 파싱
date_crawling = html.select('.tah.p10.gray03') #파싱된 문서에서 .tah p10 gray03 클래스 전부 찾기 , 추천 비추천 포함이기는 하나 날짜로 찾을 것이기에 문제 없음
title_parsing = html.select('.title')
#.title 클래스에서 a.href 속성값만 추출
if find_first_date == False:
for n in date_crawling:
check = n.text
if start_date in check:
start_date_page = t
find_first_date = True
print(f"\n{start_date}를 {start_date_page}페이지에서 찾았습니다.")
break
# if find_first_date == True:
# break
if find_first_date == True:
if find_end_date == False:
for n in title_parsing:
crawled_url_4_date.append(n.a["href"])
for n in date_crawling:
check = n.text
if end_date in check:
end_date_page = t
find_end_date = True
print(f"\n{end_date}를 {end_date_page}페이지에서 찾았습니다.")
break
# if find_end_date == True:
# break
if find_first_date == True:
if find_end_date == True:
break
return start_date_page, end_date_page, crawled_url_4_date #날짜에 맞는 페이지 리턴
if __name__ == "__main__":
start, end, url = dfinder("2023.12.11", "2023.12.10")
print(start, end, url)
</br>
crawler_bs4.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import os
import requests
from bs4 import BeautifulSoup as bs
import time
import pandas as pd
import datetime
from tqdm import tqdm
import fake_useragent #pyinstaller 사용 불가 우씨...
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
#정적 크롤러
def CWBS(page_start, page_end, input_type, url, start_date, end_date):
error_count = 0 #관리자 삭제 링크 수 세기
save_type = int(input_type) #저장 타입
#로그 파일 존재 확인
log_file_name = 'log.txt'
if os.path.isfile(log_file_name):
print("log 파일 존재")
else:
f = open("log.txt", 'w')
f.close()
print("로그파일 생성")
#크롤링 시작 log에 출력
file = open("log.txt", "a", encoding="UTF-8")
file.write(f"\n---------------------------------\n 정적 크롤링 시작\n 시작 페이지: {page_start}, 마지막 페이지: {page_end}\n")
file.close()
start_time = time.time()
#필요 리스트
date_list = [] #날짜
title_list = [] #제목
comment_list = [] #본몬
goodcnt_list = [] #추천
badcnt_list = [] #비추천
url_list = [] #크롤링된 url
#크롤링 시작
print("데이터 수집 시작")
for url_p in tqdm(url):
try: #관리자 삭제 링크 생기면 except 실행 후 다음 링크 크롤링
user_agent = fake_useragent.UserAgent()
headers = {
'Referer': 'https://finance.naver.com/item/board.naver?code=005930',
'User-Agent': user_agent.random
}
url = "https://finance.naver.com" + url_p #링크에 item 뒷부분만 포함되어있기에 앞부분 추가
response_url_html = requests.get(url=url, headers=headers) #링크 요청
url_html_text = response_url_html.text #받은 json파일에서 text값만 추출
html = bs(url_html_text, 'html.parser') #html 파싱
#요소 접근
date = html.select_one('.gray03.p9.tah').text #날짜
comment_not_cleaned = html.select_one('.view_se').text #본문
comment = comment_not_cleaned.replace("\n", "") #본문에서 \n제거
comment = ILLEGAL_CHARACTERS_RE.sub(r'', comment)
title_not_cleaned = html.select_one('.c.p15').text #제목
title = title_not_cleaned.replace("#", "").replace("■", "").replace("[", "").replace("]", "") #제목에서 특수문자 제거
title = ILLEGAL_CHARACTERS_RE.sub(r'', title)
goodcnt = html.select_one('.tah.p11.red01._goodCnt').text #추천
badcnt = html.select_one('.tah.p11.blue01._badCnt').text #비추천
#크롤링한 요소 리스트에 담기
date_list.append(date[:10]) #year, month, day만 크롤링
comment_list.append(comment)
title_list.append(title)
goodcnt_list.append(goodcnt)
badcnt_list.append(badcnt)
url_list.append(url) #디버깅용 url
except:
error_count =+ 1
#dataframe 생성 후 크롤링 한 것들 전부 담기
df = pd.DataFrame()
df['date'] = date_list
df['title'] = title_list
df['comment'] = comment_list
df['good'] = goodcnt_list
df['bad'] = badcnt_list
df['url'] = url_list
#데이터프레임 저장
if(save_type == 1):
df.to_excel(f"data/{start_date}_to_{end_date}_bs_{page_start}_{page_end}.xlsx", index = False)
elif(save_type == 2):
df.to_csv(f"data/{start_date}_to_{end_date}_bs_{page_start}_{page_end}.csv", index = False, sep='\t')
elif(save_type == 3):
df.to_csv(f"data/{start_date}_to_{end_date}_bs_{page_start}_{page_end}.txt", index = False, sep='\t')
else:
print("전부생성")
df.to_csv(f"data/{start_date}_to_{end_date}_bs_{page_start}_{page_end}.txt", index = False, sep='\t')
df.to_csv(f"data/{start_date}_to_{end_date}_bs_{page_start}_{page_end}.csv", index = False, sep='\t')
df.to_excel(f"data/{start_date}_to_{end_date}_bs_{page_start}_{page_end}.xlsx", index = False)
#디버깅용 시간 체크
end_time = time.time()
sec = (end_time - start_time)
result_t = str(datetime.timedelta(seconds=sec)).split(".") #소수점 이후로 자르기
print(f"시간 : {result_t[0]}") #잘린 소수점은 [1]
file = open("log.txt", "a", encoding="UTF-8") #마무리 로그
file.write(f"걸린 시간 : {result_t[0]}, error_count : {error_count}")
file.close()
This post is licensed under CC BY 4.0 by the author.