페이스북 억세스 토큰을 얻는 것은 트위터에 비해 조금 귀찮습니다.
브라우저를 사용해야 하기 때문입니다~
페이스북 억세스 토큰을 얻어내는 코드에 파이썬 브라우저 모듈인 mechanize 를 붙여보았습니다
# vi: set sw=4 sts=4 expandtab:
import os
import os.path
import json
import urllib2
import urllib
import urlparse
import BaseHTTPServer
import webbrowser
import mechanize
CODE_BEGIN = 'code='
CODE_END = '"'
APP_ID = '페이스북_앱_아이디'
APP_SECRET = '페이스북_앱_시크릿'
ENDPOINT = 'graph.facebook.com'
REDIRECT_URI = '콜백처리_URL'
ACCESS_TOKEN = None
LOCAL_FILE = '.fb_access_token'
STATUS_TEMPLATE = u"{name}\033[0m: {message}"
def get_url(path, args=None):
args = args or {}
if ACCESS_TOKEN:
args['access_token'] = ACCESS_TOKEN
if 'access_token' in args or 'client_secret' in args:
endpoint = "https://"+ENDPOINT
else:
endpoint = "http://"+ENDPOINT
return endpoint+path+'?'+urllib.urlencode(args)
def get(path, args=None):
return urllib2.urlopen(get_url(path, args=args)).read()
class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
global ACCESS_TOKEN
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
code = urlparse.parse_qs(urlparse.urlparse(self.path).query).get('code')
code = code[0] if code else None
if code is None:
self.wfile.write("Sorry, authentication failed.")
sys.exit(1)
response = get('/oauth/access_token', {'client_id':APP_ID,
'redirect_uri':REDIRECT_URI,
'client_secret':APP_SECRET,
'code':code})
ACCESS_TOKEN = urlparse.parse_qs(response)['access_token'][0]
open(LOCAL_FILE,'w').write(ACCESS_TOKEN)
self.wfile.write("You have successfully logged in to facebook. "
"You can close this window now.")
def print_status(item, color=u'\033[1;35m'):
print color+STATUS_TEMPLATE.format(name=item['from']['name'],
message=item['message'].strip())
def main(email, password):
url = get_url('/oauth/authorize',
{'client_id':APP_ID,
'redirect_uri':REDIRECT_URI,
'scope':'read_stream'})
browser = mechanize.Browser()
browser.set_handle_refresh(False)
browser.set_handle_robots(False)
cookies = mechanize.CookieJar()
browser.set_cookiejar(cookies)
response = browser.open(url)
open("response.html", "wb").write(response.get_data())
browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7')]
try:
browser.select_form(predicate=lambda f:"login.php" in f.action and f.method.lower() == "post")
except mechanize.FormNotFoundError:
print "WRONG_LOGIN_PAGE"
return -1
browser.form["email"] = email
browser.form["pass"] = password
response = browser.submit()
responseData = response.read()
relocationPos = responseData.find("window.location.replace")
open("response2.html", "wb").write(responseData)
if relocationPos < 0:
try:
browser.select_form(predicate=lambda f:f.action.endswith("uiserver.php") and f.method.lower() == "post")
except mechanize.FormNotFoundError:
print "RETRY_LOGIN_LATER"
return -2
response = browser.submit(name="grant_clicked")
responseData = response.read()
relocationPos = responseData.find("window.location.replace")
open("response3.html", "wb").write(responseData)
if relocationPos > 0:
tagBeginPos = responseData.find(CODE_BEGIN, relocationPos)
if tagBeginPos > 0:
tagEndPos = responseData.find(CODE_END, tagBeginPos)
code = responseData[tagBeginPos+len(CODE_BEGIN):tagEndPos].decode("unicode-escape")
response = get('/oauth/access_token', {'client_id':APP_ID,
'redirect_uri':REDIRECT_URI,
'client_secret':APP_SECRET,
'code':code})
ACCESS_TOKEN = urlparse.parse_qs(response)['access_token'][0]
open(LOCAL_FILE,'w').write(ACCESS_TOKEN)
print "LOGIN_SUCCESS"
return 0
else:
print "UNKNOWN_REDIRECT"
return -4
else:
print "INVALID_CODE"
return -3
if __name__ == '__main__':
import sys
if len(sys.argv) >= 3:
sys.exit(main(sys.argv[1], sys.argv[2]))
else:
print "USAGE:"
print "\t%s [email] [password]" % os.path.split(sys.argv[0])[1]
UNKNOWN_REDIRECT 는 뭔가 페이스 북이 특수 기능 - 이메일 친구 스캔 하기 - 을 처리하기 위해
로그인 절차와는 상관없는 페이지를 보여주는 경우가 있습니다. 이 때는 진짜 웹 브라우저를 띄워서 처리해주는 수밖에 없을 듯 합니다.
끝 ~(-_-)~


python 을 좋아하는 게임 프로그래머