読者です 読者をやめる 読者になる 読者になる

ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

はてなブログの投稿予告ツイートをrubyで書く② 複数ページ取得&xmlマージ編

はじめに

少し前に、はてなブログの投稿予告スクリプトを書いた。

take-she12.hatenablog.com

ここでの課題として、複数ページ取得できていなかったので、今回はその対応をした。draftかどうかは見てないです。

シェルスクリプト

$ cat hatena-yokoku.sh 
#!/bin/sh
# get first page
curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry > output1.xml

# get next page 2 to 4
page=`curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry | grep "link rel=\"next\"" | sed -e 's/.*page=\([0-9]*\).*/\1/'`
curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry?page=${page} > output2.xml
page=`curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry?page=${page} | grep "link rel=\"next\"" | sed -e 's/.*page=\([0-9]*\).*/\1/'`
curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry?page=${page} > output3.xml
page=`curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry?page=${page} | grep "link rel=\"next\"" | sed -e 's/.*page=\([0-9]*\).*/\1/'`
curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry?page=${page} > output4.xml

# merge xml
## remove "feed" closing tag 
grep -v "</feed>" output1.xml > output1-2.xml
## extract only entry section
tail -n +22 output2.xml | grep -v "</feed>" > output2-2.xml
tail -n +22 output3.xml | grep -v "</feed>" > output3-2.xml
tail -n +22 output4.xml | grep -v "</feed>" > output4-2.xml
## merge
cat output2-2.xml >> output1-2.xml
cat output3-2.xml >> output1-2.xml
cat output4-2.xml >> output1-2.xml
## add "feed" closing tag
echo "</feed>" >> output1-2.xml

# rename and change permission
mv output1-2.xml output.xml
chmod 755 /home/take/script/output.xml

# post yokoku-tweet!
ruby /home/take/script/hatena-yokoku.rb

# delete xml file
rm *.xml

いやーゴミみたいなシェル書いてしまいましたね!!!!!!!!!ループぐらい使わんかい!

nextページの取得

そもそも普通にクエリを投げると10記事分しか取得できなくて、?page=<ページ番号>で次のページが取得できるんですが、ありがたいことに1ページ、2ページという風に連番になってません。以下の形で次のページ番号が取得できるので、この数値を抽出するのにsedを使ってます。

<link rel="next" href="https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry?page=1454854713" />

grep "link rel=\"next\"" | sed -e 's/.page=([0-9]).*/\1/'`

対象行をgrepで抽出して、sed -eで変換処理を行う。¥1で抽出結果の1つめを持ってきてます。page=以降の数値を抽出してます。それをpage変数にいれて、クエリを投げてます。

xmlファイルのマージ

はてなブログのentryのGETレスポンスは以下の形で取得できます。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:app="http://www.w3.org/2007/app">

  <link rel="first" href="https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry" />

  
  <link rel="next" href="https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry?page=1454854713" />
  

  <title>ツナワタリマイライフ</title>
  
  <subtitle>日常ネタから技術ネタ、音楽ネタまで何でも書きます。</subtitle>
  
  <link rel="alternate" href="http://take-she12.hatenablog.com/"/>
  <updated>2016-02-11T12:00:00+09:00</updated>
  <author>
    <name>take_she12</name>
  </author>
  <generator uri="http://blog.hatena.ne.jp/" version="省略">Hatena::Blog</generator>
  <id>hatenablog://blog/省略</id>

  
  <entry>
記事に関するあれこれ
 </entry>
(省略)
  <entry>
記事に関するあれこれ
 </entry>

</feed>

この結果がページごとに取得できるとして、entryタグだけ取得してマージしたいわけです。共通部分は冒頭から22行と、最後のfeedの閉じタグですね。

まず最初の取得結果からfeedの閉じタグを除去します。 そのあと2ページ目以降は冒頭の22ページ目以降をtail -n +22で、23行目以降を取得してます。(これははじめて知りました)もちろんfeedの閉じタグも除去。 そしてファイルをマージしたあと最期にfeedの閉じタグをつけて完成と。

xmlで返ってくるんだからxmlで扱えやと自分でも思いますがまずは実現することが大事なので許してあげてください。(笑)

おわりに

とりあえず4ページ取得できてればまぁストックが30記事あるとかにならない限り大丈夫かなと思います。ストック100記事とかになったらちゃんとループで10ページ分取得する、って風に変えます(笑)

rubyのgemのrexmlとnet/http使えばrubyファイルだけでいけるんだろうけどね。。。

まぁこれで月水金の朝に直近3日間の予告ツイートができるようになりました。やりたかったことできたのでうれしい。