轉(zhuǎn)自:https://zhuanlan.zhihu.com/p/20410446?refer=xlz-d
作者:xlzd
鏈接:https://zhuanlan.zhihu.com/p/20410446
來源:知乎
著作權(quán)歸作者所有砸讳。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處界牡。
最近有幾個知乎上的朋友私信問到關(guān)于爬蟲爬取數(shù)據(jù)的時候總是出現(xiàn)這樣或者那樣的問題簿寂,這里介紹一個Python HTTP庫: requests。Requests是一個基于Apache2協(xié)議開源的Python HTTP庫宿亡,號稱是“為人類準備的HTTP庫”常遂。
Python中,系統(tǒng)自帶的urllib和urllib2都提供了功能強大的HTTP支持挽荠,但是API接口確實太難用了克胳。requests作為更高一層的封裝,確實在大部分情況下對得起它的slogan——HTTP for Humans圈匆。
發(fā)送請求
廢話少說漠另,先看看requests的簡單使用吧:
In[1]:importrequestsIn[2]:resp=requests.get('http://xlzd.me')In[3]:resp.status_codeOut[3]:200
發(fā)送一個完整的HTTP請求,只需要一句代碼即可跃赚。發(fā)送其它方式的請求同樣如此簡潔:
In[1]:r=requests.post("http://xlzd.me/login",data={"user":"xlzd","pass":"mypassword"})In[2]:r=requests.put("http://xlzd.me/post",data={"title":"article"})In[3]:r=requests.delete("http://xlzd.me/foo")In[4]:r=requests.head("http://xlzd.me/bar")In[5]:r=requests.options("http://xlzd.me/abc")
解析URL中的參數(shù)
在GET請求的時候笆搓,經(jīng)常會有很多查詢參數(shù)接在URL后面,形如http://xlzd.me/query?name=xlzd&&lang=python,在拼接URL的時候常常容易出現(xiàn)拼接錯誤的情況砚作,對此你可以使用如下代碼讓這個過程變得簡潔明了:
In[1]:r=requests.get("http://xlzd.me/query",params={"name":"xlzd","lang":"python"})In[2]:printr.urlOut[2]:http://xlzd.me/query?name=xlzd&&lang=python
如上窘奏,字典中的參數(shù)會被requests自動解析并且正確連接到URL中嘹锁。
響應內(nèi)容
如上的代碼拿到的是一個HTTP response葫录,那么怎樣取出里面的內(nèi)容呢?
In[7]:r=requests.get('http://xlzd.me')In[8]:r.encodingOut[8]:'UTF-8'In[9]:r.headersOut[9]:{'Content-Encoding':'gzip','Transfer-Encoding':'chunked','Vary':'Accept-Encoding','Server':'nginx','Connection':'keep-alive','Date':'Fri, 11 Dec 2015 06:42:31 GMT','Content-Type':'text/html; charset=UTF-8','X-Pingback':'http://xlzd.me/action/xmlrpc'}In[10]:r.cookiesOut[10]:In[11]:r.textOut[11]:u'\n\n\t
requests會自動對響應內(nèi)容編碼领猾,所以就可以通過r.text取出響應文本了米同。對于別等響應內(nèi)容(文件、圖片摔竿、...)面粮,則可以通過r.content取出來。對于json內(nèi)容继低,也可以通過r.json()來取熬苍。
自定義Headers
對于寫爬蟲來講,模擬瀏覽器是發(fā)請求的時候做的最多的事情了袁翁,最常見的模擬瀏覽器無非就是偽裝headers:
In[23]:url='http://xlzd.me'In[24]:headers={'User-Agent':'my custom user agent','Cookie':'haha'}In[25]:requests.get(url,headers=headers)
重定向和超時
requests之所以稱為“HTTP for human”柴底,因為其封裝層次很高,其中一處體現(xiàn)就在:requests會自動處理服務器響應的重定向粱胜。我在做搜狗微信公眾號抓取的時候柄驻,搜狗搜索列表頁面的公眾號文章地址,其實不是微信的地址而需要請求到搜狗到服務器做重定向焙压,而requests的默認處理則是將整個過程全部搞定鸿脓,對此可以這樣:
In[1]:r=requests.get('http://xlzd.me',allow_redirects=False)
allow_redirects參數(shù)為False則表示不會主動重定向。
另外涯曲,有時候?qū)Ψ骄W(wǎng)站的響應時間太長了野哭,我們希望在指定時間內(nèi)完事,或者直接停止這個請求幻件,這時候的做法是:
In[1]:r=requests.get('http://xlzd.me',timeout=3)
timeout表示這次請求最長我最長只等待多少秒拨黔,
代理
為requests套上一層代理的做法也非常簡單:
import requestsproxies = {? "http": "http://192.168.31.1:3128",? "https": "http://10.10.1.10:1080",}requests.get("http://xlzd.me", proxies=proxies)
會話對象
服務器端通過session來區(qū)分不同的用戶請求(瀏覽器會話),requests的會話對象是用來模擬這樣的操作的傲武,比如可以跨請求保持某些參數(shù):就像你在訪問微博的時候蓉驹,不需要每次翻頁都重新登錄一次。
session=requests.Session()session.post('http://xlzd.me/login',data={'user':'xlzd','pass':'mypassword'})# 登錄成功則可以發(fā)布文章了session.put('http://xlzd.me/new',data={'title':'title of article','data':'content'})
另外揪利,requests.Session對象也可以直接使用上面的所有方法喲态兴。
小結(jié)
requests彌補了Python自帶的urllib和urllib2的不好使用,通過使用requests疟位,可以更方便瞻润、更直觀的處理網(wǎng)絡請求相關(guān)的代碼,在網(wǎng)絡爬蟲的編寫過程中更加得心應手。