KBIdeaMarketデジタルグランプリ-1 Naverプロジェクトディスカッションルームscraping

5787 ワード

KBIdeaMarketデジタルグランプリで各サイトに対してscrapingを行ったコード,テキストマイニングコードを添付した.
必要なライブラリ
from selenium.webdriver import Chrome
import time
import os
import pandas as pd
from bs4 import BeautifulSoup
from selenium.webdriver.common.desired_capabilities import  DesiredCapabilities
import datetime as dt
import urllib.request
import openpyxl
from selenium import webdriver
import requests
import subprocess
import re
from selenium.webdriver.support.ui import Select
from selenium.webdriver import ActionChains
import os, shutil
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import xlrd
import io
import sys
import json

1.NAVERプロジェクト討論室のウェブサイト分析


NAVERプロジェクトディスカッションルームは、特にモバイルサイト上でのみプロジェクトディスカッションルームを提供します.NAVERプロジェクトディスカッションルームのURLは
https://m.stock.naver.com/worldstock/stock/ZTEK.O/discussからなり、
ここで気をつけたいのはZTEKOすべてのプロジェクトのディスカッションルームは/ZTEKですO/を除いて、共通の形式があります.そのため、沢沢のプロジェクトコードはZTEKで、アップルはAAPLで、テスラはTSLAで、それを収集する必要があります.

[図1:NAVERプロジェクトディスカッションルームURL形式]
また、NAVERプロジェクトディスカッションルームは、ダイナミックスクリプトが必要なサイトです.

[図2:NAVERプロジェクトディスカッションルーム表示ボタン]
写真のようにコメントが60~80個を超える場合は、「もっと」ボタンを押してから行うため、BeautifulSoup、Seleniumライブラリを使用しています.

2.NASDAQ株価総額上位50位項目コード(TICKER)データ収集


公募に先立ち、ナスダックの株価総額50位の株名を知る.これはナスダックの公式サイトが提供し、関連データを使用しています.
https://www.nasdaq.com/market-activity/stocks/screener?exchange=nasdaq&letter=0&render=download
そこからこの点がわかる.

3.NAVERプロジェクトディスカッションルームの閲覧

options = webdriver.ChromeOptions()
browser = webdriver.Chrome('C:/data/chromedriver.exe', options=options) #selenium 실행
data = pd.read_csv('C:/Users/apjh2/공모전/나스닥_50.csv')
ticker = data['Symbol'] #NASDAQ 사이트에서 다운로드 받은 CSV에서 'Symbol' 컬럼을 사용하여 ticker 데이터프레임에 포함
これでSeleniumを実行し、プロジェクトディスカッションルームURLに入る「symbol」もロード済みです.今度はscrapingの番だ
stop_date = ('2022/01/01') #크롤링 기간 설정
formatted_date2 = time.strptime(stop_date, "%Y/%m/%d")
for tick in ticker:
    titles = []
    comments = []
    종목 = []
    dates = []
    df = pd.DataFrame()
    browser.get('https://m.stock.naver.com/worldstock/stock/{}.O/discuss'.format(tick))
    time.sleep(0.5)
    SCROLL_PAUSE_SEC = 0.5
    last_height = browser.execute_script("return document.body.scrollHeight")         

    while True:
        # 해당 페이지를 '더보기' 버튼이 나올 때까지 스크롤 다운                      
        browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")

        time.sleep(SCROLL_PAUSE_SEC)                                          
        browser.execute_script("window.scrollTo(0, document.body.scrollHeight-50);")
        time.sleep(SCROLL_PAUSE_SEC)
        # Calculate new scroll height and compare with last scroll height            
        new_height = browser.execute_script("return document.body.scrollHeight")
        try: #더보기 버튼이 있으면 클릭하고, 없으면 더 보기 버튼이 없음을 출력
            element = browser.find_element_by_xpath('//*[@id="content"]/div[7]/a')
            browser.execute_script("arguments[0].click();", element)
            time.sleep(SCROLL_PAUSE_SEC)
        except NoSuchElementException:
            print(tick,': 더 보기 없음')
            break
        html = browser.page_source
        soup = BeautifulSoup(html.decode('euc-kr'),'html.parser') #해당 html를 euc-kr로 디코딩할 것을 지정
        final = browser.find_elements_by_class_name('DiscussListItem_info__23BlI')
        final_date = final[-1].text
        final_date = re.search('\n(.+?)\n', final_date).group(1)
        final_date =final_date.replace('.','/')
        final_date = final_date.rstrip('/')
        formatted_date1 = time.strptime(final_date, "%Y/%m/%d") #날짜 비교를 위해 맨 마지막 댓글의 날짜를 YY-MM-DD의 형태로 변환
        if formatted_date1 < formatted_date2:
            try: #종료 날짜보다 맨 마지막 댓글의 날짜가 더 옛날 것이면, 모든 제목과 댓글을 데이터프레임에 저장
                data_html = soup.find('ul',{'class':'DiscussList_listDiscuss__3AaMp listDiscussCard'}).find_all('li',{'class':'DiscussListItem_item__2W_lB'})
                for i in range(len(data_html)):
                    titles_1 = remove_html(str(data_html[i].find('strong')))
                    comments_1 = remove_html(str(data_html[i].find('p')))
                    titles.append(titles_1)
                    comments.append(comments_1)
                    df_1 = pd.DataFrame(titles)
                    df_2 = pd.DataFrame(comments)
            except AttributeError as e:
                    print(e)
            result = pd.concat([df_1,df_2],axis=1,ignore_index = True)
            result.to_csv('C:/Users/apjh2/공모전/나스닥_50/{}.csv'.format(tick))
            #나스닥_50 폴더에 Symbol 이름으로 csv로 저장
            print("총 ", i, "개 댓글 수집 완료 ", tick,':저장 완료')
            break

        last_height = new_height
この符号化の実行結果は、すべての株のスコアリング結果が正しく格納されていることを示している.

[図3.スクリプトコードを実行した結果]