Ruby+nokogiriを使ってブログの過去記事をTwitterに投稿してみる
2017/08/07
こんにちは、okutani(@okutani_t)です。本ブログ『vdeep.net』の過去記事を、Twitterに投稿したいなーと思って、きまぐれにRubyで書いてみました。
vdeepはWordPressで運用しているので、探せばそんなプラグインいくらでもありそうですが、それではなんかツマラナイので自分で作ってみることに。
仕事でRubyスクレイピングはちょこちょこやっていたので、実装自体は30分〜ぐらいで倒せました。僕の尊敬する日刊Emacsの「るびきち」さんの書籍がめっちゃ良書なのでめっちゃオススメです。
今回は、次の流れでブログの過去記事をTwitterに投稿していきます。
- open-uriでサイトマップの情報を取得
- nokogiriでスクレイピング
- 重複を取り除き、array.sampleでランダムにひとつ選択
- cronで12, 20時になったらTwitterに投稿
環境はMac、Ruby2.3(rbenvで導入)でコーディング、実際の運用はさくらVPS+CentOS7+Ruby2.3、cronで定期実行しています。以下、関連記事。
では、Rubyを使ってブログの過去記事をTwitterに投稿する方法を、備忘録的につらつら書いていきまっす。
参考rubyでtwitterのbotを実装する(第5世代のやり方) – Qiita
スポンサーリンク
もくじ
gemライブラリの導入
まず必要なgemライブラリを、以下のようにGemfileに記述していきます。と言っても、必要なのはこのふたつだけ。
source "https://rubygems.org"
gem 'nokogiri'
gem 'twitter'
インストールを実行。
$ bundle install
今回はそれぞれ次のバーションが導入されました。
$ gem list --local | grep nokogiri
nokogiri (1.6.8)
$ gem list --local | grep twitter
twitter (5.16.0)
これで必要なライブラリが準備できました。
nokogiriでスクレイピング
nokogiriを使ってスクレイピングをおこなう「Scraping」モジュールを作成します。
今回はWordPressの「PS Auto Sitemap」を使って作成されたサイトマップを対象にスクレイピングをおこなっていきます。それ以外の方は、HTMLの構造に合わせてxpathの指定を変えてあげればOKです。以下、PS Auto Sitemapの参考記事です。
次のように、scraping.rbとして作成しました。
# coding: utf-8
require 'kconv'
require 'open-uri'
module Scraping
def fetch_old_post(url)
old_posts = []
doc = Nokogiri::HTML(open(url, &:read).toutf8)
doc.xpath('//li[contains(@class, "post-item")]/a').each do |node|
old_posts << {title: node.text,url: node.attribute('href').value}
end
# 重複を取り除く
old_posts.uniq!
# ランダムにひとつ返す
old_posts.sample
end
module_function :fetch_old_post
end
あとはTwitterに投稿する処理を書けばOKですね。
Twitter投稿の前準備
Twitterに投稿するため、「Twitter Application Management」というサイトに、アプリを前もって登録しておきます。
のちに「CONSUMER_KEY」「CONSUMER_SECRET」「ACCESS_TOKEN」「ACCESS_TOKEN_SECRET」を利用しますので、そちらをそれぞれ取得するまでみていきましょう。
以下から利用したいTwitterアカウントでログイン。
LINKTwitter Application Management
「Create New App」を選択。
次の形で入力。
- Name: アプリの名前(ユニークなものならなんでもOK)
- Description: アプリの概要(なんでもOK)
- Website: 自分のサイトのURL(なんでもOK)
- Callback URL: サイト上でTwitter認証するときのURLを入力。今回は使わないので空
入力が済んだら「Developer Agreement」にチェックを入れて「Create your Twitter application」をクリック。
登録時にエラーが出る場合
今回、登録しようとすると次のようなエラーが出ました。
Error
You must add your mobile phone to your Twitter profile before creating an application. Please read
https://support.twitter.com/articles/110250-adding-your-mobile-number-to-your-account-via-web for more information.
これは、Twitterアカウントに電話番号が登録されていないと出るようです。以下から電話番号を登録しておきます。
LINKTwitter / 設定
ちなみに、番号は090-XXXX-XXXXではなく、90-XXXX-XXXXのように頭の0を抜いて入力します。無駄にややこしい。。
Twitter認証コードが発行されるので、SMSで受け取って入力。
これでアプリの作成ができるようになりました。
Consumer Keyの取得
Consumer Key, Consumer Secretを取得します。「Keys and Access Tokens」タブからそれぞれ確認しましょう。
このとき、「Access level」が「Read and write」になっていることも一応、確認しておいてください。
これで、Consumer Key, Consumer Secretが取得できました。
Access Tokenの取得
次に、Access Token, Access Token Secretを取得します。同じく、「Keys and Access Tokens」タブの下の方に「Create my access token」ボタンがあるのでクリック。
「Access Token」と「Access Token Secret」をそれぞれ確認。同じく、「Access Level」が「Read and write」になっていることも確認しておくとGoodです。
これですべての設定が整いました。
Twitterに投稿
では、前準備ができたので、「tweet_old_post.rb」というファイルを作成して、スクレイピングをおこなった結果をツイートする処理を書いていきます。
次のように作成しました。
# coding: utf-8
require 'bundler'
Bundler.require
require './scraping'
# 引数のエラー処理
if ARGV[0] == nil
puts 'please input args! ex: $ ruby tweet_old_post.rb http://example.com/sitemap'
exit
end
URL = ARGV[0]
# スクレイピング
old_post = Scraping.fetch_old_post(URL)
# Twitter投稿
client = Twitter::REST::Client.new(
consumer_key: "CONSUMER_KEY",
consumer_secret: "CONSUMER_SECRET",
access_token: "ACCESS_TOKEN",
access_token_secret: "ACCESS_SECRET",
)
client.update(old_post[:title] + ' ' + old_post[:url])
投稿できるか確かめてみましょう。
$ ruby tweet_old_post.rb サイトマップのURL
ちゃんと過去記事が投稿されていればOKです。
cronを使って定期実行してみる
では、cronを使って定期実行してみましょう。cronでRubyプログラムを定期実行する方法は、過去に記事にしているので参考にしてください。
サーバーに作成したプログラムをアップロードし、次のようにcrontabで設定すれば、毎日12時と20時に過去記事がツイートされます。
以下はvdeepのサイトマップをツイートする一例です(試すときはご自身のサイトでお願いします)。
$ crontab -e
PATH=$PATH:/usr/local/rbenv/shims:/usr/bin
0 12,20 * * * cd /home/username/tweet_old_post && ruby tweet_old_post.rb http://vdeep.net/sitemap
ツイートが一番読まれやすい時間帯が「12時と20時ごろ」なので、上記の設定にしています。ここらへんは好みの時間帯でセットしてみてください。
これで、12時と20時に過去記事がツイートされていればOKですね。
ソースコード
ソースコードはGitHubで公開しています。
本記事では紹介しませんでしたが、さらに簡潔・柔軟に利用するため、認証キーをYAMLで管理しています。参考にしてください。
参考okutani-t/tweet_old_post: WordPressの過去記事をツイートするRubyプログラム
あまり実用的なプログラムとは言えないですが(プラグインなどでかんたんに代用できるため)、Rubyを使ったスクレイピング、Twitter連携時の一例になれば幸いです。
Web開発のお仕事を募集しています
フリーランスのエンジニアとして、Webシステム開発のお仕事依頼を随時募集しています(現在の業務量によってお受けできない場合もあります)。
「Ruby on Rails」「JavaScript(jQuery, Reactなど)」「HTML + CSS」を用いたシステム開発、「Heroku」等を用いたサーバー構築・運用、「Git」や「GitHub」を利用したソーシャルコーディングなどに対応しています。
ご依頼を検討している方は、下記リンク本ブログからのお問い合わせ、もしくはokutaniのポートフォリオからご連絡ください。
LINKお問い合わせ
スポンサーリンク