1. 程式人生 > >python httplib2與urllib2包的介紹(轉)

python httplib2與urllib2包的介紹(轉)

剛剛發現了一個比urllib2更好用的庫httplib2,可以比較簡單的解決本文遇到的一些問題
http://code.google.com/p/httplib2/

————————————————————

最近用urllib2寫了一個公司內部用的指令碼

這個指令碼要訪問一個webservice,訪問之前先要用https登陸拿到cookie再到另一個地方獲取一個臨時用的id

https登陸,獲取cookie

首先是https登陸,這段很好寫,以前寫過校內網發帖機,輕車熟路,用cookielib的CookieJar加上HTTPCookieProcessor搞定,程式碼如下(其中那個超簡單的lambda hack簡直絕了:



#! /usr/bin/env python
# -*- coding: utf-8 -*-
import urllib, urllib2, sys, cookielib, re, os, json cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
url_login = 'https://xxx.yahoo.com/login/'
body = (('username', '半瓶墨水'),
('password', '密碼'),
('action', 'login'),)

print 'login to get cookies'

opener.open(url_login, urllib.urlencode(body))



處理HTTP 403/500 Exception

但是後面用cookie去拿id的時候,就老是告訴我403錯誤,然後opener就拋異常,想問題想到頭大,後來發現這個服務訪問成功不是返回200,而是403,所以看到403的時候不要管他,直接看body內容就行了,日,不知道為什麼這麼設計。

怎麼辦呢?查了一下urllib2的文件,發現可以繼承一下HTTPCookieProcessor,自己做了一個 NoExceptionCookieProcesser,後來的過程中發現webservice有時候返回400和500的時候body中包含有用的資訊,一併處理了:


#! /usr/bin/env python
# -*- coding: utf-8 -*-
import urllib, urllib2, sys, cookielib, re, os, json
#suppress the 403/400/500 exception and return the body
class NoExceptionCookieProcesser(urllib2.HTTPCookieProcessor):
    def http_error_403(self, req, fp, code, msg, hdrs):
        return fp

    def http_error_400(self, req, fp, code, msg, hdrs):
        return fp

    def http_error_500(self, req, fp, code, msg, hdrs):
        return fp

cj = cookielib.CookieJar()
opener = urllib2.build_opener(NoExceptionCookieProcesser(cj))
url_login = 'https://xxx.yahoo.com/login/'
body = (('username', '半瓶墨水'),
('password', '密碼'),
('action', 'login'),) print 'login to get cookies'
opener.open(url_login, urllib.urlencode(body))



urllib2中用PUT進行請求

然後又發現一個問題,webservice在提交的時候要求用PUT方式,並且只接受json,urllib2預設只支援GET和POST,Google了一下,發現可以建立Request物件,然後更改它的請求方法(get_method)以及header,搞定:

request = urllib2.Request(url_ws, data="blablabla")
request.add_header('Content-Type', 'application/json')
request.add_header('Accept', 'application/json')
request.get_method = lambda: 'PUT'
result = opener.open(request).read().strip()


參考:http://stackoverflow.com/questions/111945/is-there-any-way-to-do-http-put-in-python