Rubyによるアメブロ『いいね』自動化スクリプト(3) 「いいね」のターゲット設定(その1)

前回までで、「いいね」をつけるスクリプトが出来たので、今回はそのターゲットの抽出方法。

依頼者の要望は、
「自分のブログ記事についた「いいね」をお返しする」
と言うこと。
なので、自分のブログ記事についた「いいね」を取得する方法を考える。

「いいね」のデータを取得するには大きく3つの方法がある。
(1)記事のいいねのリンクから、その記事についた「いいね」を新しい順に見ることができる。
(2)ログインした状態の「いいね」履歴で
(2)-1 記事毎についた「いいね」の履歴を見ることができる。記事は記事の日付時刻順ではなく、「いいね」がついた時刻の新しい順に整列される。だから大昔の記事でも「いいね」が新しくつけば、データの先頭になる。
(2)-2 「いいね」をつけてくれたユーザ毎のデータを取得できる。この時もユーザの並びは「いいね」をつけた時刻の降順。新しく「いいね」をつけてくれたユーザほど新しく表示される。

これらのいずれの場合でも、データはhtmlではなくjsonの形式で送られて来る。一回のリクエストではデータ10件のみが送られ、全件のデータを得ることは出来ない。
この一度に全件データが得られないとこら辺が、自動処理が面倒になる所なのだが、自動処理はサービス供給側の意図から外れているし、全件データ送信はトラフィックとサーバーの負荷がやたらに増えて仕方ないので妥当な処理方法という所か。(そもそも今回のシステム変更の目的が、トラフィックとサーバー負荷の低減だったのではないかという気もする)

依頼者の要求仕様のお返しとしての「いいね」をつける相手に合致するのは、単純に「いいね」時刻順でデータを得られる(3)の方法。
この(3)の場合に送られてくるデータの内容を、もう少し詳しく見る。

データを得るためのリンクを押すと以下のリクエストが送られる。

GET /api/iine_history_user.json
  ?ts=1389608323904&callback=iineHistoryUserCallback&_=1389608323908 HTTP/1.1
Host	iine.blog.ameba.jp
User-Agent	Mozilla/5.0 (Windows NT 6.0; Win64; x64; rv:29.0) Gecko/20100101 Firefox/29.0
Referer	http://blog.ameba.jp/ucs/iine/list.html

ここで"ts"、および"_"というデータは、リクエストが発生した日時をGMTの1970年1月1日午前0時からの経過秒数でシリアライズされたモノ。
(どちらか片方だけで良い様な気がするのだが…)
リクエストの中には、自分のブログを表わす情報が全く入っていない。おそらく、そこら辺はクッキーで処理されているのではないかと想像しているのだが、良く分らない。


以下が送られてくるjsonのデータ例。

iineHistoryUserCallback({
    "successFlg": true,
    "lastUpdMillis": 1389364094206,
    "lastFlg": false,
    "userList": [{//1件目のデータ
        "validFlg": true,
        "amebaId": "*****",
        "blogTitle": "************",
        "iineCount": 1,
        "profile": {
            "nickname": "***",
            "profileImage": {
                "url": "http://stat.profile.ameba.jp/profile_images/******/**.jpg",
                "height": 2048,
                "width": 1536
            }
        }
    }, 

   // ...途中省略...

       {//10件目のデータ
        "validFlg": true,
        "amebaId": "****",
        "blogTitle": "*******",
        "iineCount": 4,
        "profile": {
            "nickname": "****",
            "profileImage": {
                "url": "http://stat.profile.ameba.jp/profile_images/**************/**/****.jpg",
                "height": 236,
                "width": 243
            }
        }
    }]
});


送られてくるデータは、整形されていないベタのテキストデータだが、http://jsbeautifier.org/で整形。
内容を見ると
"lastUpdMillis"という項目に 1389364094206という数値が入っている。(この項目については後述)
"lastFlg"という項目に falseが入っていて、リストがまだ続く事がわかる。
"userList"の項目は、「いいね」をつけてくれた相手のid、相手のブログタイトル、「いいね」をつけてくれた回数、相手のプロファイルデータが10件分入っている。

