#はじめに
NewsPicksを使ってpickしたニュースを保存したくなったので、マイページ上からスクレイピングするスクリプトを書きました。javascriptが実行されているページだったので、一応後で拡張できるようにseleniumを使いました。今回は当日pickした情報のみをスクレイピングします。
集めた情報はpickしたニュースの以下のデータです。
- url
- タイトル
- 自分のコメント
- 日時が分かるモノ
#NewsPicksへのログインとマイページ情報の取得
import requests
from selenium import webdriver
import time
import datetime
class NPscraping():
def __init__(self, user_id, password):
self.base_url = "https://newspicks.com/"
self.user_id = user_id
self.password = password
def get_today_news(self):
driver = webdriver.PhantomJS()
driver.set_window_size(1920, 1080)
driver.get(self.base_url)
driver.find_element_by_class_name("login").click()
driver.find_element_by_id('login-username').send_keys(self.user_id)
driver.find_element_by_id('login-password').send_keys(self.password)
driver.find_element_by_class_name("login-btn").click()
time.sleep(5)
driver.find_element_by_class_name("user-header").click()
return self.get_news_cards(driver)
def get_news_cards(self, driver):
news_cards = []
today_str = datetime.date.today().strftime('%Y%m%d') #今日の日付
for card in driver.find_elements_by_class_name('news-card'):
if card.get_attribute('data-key')[0:8] != today_str: #今日の日付と同じものだけ
break
news_cards.append({
'url': card.find_element_by_tag_name("a").get_attribute("href"),
'title': card.find_element_by_tag_name("a").find_element_by_class_name("title").text,
'comment': card.find_element_by_class_name("user-comment").find_element_by_class_name("comment").text,
'data-key': card.get_attribute('data-key')
})
return news_cards
色々機能をつけようと思ったのでクラスにしましたが、特にクラスにする必要はないと思います。
- PhantomJSを使ってNewspickのログインページに入り、"login"class要素のボタンを情報を入力してクリック。
- 続いて、"user-header"class要素がマイページに繋がる要素なのでクリック
- today_strに本日の日付をNewsPicksのフォーマットを合わせて保存
- "news-card"class要素の'data-key'要素から日付を比較
- 後は"news-card"class要素の中から必要なデータをdict変数に保存
という流れになっています。(地味にどのclass要素がマイページに繋がるのが見つけるのがしんどかったです)
user_id = <newspickのid>
password = <newspicksのpass>
np = NPscraping(user_id, password)
news_cards = np.get_today_news()
で本日pickしたニュースをdictのlistで入手できます。オブジェクト化した意味はないと思いますが、とりあえず入手はできます。(オブジェクト指向よく分かってないです...)
#今後
今回のスクレイピングは自分で情報を保管したり編集したり、ブログに自動で投稿できるようにするためにデータ化したものです。自分としては、はてなブログの下書きに毎日投稿して、自分のニュース閲覧を管理・公開をしたいと思っています。
#追記
上のコードだと、自分のコメントのデータを取る時画面に表示されてるコメントしか取れません。(多分)60文字以上のコメントは省略されてしまうからです。なので
'comment': card.find_element_by_class_name("user-comment").find_element_by_class_name("comment").text,
ではなくて
'comment': card.find_element_by_class_name("user-comment").find_element_by_class_name("comment").get_attribute("data-org")
にする必要があります。省略されてる場合はdata-orgというattributeが存在するようになるので、そのような場合わけをするだけで取得できます。