8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

newspicksで自分がpickしたニュースのスクレイピング

Last updated at Posted at 2017-12-11

#はじめに
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が存在するようになるので、そのような場合わけをするだけで取得できます。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?