Downloads - ChromeDriver - WebDriver for Chrome
以上では特にニコニコ動画でクローリング+スクレイピングは禁止していない.ただ,禁則事項に
っとあるので,連続アクセスとかはやらないように...
#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)を動かす必要があるんですが,
それがググっても分からない.また,以上の方法だと,時間がかかりますし,色々問題点があるんですよ...
とりあえず,やったよっということで載せておきます.あと,スクリプト見にくくてスミマセン.
参考
- PythonでSeleniumを使ってスクレイピング (基礎) - Qiita
- Selenium webdriverよく使う操作メソッドまとめ - Qiita
- Chrome を使った e2e テストの <input type=date> への入力に注意 - Qiita
- PythonとSeleniumを使用したドロップダウンメニューの取得して値をセットする - Qiita
- Python - selenium.common.exceptions.StaleElementReferenceException|teratail
- How to locate an element by class name and its text in python selenium - Stack Overflow
- PythonによるSelenium Tips - Qiita
- Python + Selenium で Chrome の自動操作を一通り - Qiita
other
- 意外と知らないChrome Developer Toolsの便利な機能 - Qiita
- ネストしたリストや辞書をPandasデータフレームに格納 - Qiita
- pandasのjson_normalizeで辞書のリストをDataFrameに変換 | note.nkmk.me
- python 現在時刻取得 - Qiita
- 【Python】文字列と日付(datetime,date)の変換.例とstrp,strfの覚え方
- datetime --- 基本的な日付型および時間型 — Python 3.7.4 ドキュメント
- UnboundLocalError: local variable '変数名' referenced before assignment ってエラー - TIL