"lastUpdMillis"という項目は、どうもこの10件の次、つまり11件目以降の「いいね」をつけてくれたユーザーのデータをリクエストする時に必要なデータで、10件目がついた日時データの様な気がする。(もしかしたらサーバー側が11件目の日時データを返して来ているのかも知れないが…)
でこの次のデータをリクエストする場合には、

GET /api/iine_history_user.json?updMillis=1389364094206
    &ts=1389614304062&callback=iineHistoryUserCallback&_=1389614304064 HTTP/1.1

と、"lastUpdMillis"のデータを追加して送る。
このリクエストを"lastUpdMillis"の値が自分が望む日時になるまで、或いは"lastFlg"がTRUEになるまで繰り返して、データを得れば良い。。

Rubyによるアメブロ『いいね』自動化スクリプト(2) 『いいね』をつけるスクリプト

1回目で説明した「いいね」をつける仕組みをrubyで実装する。
まずはアメブロにログインしてクッキーを入手するスクリプト

require 'digest/md5'
require 'net/http'

Net::HTTP.version_1_2 

cookie = Hash.new

#Set-Cookie
def set_cookie_from_res(res,cook)
  if not res.get_fields('Set-cookie') == nil
    res.get_fields('Set-cookie').each{|str|
      k,v = str[0...str.index(';')].split('=')
      cook[k] = v
    }
  end
end

def cookie_str(cook)
cook.map{|k,v|
      "#{k}=#{v}"
    }.join(';')
end

#Program Start
print "Please input your BlogID :"
blog_id = gets.chop

print "Please input your password :"
blog_pwd = gets.chop

print "Please input iineNo :"
iine_no = gets.chop.to_i


#ログインしてクッキーを入手
http = Net::HTTP.new("www.ameba.jp",80)

path = '/'
req=Net::HTTP::Get.new(path)
req['Connection'] = 'Keep-Alive'
req['Cookie'] = cookie_str(cookie)
req['User-Agent']
     = 'Mozilla/5.0 (Windows NT 6.0; Win64; x64; rv:29.0) Gecko/20100101 Firefox/29.0'
http.start
response = http.request(req)

set_cookie_from_res(response,cookie)
path = '/login.do'
post_data = 'amebaId=' + blog_id
          + '&password=' + Digest::MD5.hexdigest(blog_pwd) + '&Submit.x=0&Submit.y=0'
req = Net::HTTP::Post.new(path)
req['Connection'] = 'Keep-Alive'
req['Cookie'] = cookie_str(cookie)
req['User-Agent'] 
     = 'Mozilla/5.0 (Windows NT 6.0; Win64; x64; rv:29.0) Gecko/20100101 Firefox/29.0'
response = http.request(req,post_data)
if response.code == '302'
  set_cookie_from_res(response,cookie)
  #ここに「いいね」をつけるスクリプトを書く

else
  print "Wrong ID or wrong pathword!!"
end

このスクリプトは前のペタ貼りのスクリプトと同じ。
ユーザエージェントの設定は、素直にrubyのままだとサーバー側で弾かれるかも知れないのでFireFoxを詐称している。(アメブロさん、ごめんなさい)

上記のスクリプトの『#ここに「いいね」をつけるスクリプトを書く』の部分に、コードを入れる。

まずは、準備として、
(1)「いいね」をつけたいアメブロのidが入っている配列
(2)サーバーから受け取った文字列からデータを抽出するための正規表現
を定義する。

iine_list = Array.new#「いいね」つけたいidを入れる配列

