爬蟲必備——requests
最近有幾個知乎上的朋友私信問到關於爬蟲爬取數據的時候總是出現這樣或者那樣的問題,這裡介紹一個Python HTTP庫: requests。Requests是一個基於Apache2協議開源的Python HTTP庫,號稱是「為人類準備的HTTP庫」。
Python中,系統自帶的urllib和urllib2都提供了功能強大的HTTP支持,但是API介面確實太難用了。requests作為更高一層的封裝,確實在大部分情況下對得起它的slogan——HTTP for Humans。
發送請求
廢話少說,先看看requests的簡單使用吧:
In [1]: import requests nIn [2]: resp = requests.get(http://xlzd.me)nnIn [3]: resp.status_codenOut[3]: 200n
發送一個完整的HTTP請求,只需要一句代碼即可。發送其它方式的請求同樣如此簡潔:
In [1]: r = requests.post("http://xlzd.me/login", data = {"user":"xlzd", "pass": "mypassword"})nIn [2]: r = requests.put("http://xlzd.me/post", data = {"title":"article"})nIn [3]: r = requests.delete("http://xlzd.me/foo")nIn [4]: r = requests.head("http://xlzd.me/bar")nIn [5]: r = requests.options("http://xlzd.me/abc")n
解析URL中的參數
在GET請求的時候,經常會有很多查詢參數接在URL後面,形如http://xlzd.me/query?name=xlzd&&lang=python,在拼接URL的時候常常容易出現拼接錯誤的情況,對此你可以使用如下代碼讓這個過程變得簡潔明了:
In [1]: r = requests.get("http://xlzd.me/query", params={"name":"xlzd", "lang": "python"})nnIn [2]: print r.urlnOut[2]: http://xlzd.me/query?name=xlzd&&lang=pythonn
如上,字典中的參數會被requests自動解析並且正確連接到URL中。
響應內容
如上的代碼拿到的是一個HTTP response,那麼怎樣取出裡面的內容呢?
In [7]: r = requests.get(http://xlzd.me)nnIn [8]: r.encodingnOut[8]: UTF-8nnIn [9]: r.headersnOut[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}nnIn [10]: r.cookiesnOut[10]: <RequestsCookieJar[]>nnIn [11]: r.textnOut[11]: u<!DOCTYPE HTML>n<html lang="zh-CN">nt<hea......n
requests會自動對響應內容編碼,所以就可以通過r.text取出響應文本了。對於別等響應內容(文件、圖片、...),則可以通過r.content取出來。對於json內容,也可以通過r.json()來取。
自定義Headers
對於寫爬蟲來講,模擬瀏覽器是發請求的時候做的最多的事情了,最常見的模擬瀏覽器無非就是偽裝headers:
In [23]: url = http://xlzd.mennIn [24]: headers = {User-Agent: my custom user agent, Cookie: haha}nnIn [25]: requests.get(url, headers=headers)n
重定向和超時
requests之所以稱為「HTTP for human」,因為其封裝層次很高,其中一處體現就在:requests會自動處理伺服器響應的重定向。我在做搜狗微信公眾號抓取的時候,搜狗搜索列表頁面的公眾號文章地址,其實不是微信的地址而需要請求到搜狗到伺服器做重定向,而requests的默認處理則是將整個過程全部搞定,對此可以這樣:
In [1]: r = requests.get(http://xlzd.me, allow_redirects=False)n
allow_redirects參數為False則表示不會主動重定向。
另外,有時候對方網站的響應時間太長了,我們希望在指定時間內完事,或者直接停止這個請求,這時候的做法是:
In [1]: r = requests.get(http://xlzd.me, timeout=3)n
timeout表示這次請求最長我最長只等待多少秒,
代理
為requests套上一層代理的做法也非常簡單:
import requestsnnproxies = {n "http": "http://192.168.31.1:3128",n "https": "http://10.10.1.10:1080",n}nnrequests.get("http://xlzd.me", proxies=proxies)n
會話對象
伺服器端通過session來區分不同的用戶請求(瀏覽器會話),requests的會話對象是用來模擬這樣的操作的,比如可以跨請求保持某些參數:就像你在訪問微博的時候,不需要每次翻頁都重新登錄一次。
session = requests.Session()nsession.post(http://xlzd.me/login, data={user: xlzd, pass: mypassword})n# 登錄成功則可以發布文章了nsession.put(http://xlzd.me/new, data={title: title of article, data: content})n
另外,requests.Session對象也可以直接使用上面的所有方法喲。
小結
requests彌補了Python自帶的urllib和urllib2的不好使用,通過使用requests,可以更方便、更直觀的處理網路請求相關的代碼,在網路爬蟲的編寫過程中更加得心應手。
推薦閱讀:
TAG:xlzd杂谈 |