Post

네이버 종목토론방 크롤링 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.