iine_entry_url = Regexp.new("/web/display_iine.html\\?receiveAmebaId=[A-Za-z0-9\-]
                            +&entryId=[0-9]+&from=entry&device=pc")#いいねボタン検出
iine_receiveAmebaId = Regexp.new('name="receiveAmebaId" value="[A-Za-z0-9\\-]+"')
iine_entryId = Regexp.new('name="entryId" value="[0-9]+"')
iine_token = Regexp.new('name="token" value="[a-z0-9]+"')

前回の「いいね」のしくみで調べたように、「いいね」の管理は一般的のアメブロの記事と別サーバーなので、スクリプトではhttp2を用意して、「いいね」のサーバーを割り当てる。

「いいね」をつけるスクリプトのコードは以下の通り

  http2 = Net::HTTP.new("iine.blog.ameba.jp",80)
  iine_list.each do |line|
  begin  
    print "Checking ", line ," blog... "
    target_blog_path = '/' + line + '/'
    
    
    response = http.get(target_blog_path,header)
    set_cookie_from_res(response,cookie)
    if response.code == '404'
      print "Can't find target blog."
    else
      iine_entry = iine_entry_url.match(response.body).to_s
      
      path = iine_entry+' HTTP/1.1'
      header['Referer'] = 'http://ameblo.jp'+target_blog_path

      response = http2.get(path,header)
      if response.body =~  /alreadyIineFlg:true/
        print "Already iine"
      else
        receiveAmebaId = iine_receiveAmebaId.match(response.body).to_s.sub
                                           (/name="receiveAmebaId" value=/,'').tr('"','')
        if not receiveAmebaId == ''
          entryId = iine_entryId.match(response.body).to_s.sub
                                                  (/name="entryId" value=/,'').tr('"','')
          token = iine_token.match(response.body).to_s.sub
                                                  (/name="token" value=/,'').tr('"','')
          postdata = 'receiveAmebaId=' + receiveAmebaId 
                   + '&entryId=' + entryId + '&token=' + token + '&from=entry&device=pc'
          print "Sending iine..."
        
          path = '/web/exec_iine.html HTTP/1.1'
          header['Referer'] 
         = 'http://iine.blog.ameba.jp/web/display_iine.html?receiveAmebaId=' + receiveAmebaId
         + '&entryId=' + entryId + '&from=entry&device=pc'

          response = http2.post(path,postdata,header)
          print "OK"
          
        else
          print "No iine_entry in this blog."
        end
      end
    end
    
    rescue Timeout::Error
      print "Timeout!!"
    rescue Errno::	ECONNRESET
      print "Econn reset!!"
    ensure
      print "\n"
    end
  end
  


さて、問題はiine_listの中に入れるアメブロのid。
ターゲットになるidをどうやって取得するのか…
次回は、その取得方法について書く。

Rubyによるアメブロ『いいね』自動化スクリプト(1) 『いいね』のしくみ

アメブロが11/20にシステム変更を実施した。
『ペタ』の代わりにフェイスブックもどきの『いいね』というボタンを押すしくみになった。
(アメブロの中には、フェイスブックの「いいね」ボタンもあるから話がややこしい…)
運営側がどういう意図でシステムの変更を行ったのかは判らないが、スクリプトを書いて『ペタ』貼りを自動化していた利用者としては、今回の『いいね』も自動化したくなる。

ペタの自動化スクリプト製作依頼のあった件の知り合いから、今度は『いいね』の自動化スクリプト製作依頼が来る。

ペタの時同様に、そうやって無駄にネットワークのトラフィックを増やして虚勢を張らなくても良いだろうと言ったのだが、当人にはそういう事がとても大事な様で、どうしてもと頼み込まれた。

と言うわけで、この『いいね』を自動化するスクリプトを作成する。

FireFoxのアドインHttpfoxを使って、『いいね』ボタンの表示、ボタンを押した時にブラウザとサーバーの間でどんなやりとりをしているのかを調べる。

「いいね」ボタンの表示

「いいね」ボタンHTMLの下記の様に、インラインフレームを利用して読み込まれる。

<iframe src="http://iine.blog.ameba.jp/web/display_iine.html?
receiveAmebaId=****(ブログid)
&entryId=**********(ブログ記事id 11桁の数値)
&from=entry&device=pc" name="iine" 
class="iineBtnIframe" 
allowtransparency="true" 
frameborder="0" height="34" width="100%">いいね!</iframe>

「いいね」ボタンの詳細データを入手

上のアドレスからデータをGETして、「いいね」ボタンの詳細データを入手する。

Host	iine.blog.ameba.jp
GET /web/display_iine.html?
receiveAmebaId=****
&entryId=***********
&from=entry
&device=pc 
HTTP/1.1

この時、大事なのは、
(1)リクエストヘッダーのRefererに"http://ameblo.jp/****/entry-***********.html"を入れておく事。
これを入れておかないと、データが帰ってこない。自動化スクリプト対策(?)でサーバー側でGETリクエストとリクエストヘッダーのRefererをチェックしているのだろうと考えられる。
(2)予めログインしてクッキーを入手、一緒に送信する事。
クッキーでSession-id等をサーバーに送らないと、サーバー側では誰が「いいね」をしようとしているのか判らない。(ログインとクッキーについては過去記事参照)


このリクエストの結果、下記のHTMLが得られる。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<link media="screen,print" rel="stylesheet" 
href="http://stat.ameba.jp/blog/css/user/blogIineBtn.1.000.css">
</head>

<body>
<div id="iineBtnFrame">
<form action="http://iine.blog.ameba.jp/web/exec_iine.html" method="post" id="iineForm">
<input type="hidden" name="receiveAmebaId" value="****" id="receiveAmebaId"> 
<--****はブログのid -->
<input type="hidden" name="entryId" value="**********" id="entryId"> 
<-- 記事のid 11桁の数字 -->
<input type="hidden" name="token" value="********************************"> 
<--トークン:数字とアルファベット小文字32文字の組み合わせ-->
<input type="hidden" name="from" value="entry">
<input type="hidden" name="device" value="pc">
<div id="iineBtnContent">
<p id="iineBtn" class="alreadyIine iine"><span>いいね!</span></p>
<p id="iineBtnerror"><span>いいね!</span></p>
<p id="iineCount" class="">
<span class="iineCountContent">
<span id="connected"></span>
<span id="disconnected">4</span>

</span>
<span class="iineCountFrame"></span>
</p>
</div>
</form>
</div>

<script src="http://stat.ameba.jp/blog/js/user/iineBtn.js"></script>
<script>
new Amb.IineBtnAmb.PcBlog({
setting:{
loginFlg:true,
alreadyIineFlg:false,
iineEntryTotalCount:4,
receiveAmebaId:'****',
eid:'***********',
from:'entry',
blogDomain:'http://blog.ameba.jp',
iineDomain:'http://iine.blog.ameba.jp'
}
});
</script>
</body>
</html>

を得られる。要点は
(1)32桁のトーク

<input type="hidden" name="token" value="********************************">

(2)javascriptの中に記述されている

alreadyIineFlg:false

の部分。
トークンは、良いねボタンを押した時にサーバーに送るpostの中に含める必要がある。
'alreadyIineFlg'は、その記事の「いいね」をサーバに送ってなければ'false'、既に送っていれば'true'になる。「いいね」は、既に「いいね」を送った記事に対して、再度postを送信した場合には「いいね」が取り消しになる仕組み。粗っぽい自動化スクリプトを作って、この'alreadyIineFlg'を確認せずに、重複してpostを送った場合には、せっかく過去につけた「いいね」が取り消しになってしまう。

記事に「いいね」をつける

記事に「いいね」をつけるためには、上記で得られたサーバーに下記の様にデータをPOSTする。
サーバーとポスト先のパスは

Host iine.blog.ameba.jp
POST /web/exec_iine.html HTTP/1.1

ここでもヘッダーにRefererをつけるのを忘れてはいけない

Referer	http://iine.blog.ameba.jp/web/display_iine.html?
receiveAmebaId=****&entryId=***********&from=entry&device=pc

POSTするデータは以下の通り

receiveAmebaId	****
entryId	***********
token	********************************
from	entry
device	pc


以上の一連のやりとりによって、目標の記事に「いいね」をつける事ができる。

ライブラリ

Delphiから長く離れていたのと、元々VCLの理解が浅いので、Delphiの勘を取り戻すのに四苦八苦している。

サンデープログラマがプログラムを組む場合、構想(アーキテクチャ)に費やす時間は短い。どちらかと言うと、実装(インプリメント)に時間がかかる。

そりゃそうだ。

サンデープログラマの場合、プログラムをいじり始めた時点で、構想部分は日々の生活の中で頭の中に十分にできあがっている。売れるか否かとか心配する必要はないし、構想に対して注文や文句をつける上司もいない。僕の様な、ソフトウェアを生業としていないサンデープログラマが苦労するのは、構想を如何に実現するかの実装部分だ。30年前ならは、データ構造とアルゴリズムを決めて、ゴリゴリとプログラムを組めば良かった。今でも、スクリプトとかはそう言う組み方だ。
しかし、GUIとかマルチメディアが入ってきて、プログラムを対話的(イベントドリブン)に扱わないといけなくなってから、一気にハードルが上がった。OSが提供するそういう機能をラップするために、各開発言語/環境でライブラリが提供され、ちょっと気の利いたソフトを作ろうと思ったら、そのライブラリを誤魔化しながらでも使う程度には理解する必要が出てきた。ボーランド系の開発環境ならOWL、VCL、CLX…、そして今はWindowsMac/iOSまでクロスで開発できるFireMonkeyなんていうのまである。

本当はそのクロスプラットフォームのFireMonkey辺りを勉強し直せば良いのかも知れないのだけど、PC・スマホタブレット・携帯プレーヤーまで含め未だにアップル製品とは縁がない生活。それなら慣れ親しんだWindows用のVCLで良いか…というのが現在の判断。まぁ、実際はタブレットスマホと縁がないから、タッチパネルでの操作体系が分からないだけ…

と言う訳で、ここ暫くはこのブログ、VCLのお勉強とメモが続くだろう。

しかし、こうしたライブラリの内容を説明した日本語の資料が少ない。
10年ほど前に出たDelphiの文献、特に難しそうなのを、少し高いなぁと思いながら当時買っておいて良かったなぁ…と思っている。
Marco Cantuの本とか、オライリーから出た山猫が表紙の本、中村拓男『Delphi コンポーネント設計&開発完全解説』、堀越一雄『Delphi オブジェクト指向プログラミング』とかね。

C++とかで開発されている人はどうしているのだろう?
使ってるライブラリの資料は手に入ってるのかしら

Rubyによるアメブロのペタ貼り自動化スクリプト(16) まとめ

いささか不具合があるものの、一旦、改善したスクリプトをココに貼って、一区切り。
クライアントからは、『Androidスマートフォンから同様の事が出来る様にしてくれ』というワガママな依頼が来ている。
AndroidJavaのサブセットだから、アルゴリズムが決まっていれば、Rubyでなくても簡単にできそうな気がするけれど、僕自身がAndroidの実行環境を持っていないので、いささか敷居が高い。
ボチボチとJavaの復習と、Androidの勉強をしようかと考えている所。

以下、暫定の最終コード

require 'csv'
require 'digest/md5'
require 'net/http'

Net::HTTP.version_1_2  #おまじない

cookie = Hash.new

#Set-Cookie→クッキーの設定
def set_cookie_from_res(res,cook)
res.get_fields('Set-cookie').each{|str|
  k,v = str[0...str.index(';')].split('=')
  cook[k] = v
}
end

def cookie_str(cook)
cook.map{|k,v|
      "#{k}=#{v}"
    }.join(';')
end

list = Array.new
not_list = Array.new

ameba_url = Regexp.new("http:\/\/ameblo.jp\/([A-Za-z0-9]*)\/")
peta_url = Regexp.new("(?-mix:\\/p\\/addPetaComplete.do(?:\\?(?:[;\\/?:@&=+$,A-Za-z0-9\\-_.!~*'()]|%[0-9a-fA-F][0-9a-fA-F])*))")
peta_entry = Regexp.new("/p/addPeta\\.do\\?targetAmebaId=[A-Za-z0-9\\-]+&service=blog_e&key=[0-9]+&sig=[a-z0-9]+")
amember_entry = Regexp.new("secret.ameba.jp/[A-Za-z0-9\\-]+/amemberentry-[0-9]+.html")


print "Please input your BlogID :"
blog_id = gets.chop
print "Please input your password :"
blog_pwd = gets.chop

#まずwww.ameba.jp/に接続してセッションIDを入手する
http = Net::HTTP.new("www.ameba.jp",80)
path = '/'
req=Net::HTTP::Get.new(path)
req['Connection'] = 'Keep-Alive'
req['Cookie'] = cookie_str(cookie)
http.start
response = http.request(req)
set_cookie_from_res(response,cookie)#入手したクッキーからセッションID等をハッシュに設定する
#ID、パスワードを送信して、ログインする
path = '/login.do'
post_data = 'amebaId=' + blog_id + '&password=' + Digest::MD5.hexdigest(blog_pwd) + '&Submit.x=0&Submit.y=0'
req = Net::HTTP::Post.new(path)
req['Connection'] = 'Keep-Alive'
req['Cookie'] = cookie_str(cookie)
response = http.request(req,post_data)
if response.code == '302'
  set_cookie_from_res(response,cookie)#入手したクッキーからpetaに必要なクッキーをハッシュに設定する

  #設定されたペタターゲットファイルを読み込む
  print "Reading Target textfile...\n"
  File.open("peta_target.txt").each do |file|
    file.each_line do |line|
      list.push(line.chomp!)
    end
  end

  #ペタをつけないブログのリストを読み込む
  print"Reading NG Blogs datafile...\n"
  File.open("peta_not_list.txt").each do |file|
    file.each_line do |line|
      not_list.push(line.chomp!)
    end
  end
  
  #自分のブログについたペタを確認。ペタ返しのためのブログurlをリストに追加する。
  print "Reading Recieved Petadata...\n"
  for i in 1..25
    res = Net::HTTP.get('peta.ameba.jp','/p/addPeta.do?petaId=&targetAmebaId='+blog_id+'&pageNo='+i.to_s)
    res.to_s.scan(ameba_url) do |a|
      list.push(a[0])
    end
  end

  #自分のつけたい分野のランキングを確認。例)本、読書ランキング上位のブログ
  for i in 1..10
    res = Net::HTTP.get('ranking.ameba.jp','/genre/detail?genreCode=book&page='+i.to_s)
    res.to_s.scan(ameba_url) do |a|
      list.push(a[0])
    end
  end

  #この後に更に自分のつけたい分野のランキングがあるならば上記を同様に繰り返すを確認

  list.delete(blog_id)#自分のブログを外す
  list.delete("famousblog")#人気ブログへのリンクを外す
  list.delete("content")#プレミアムブログへのリンクを外す
  list1 = list.uniq
  list1 = list1 - not_list#ペタをつけない設定のブログを外す

  #ログデータのlogへの読み込み
  log = Array.new
  log = CSV.readlines('logdata.csv')


  #各ペタページにアクセスしてペタ貼りをする
  http3 = Net::HTTP.new('peta.ameba.jp',80)
  http3.start
  header = Hash::new
  header['Connection'] = 'Keep-Alive'
  header['Cookie'] = cookie_str(cookie)
  g = 0
  ng = 0
  nup = 0

  list1.each do |line|
    print "Checking ", line ," blog... "
    #Get peta_entry url
    response = Net::HTTP.get('ameblo.jp','/'+line+'/')
    if peta_blog_e_get = peta_entry.match(response)
      entry_point = peta_blog_e_get.begin(0)
      peta_e_log = peta_blog_e_get.to_s
      #serchi Amenber entry
      #if find amenber entry link, check position between peta_link
      if (amember_e_get = amember_entry.match(response)) and (entry_point > amember_e_get.begin(0))
        amember_path = amember_e_get.to_s
        amember_path.sub!(/secret.ameba.jp/,'')
        http2 = Net::HTTP.new('secret.ameba.jp')
        http2.start
        amember_response = http2.get(amember_path, header)
        http2.finish
      
        if peta_entry.match(amember_response.body)
          peta_e_path = peta_blog_e_get.to_s
          posting_text = "from blog entry(amenber).."
        else
          peta_e_path = '/p/addPeta.do?targetAmebaId='+line+'&service=profile'
          posting_text = "from Profile(not amenber)..."
        end
      else
        peta_e_path = peta_blog_e_get.to_s
        posting_text = "from blog entry..."
      end
      if (log.assoc(line) == nil) or (log.assoc(line)[1] != peta_e_log) then
        print "Posting Peta " + posting_text
        response = http3.get(peta_e_path,header)
        
        if petaIDget =peta_url.match(response.body)
          peta_path =  petaIDget.to_s
          response = http3.get(peta_path,header)
          if log.assoc(line) == nil then
            log << [line, peta_e_log]
          else
            log.assoc(line)[1] = peta_e_log
          end
          print "OK"
          g += 1
        else
          print "NG"
          ng += 1
        end
      else
        print "not updated."
        nup += 1
      end
    else
      print "can't find peta link."
    end
    print "\n"
  end
  http3.finish
  
  print "\n"
  print "Number of peta target blogs: ", list1.length, "\n"
  print "Post peta successed: ", g, "\n"
  print "Post peta faild: ",ng, "\n"
  print "Not updated blogs: ", nup, "\n"
  
  #ログデータの書き込み
  print "\n"
  print "Saving log data. Wait a moment..."
  CSV.open("logdata.csv", 'w') do |writer|
  print "finish!\n"
    log.each do |line|
    writer << line
    end
  end

else
  print "Wrong ID or wrong pathword!!"
end
http.finish

Rubyによるアメブロのペタ貼り自動化スクリプト(15) アメンバー限定記事の処理の不具合

前回までにアメンバー限定記事の処理コードを書いた。
のだけれども、どうもまだ不具合がある。

不具合なのは以下の部分

     #アメンバー申請へのリンクを探す
   #アメンバー申請へのリンクが見つかった場合には、ペタへのリンクとどちらが先か確認する
		if (amember_e_get = amember_entry.match(response)) and (entry_point >amember_e_get.begin(0))
			amember_path = amember_e_get.to_s
			amember_path.sub!(/secret.ameba.jp/,'')
			http2 = Net::HTTP.new('secret.ameba.jp')
			http2.start
			amember_response = http2.get(amember_path, header)
			http2.finish
			
			if peta_entry.match(amember_response.body)
				peta_e_path = peta_blog_e_get.to_s
				posting_text = "from blog entry(amenber).."
			else
				peta_e_path = '/p/addPeta.do?targetAmebaId='+line+'&service=profile'
				posting_text = "from Profile(not amenber)..."
			end
		else
			peta_e_path = peta_blog_e_get.to_s
			posting_text = "from blog entry..."
		end

ペタへのリンクとアメンバー申請のリンクの前後関係を調べ、アメンバー申請のリンクが先の場合にはその記事をアメンバー限定記事の扱いにしたのだが、コレが不具合だった。
アメブロでは、画像付き記事とかの場合に記事の末尾ペタリンクの前に3件の『最近の画像付き記事』とかのリンク画像が付加されている。
その過去記事の中にアメンバー限定記事があった場合、上記スクリプトでは一般記事をアメンバー限定記事と誤判断してしまう。

横着なスクリプトではなかなか上手くいかないモノだ。