mechanizeはWeb上の操作を自動化してくれる便利なPythonのライブラリ。Pure Pythonなのでいろんなところで動くよ。PerlのWWW::Mechanizeにinspireされて作られた。RubyにもMechanizeという同種のライブラリがある。Perl偉い!
「Web上の操作を自動化する」っていうのは,例えばどこかのサービスにログインしてあれこれするとか,そういったことをプログラマブルに行える,ということ。フォームの操作などもオブジェクトを使って実行できるのでとても手軽。Webアプリの開発などではテストに使われたりするんだけど,結局僕がなにをしたかったかというと,朝嫁が出かける準備をしている間にtumblrでqueueした尻画像とか尻画像,あと尻画像なんかを自動的にpostして欲しいってことです。tumblrのqueue,たまに動かなくなるんです。最初はtumblr APIを使ってやろうかと思ったけど,queueの部分がよく動かないのです。
ふにゃふにゃ,って感じで30分くらいでスクリプトを書いてみました。このスクリプトを定期的に動かせば,tumblrのqueueが美味く動かない時にだけ,スクリプトが自動的にqueueに貯めた投稿をpostしてくれる。グレイト。Cookie Jarと組み合わせると,認証時に発行されるセッション用クッキーなんかも自動的に保存してくれるので超便利。
#!/usr/bin/env python import mechanize import cookielib import re import time def make_browser(): """ A function to make browser object. """ brwser = mechanize.Browser() # Making Cookie Jar and bind it to browser cj = cookielib.LWPCookieJar() browser.set_cookiejar(cj) # Setting browser options browser.set_handle_equiv(True) browser.set_handle_redirect(True) browser.set_handle_referer(True) browser.set_handle_robots(False) browser.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) browser.addheaders = [('User-agent', ('Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3)' ' Gecko/20041001 Firefox/0.10.1'))] return browser def time2minutes(s): """ A function to obtain minutes of the day from given string. """ hstr, rest = s.split(':') h = int(hstr) m = int(re.sub(r'am|pm', '', rest)) if rest.endswith('pm'): h += 12; return h*60+m if __name__ = '__main__': browser = make_browser() browser.open('https://www.tumblr.com/login') browser.select_form(nr=0) # Login browser.form['user[email]'] = '***************' browser.form['user[password]'] = '*************' browser.submit() # Go to queue browser.open('http://tumblr.com/queue') body = browser.response().read() # Getting a part containing time to be published ptpart = re.findall(r"""var publish_on_times = \[(.+?)];""", body, re.M | re.S) ptpart = ''.join(ptpart) pubtimes = re.findall(r""".+?'(.+?)'.+?'(.+?)'""", ptpart, re.M | re.S) now = time2minutes(time.strftime('%H:%M', time.localtime(time.time()))) for cnt, (wd, pt) in enumerate(pubtimes): pm = time2minutes(pt) if pm < now: try: browser.select_form(nr=2+cnt*2) browser.submit() except: pass