メインコンテンツへスキップ
見出し画像

Pythonでやってみた7:データ自動取得(Webスクレイピング)①noteのダッシュボードデータ取得

    KIYO

    1.概要

     自分が欲しい情報を自動で取得する技術としてWebスクレイピングがあります。本記事ではnoteのダッシュボードから各記事のビュー回数、コメント、スキ回数を自動で取得します。

    画像

     なお別記事ではAPI(非公式)を実施しておりますのでご参考までに

    2.参考資料

    3.完成品の説明

     まとめとして完成品を説明します。ファイル内にはnote_selenium.ipynbスクリプトファイルとwebドライバを入れております。

    画像

    3-1.完成コード

     完成コード及び注意点は下記の通りです。

    ●ログインはTwitterアカウントから実施しています。
    ●安定性を考慮してdriver.implicitly_wait(10)と長めに設定しました。

    [In]
    import time 
    from selenium import webdriver
    from webdriver_manager.chrome import ChromeDriverManager
    from selenium.common.exceptions import NoSuchElementException
    import pandas as pd 
    
    url = 'https://note.com/sitesettings/stats'
    
    driver = webdriver.Chrome('chromedriver.exe') #chrome webdriverを起動、パスを指定
    driver.implicitly_wait(10)
    driver.get(url) #URLにアクセス
    
    time.sleep(1)
    driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > main > div > div.o-login__auth > div > button').click() #ログインボタンをクリック
    
    driver.find_element_by_id('username_or_email').send_keys('Twitterのユーザー名') #ユーザー名
    driver.find_element_by_id('password').send_keys('Twitterのパスワード') #ユーザー名
    driver.find_element_by_id('allow').click()#ログインボタンをクリック
    
    driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > div.t-siteSettings > div > main > div > div.t-settings__center > div > div > div > div.o-statsContent__nav > div.o-statsContent__navSort > ul > li:nth-child(4) > button').click() #全期間ボタンを押す
    
    from selenium.common.exceptions import NoSuchElementException
    while True:
        try:
            button_more = driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > div.t-siteSettings > div > main > div > div.t-settings__center > div > div > div > div:nth-child(6) > button') #もっと見るボタン
            button_more.click()
        except (NoSuchElementException) as e:
            print('全ての「もっと見る」ボタンをクリックしました')
            break
    
    tabletag = driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > div.t-siteSettings > div > main > div > div.t-settings__center > div > div > div > div.o-statsContent__notesList') #テーブルタグの親要素を取得
    df = pd.read_html(tabletag.get_attribute('innerHTML'))[0]
    
    df.columns = ['記事', '全体ビュー', 'コメント', 'スキ']
    df.to_excel('note_dashboard.xlsx', index=False) #Excelに保存
    driver.quit() 
        

    3-2.完成品のアウトプット

     スクリプトを実行するとWebドライバが立ち上がり下記動作がすべて自動で処理されます。

    画像

     上記完了後にフォルダ内に「note_dashboard.xlsx」ができ、下記のようなExcelファイルが作成されます。

    画像

    4.動作説明

    4-1.Webドライバの立ち上げ

     まずはSeleniumでWebドライバを立ち上げます。

    [In]
    import time 
    from selenium import webdriver
    from webdriver_manager.chrome import ChromeDriverManager
    from selenium.common.exceptions import NoSuchElementException
    import pandas as pd 
    
    url = 'https://note.com/sitesettings/stats'
    
    driver = webdriver.Chrome('chromedriver.exe') #chrome webdriverを起動、パスを指定
    driver.implicitly_wait(10)
    driver.get(url) #URLにアクセス
    
    time.sleep(1) #動作安定用

    4-2.noteにログイン

     Twitterログインボタンからユーザー名とパスワードを入れてログインボタンを押します。

    [In]
    driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > main > div > div.o-login__auth > div > button').click() #ログインボタンをクリック
    
    driver.find_element_by_id('username_or_email').send_keys('Twitterのユーザー名') #ユーザー名
    driver.find_element_by_id('password').send_keys('Twitterのパスワード') #ユーザー名
    driver.find_element_by_id('allow').click()#ログインボタンをクリック
    

    4-3.全期間へ移動

     ダッシュボード画面の「全期間」ボタンを押します。

    [In]
    driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > div.t-siteSettings > div > main > div > div.t-settings__center > div > div > div > div.o-statsContent__nav > div.o-statsContent__navSort > ul > li:nth-child(4) > button').click() #全期間ボタンを押す
    

    4-4.「もっと見る」ボタンを押してデータを全表示★

     現時点ではブラウザに十分な情報が表示されていないため「もっと見る」ボタンを押す必要があります。そこで「もっと見るボタンがなくなる」==「NoSuchElementExceptionエラーが発生したらループを抜ける」処理を追加して「もっと見る」ボタンがなくなるまで処理をかけました。

    [In]
    from selenium.common.exceptions import NoSuchElementException
    while True:
        try:
            button_more = driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > div.t-siteSettings > div > main > div > div.t-settings__center > div > div > div > div:nth-child(6) > button') #もっと見るボタン
            button_more.click()
        except (NoSuchElementException) as e:
            print('全ての「もっと見る」ボタンをクリックしました')
            break

     要素がないことを確認してからループを抜けるため最後の処理ではdriver.implicitly_wait()の引数秒だけ要素を探すことになります無駄な待ち時間が発生する。

    4-5.データの抽出

     ダッシュボードはTableタグで構成されているためTableタグを含む要素を取得して"pd.read_html()"に入れることでDataFrame型データを取得できます。

    [In]
    tabletag = driver.find_element_by_css_selector('#__layout > div > div:nth-child(1) > div.t-siteSettings > div > main > div > div.t-settings__center > div > div > div > div.o-statsContent__notesList') #テーブルタグの親要素を取得
    df = pd.read_html(tabletag.get_attribute('innerHTML'))[0]

    【参考】4-5-1.Tableタグの取得
     
    タグ要素はelem.get_attribute('innerHTML')で取得しました。参考までに中身をbs4で示します。

    [In]
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(tabletag.get_attribute('innerHTML'), 'html.parser')
    soup.prettify()
    画像

    【参考】4-5-2.pd.read_html()の動作
     
    pd.read_html()はTableタグを含む要素を解析してDataFrame型に変換してくれます。参考までに上記では"tabletag.get_attribute('innerHTML')"を入れましたがTableタグを含むURLを入れるとWebサイトから情報抽出も可能です。

    画像

    4-6.Excelファイルに出力/ドライバの立ち下げ

     最後に取得したデータ(df型)をExcelに出力してドライバを立ち下げます。

    [In]
    df.columns = ['記事', '全体ビュー', 'コメント', 'スキ']
    df.to_excel('note_dashboard.xlsx', index=False) #Excelに保存
    driver.quit() 

    あとがき

     本当はここから下記のようなことをしてみたいけどWebスクレイピングをメインにした記事のため今回は避けました。

    ●記事で使用したハッシュタグワードや数も取得(どこにあるか知らんけど)
    ●記事の文字の形態素解析
    ●上記も含めて全データで機械学習をしてどのような記事が伸びるのか


     
     
     

    KIYO

     
     
    普段は製造業で企画/開発/設計しております。記事はプログラミング・機械学習、IoT関係の記事をメインで作成し、なるべく1つの記事で知りたいことを網羅していきます。内容は学術的より実装・アウトプット(ほしくなるもの)を重視して作成しています。 面白そうな仕事があればやりたいです!

    あなたへのおすすめ