芋の独り言

当ブログへのアクセスは当ブログのプライバシーポリシーに同意したものとみなします.

ニコニコ動画のコメントの取得方法(selenium):未完だけども...

Downloads - ChromeDriver - WebDriver for Chrome

以上では特にニコニコ動画でクローリング+スクレイピングは禁止していない.ただ,禁則事項

・「niconico」のサーバーに過度の負担を及ぼす行為
・「niconico」の運営を妨害する行為

っとあるので,連続アクセスとかはやらないように...

#encoding:utf-8
from selenium import webdriver
import selenium
from selenium.webdriver.support.ui import Select
from time import sleep
from datetime import datetime,timedelta
import pandas as pd
import re

def main(url,mail,password):
    res = []
    come = {}
    now = datetime.now()
    
    browser = webdriver.Chrome(executable_path='./chromedriver')

    # ニコニコ動画にログイン
    url_login="https://account.nicovideo.jp/login?site=niconico&time=1568443071&hash_key=57aa5439&next_url="
    browser.get(url_login)
    browser.find_element_by_id("input__mailtel").send_keys(mail)
    browser.find_element_by_id("input__password").send_keys(password)
    sleep(1)
    browser.find_element_by_id("login__submit").click()
    sleep(1)
            

    # 動画ページへ
    browser.get(url)
    sleep(10)
    while True:
        try:
            # 広告等の邪魔なポップアップをクリックして閉じる
            browser.find_element_by_css_selector("button.ActionButton.CloseButton.Balloon-closeButton").click()
            sleep(1)
            try:
                # 公式の場合はないので,エラーでスルーさせる
                browser.find_element_by_css_selector("button.ActionButton.CloseButton").click()
                sleep(1)
            except selenium.common.exceptions.ElementNotInteractableException:
                pass
                
            # 過去ログボタンをクリック
            browser.find_element_by_css_selector("button.ActionButton.CalendarButton.is-inactive").click()
            sleep(1)
            # 書込時刻をクリックして,書込時刻でコメントをソートさせておく
            postdate_elm = browser.find_element_by_xpath("//span[@class='CommentPanelDataGrid-HeaderCell' and text()='書込時刻']")
            postdate_elm.click()
            postdate_elm.click()
            sleep(1)

            uploaddate = browser.find_element_by_class_name("VideoUploadDateMeta-dateTimeLabel").text
            uploaddate = datetime.strptime(uploaddate, '%Y/%m/%d %H:%M')
            date_time = now
    
            while True:
                date = '00' + date_time.strftime('%Y-%m-%d')
                time = date_time.strftime('%H:%M')

                # 過去ログの日付を変更
                browser.find_element_by_class_name("DateTimeInput-date").send_keys(date)
                browser.find_element_by_class_name("DateTimeInput-time").send_keys(time)
                sleep(1)
                # (過去)ログの表示(変更)ボタンをクリック
                browser.find_element_by_css_selector("button.ActionButton.PastCommentFetchButton").click()
                sleep(5)

                try:
                    for no in range(2430):
                        try:
                            ele = browser.find_element_by_xpath('//div[@class="DataGrid-Table CommentPanelDataGrid-Table" and @data-offset="{}"]'.format(no))
                            print(ele.text)
                        except selenium.common.exceptions.NoSuchElementException:
                            continue
                    for i in browser.find_elements_by_class_name("DataGrid-TableRow"):
                        j = i.text.split('\n')
                        if len(j) == 4:
                            come = {
                                'comment':j[0],
                                'vpos':j[1],
                                'psotdate':j[2],
                                'no':j[3]
                                }
                        else:
                            # コメントが取れてないorコメントがない(空白)
                            pass
                        

                        if re.match(r'\d\d/\d\d \d\d:\d\d',come['psotdate']):
                            date_time = '{0}/{1}'.format(now.year,come['psotdate'])
                            date_time = datetime.strptime(date_time,'%Y/%m/%d %H:%M')
                        else:
                            date_time = date_time - timedelta(hours=1)
                        
                        
                        if come in res:
                            pass
                        else:
                            res.append(come)
                            
                except selenium.common.exceptions.StaleElementReferenceException:
                    sleep(5)
                    continue

                print(len(res))
                # 日付が投稿日より遡ったら終了
                if (date_time - uploaddate) < timedelta(hours=-1):
                    break
            break
        
        except selenium.common.exceptions.ElementNotInteractableException:
            browser.refresh()
            continue

    browser.close()
    browser.quit()

    df = pd.io.json.json_normalize(res)
    df.sort_values(by='postdate',ascending=True) # ソート
    df.drop_duplicates() # 重複削除
    df.to_csv('{0}_{1}.csv'.format(url.split('/')[-1],now.strftime('%Y-%m-%d_%H-%M')),encoding='cp932')

    print('finish')

if __name__ == '__main__':
    url = input('url:')
    main(url,mail,password)

正直未完というか,seleniumの限界を感じました...いや,やり方知らないだけかもしれませんが... ブラウザに表示されているコメントをすべて見るには,ページ内のスクロールバー(裏で動いているJavascript)を動かす必要があるんですが, それがググっても分からない.また,以上の方法だと,時間がかかりますし,色々問題点があるんですよ... とりあえず,やったよっということで載せておきます.あと,スクリプト見にくくてスミマセン.

参考

selenium

other