Python 3.2 への Facebook-sdk のインストール
はじめに
ある Facebook アカウントを RSS リーダ*1で読みたいなと思ったのでその方法をググってみた。
Facebook は捨て垢(というかそういった概念があるのかも不明)すら作ってないのでよくわからん。ただこの件に関しては該当アカウントの Facebook ID とやらをゲットして
https://www.facebook.com/feeds/page.php?format=rss20&id=[Facebook ID]
を RSS リーダに読ませればいい。Facebook ID の取得方法は
https://graph.facebook.com/[Facebook Username]
にアクセスすれば簡単に見つけられる。
これ自体は大したこと無いが「Python で Facebook ID 拾ってこれるんじゃね?」と思ってしまったのが運の尽き…。
facebook-sdk のインストール
条件
OS : Windows 8.1 (64 bit)
Python : 3.2.5
facebook-sdk : 0.4.0 (pip でインストール)
インストール
1. まずは pip でインストールする。requests は GitHub の install.rst で required だったので インストールした。*2
$ pip install requests $ pip install facebook-sdk
2. 試しに import してみたら次のような Syntax Error が出る。
>>> import facebook Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python32\lib\site-packages\facebook.py", line 222 except urllib2.HTTPError, e: ^ SyntaxError: invalid syntax
とりあえず該当箇所の 222 行付近を調べてみると、
try: data = urllib2.urlopen(req).read() #For Python 3 use this: #except urllib2.HTTPError as e: except urllib2.HTTPError, e: data = e.read() # Facebook sends OAuth errors as 400, and urllib2 # throws an exception, we want a GraphAPIError
とコメントされてた。ふむふむ、facebook.py は Python 2.x 向けなのね。
他にも該当箇所あるし、そもそも urllib2 は Python 3 で変わってる*3し、ちまちま治すのは面倒だな。
3. てなわけで 2to3 で変換する。
$ python c:\Python32\Tools\Scripts\2to3.py -w --no-diffs c:\Python32\lib\site-packages\facebook.py
これで 2to3.py による変換終了。これで import 時のエラーは消える。
4. import はうまくいくものの、まだバグはある。
maintype バグ
facebook-sdk で読み込もうとすると 308 行目をさして
AttributeError: 'HTTPMessage' object has no attribute 'maintype'
となっている。fileInfo は HTTPMessage object だが maintype を取ってくるには get_content_maintype メゾットで拾ってくる必要がある。(参考:
Issue 4773: HTTPMessage not documented and has inconsistent API across Py2/Py3 - Python tracker)
よって 308-310 行目を次のように変える。(旧ソースはコメントアウトした。)
if fileInfo.get_content_maintype() == 'text':#fileInfo.maintype == 'text': response = _parse_json(file.read()) elif fileInfo.get_content_maintype() == 'image':#fileInfo.maintype == 'image':
_parse_json (実態は json.loads) の decode
_parse_json なる謎コマンドは 56 行で
_parse_json = json.loads
と定義されている。はっきり言って見にくい(しわざわざ定義する意味を感じない)のでこの定義をコメントアウトする。その後に _parse_json を json.loads にエディタで一斉置換しておく。
さて、json.loads() の仕様は 19.2. json — JSON エンコーダおよびデコーダ — Python 3.4.1 ドキュメント にある通り。
別に問題ないはずだが facebook-sdk で読み込もうとすると次のエラーが出る。
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python32\lib\site-packages\facebook.py", line 100, in get_object return self.request(id, args) File "C:\Python32\lib\site-packages\facebook.py", line 309, in request response = json.loads(file.read()) File "C:\Python32\lib\json\__init__.py", line 319, in loads return _default_decoder.decode(s) File "C:\Python32\lib\json\decoder.py", line 353, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) TypeError: can't use a string pattern on a bytes-like object
よくわからんが json.loads() の default decoder がうまく機能してないっぽいので decode を指定してしまえばいいと思う。
日本語を含むものも utf-8 ならきれいに読み込めたので
309 行目を
response = json.loads(file.read().decode('utf-8'))#response = json.loads(file.read())
とする。他にも json.loads() は使われているが今のとこエラーを吐かないのでそのままにしておく。
facebook-sdk による facebook ID の取得
さて、やっと facebook-sdk を使える。
インタラクティブシェルから
>>> import facebook >>> gap = facebook.GraphAPI() >>> gob = gap.get_object("Google") >>> print(gob)
とすると Google の facebook アカウントの情報が得られる。
gob は辞書型なので key を指定すればそれだけを表示させられる。
例えば、
>>> gob.keys() # key の確認 >>> print("id : ", gob['id'], "\nusername : ", gob['username'], "\n")
とすれば id と username のみを表示させられる。
参考文献みたいなもの
Facebook Python Library
http://facebook-python-library.docs-library.appspot.com/facebook-python/facebook-python-library.html
Facebook-SDK のインストールから使い方まで。使い方はひとまずこれを見ようかな。
インストールはあまり参考にならなかった。
Developer のサイト。GitHub ではα版が公開されている。
これは pip じゃなくて GitHub からインストールすべきだったか?
みたところ、urllib2 のバグは消えている。maintype は別の方法で回避している。
ただ、json.loads のやつは変な定義式を消したくらいで decode 指定はない。
これで上手くいくのか?それとも俺の環境が悪いのか?
doc/install.rst を見ると Python 2.6/2.7/3.3 推奨とな。これが原因…なのか…?
Lookup any Username on FACEBOOK
http://www.go4expert.com/articles/lookup-username-facebook-t27093/
http://graph.facebook.com/[facebook username]
から情報を取得するスクリプト。まあ一番シンプルだな。
*1:私は Google Reader → Feedly と使っている人間です。
*2:なお、実際は全部終わったあとで気づいてインストールした。requests がなくても問題なく動いたが他の機能で必要なのかな?
*3:参考:20.6. urllib2 — URL を開くための拡張可能なライブラリ — Python 2.7ja1 documentation