小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

coder-pig發表於2018-02-04

一句話概括本文

本節講解Requests庫的常見使用,以及一個實戰專案: 扒取某一篇微信文章裡所有的圖片,視訊,音訊 尤其在扒取視訊和音訊的時候思考非常好玩~

配圖:順道給涼了的大A站上香:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫


引言

剛學爬蟲沒多久的時候就知道requests這個HTTP庫了,不過 因為自己覺得學習新的庫需要一定的時間成本,而且自帶的 urllib寫寫小爬蟲夠用,就沒去深入學,在寫上一節的 時候評論有人就提到了requests,除了那個Referer的坑 外,在使用urllib的時候就遇到一些很繁瑣的東西了, 舉幾個例子:

  • 傳送Get和Post請求
  • Cookie處理
  • 設定代理

還有一點urllib預設不支援壓縮,要返回壓縮格式,必須在 請求頭裡寫明 accept-encoding,然後獲取返回資料時要在 響應頭裡是否有accept-encoding以此判斷是否需要解碼, 非常繁瑣...

當然你可以自己對urllib進行一些常用的封裝,以此規避此類 問題。恰逢前幾天,看到我妹蹲在電腦前在呆呆地重複做些 什麼事情,好奇的問了下她:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

我妹

儲存微信文章裡的圖片,音訊,視訊啊,寫公司的文章要用到。

:這麼呆???

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

是的,她就這樣重複每一篇文章:

右鍵圖片儲存,視訊開啟chrome f12找到flash裡的視訊連結, 然後再發到v.ranks.xin/解析,得到下載的url,再進行下載   作為技術宅的歐尼醬,肯定要寫個小指令碼來幫她脫離這種 重複性的勞動,作為交換條件,她需要打掃一週衛生。

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

所以就有了這個實戰例子~ (PS:某寶上有這樣的工具,竟然賣10塊錢,還有人買,2333)


1.Requests簡介

(本節只講述常用的姿勢,更多內容可到官方文件中翻閱~)

作者:Kenneth Reitz Gayhub地址github.com/kennethreit… 官方倉庫github.com/requests/re… 官方文件www.python-requests.org/en/master/

Feature Support

  • International Domains and URLs —— 國際化域名和URL
  • Keep-Alive & Connection Pooling —— Keep-Alive & 連線池
  • Sessions with Cookie Persistence —— 帶持久Cookie的會話
  • Browser-style SSL Verification —— 瀏覽器式的SSL認證
  • Basic/Digest Authentication —— 基本/摘要式的身份認證
  • Elegant Key/Value Cookies —— 優雅的 key/value Cookie
  • Automatic Decompression —— 自動解壓
  • Automatic Content Decoding —— 自動內容解碼
  • Unicode Response Bodies —— Unicode響應體
  • Multipart File Uploads —— 檔案分塊上傳
  • HTTP(S) Proxy Support —— HTTP(S)代理支援
  • Connection Timeouts —— 連線超時
  • Streaming Downloads —— 流下載
  • .netrc Support —— 支援.netrc
  • Chunked Requests —— Chunked請求

有些聽都聽不懂,感覺很牛逼的樣子,不方,跟著小豬擼一遍就好~ 先通過 pip install request 安裝一波庫,然後就可以開始玩了!


2.三分鐘上手requests

# 1.支援各種請求方式:GET,POST,PUT,DELETE,HEAD,OPTION
r1 = requests.get("http://xxx", params={"x": 1, "y": 2})
r2 = requests.post("http://xxx", data={"x": 1, "y": 2})
r3 = requests.put("http://xxx")
r4 = requests.delete("http://xxx")
r5 = requests.head("http://xxx")
r6 = requests.options("http://xxx")
複製程式碼

注意

  • URL連結裡有中文會自動轉碼
  • post時如果傳遞的是一個str而不是一個dict,會直接傳送出去!(比如json字串)
  • 2.4.2版新增:可以通過**json**引數傳遞dict,自動會把dict轉換為json字串!
  • post上傳檔案可以通過**file**引數,如post(url, files={'file': open('report.xls', 'rb')})

請求的相關設定

  • 請求頭headers={'xxx':'yyy'}
  • 代理proxies={'https':'xxx'}
  • 超時(單位秒)timeout=15

處理返回結果

注:由requests發起的請求,當相應內容經過gzipdeflate壓縮時, requests會自動解包,可以獲得通過content獲得byte方式的響應結果。

  • status_code:獲取狀態碼
  • reason:狀態資訊
  • url:獲取請求的url
  • content: 獲取byte型別的返回結果,相當於urllib.urlopen().read;
  • raw:獲得原始的返回結果,請求裡需要設定**stream=True**;
  • text:獲取str型別的返回結果,會自動根據響應頭部的字元編碼進行解碼; 可以呼叫r.encoding獲得編碼方式,或者在調text之前先r.encoding='編碼' 設定編碼型別,text就會按照對應的編碼進行解析;
  • json:解析序列化為JSON格式的資料,直接就可以['xxx']拿資料了, 如果解析錯誤會丟擲異常:ValueError: No JSON object could be decoded

除此之外還可以呼叫headers獲得響應頭比如:

r = requests.get('http://gank.io/api/data/福利/50/1')
# 直接根據鍵獲得值
print(r.headers.get('Date'))
# 遍歷獲得請求頭裡所有鍵值
for key, value in r.headers.items():
    print(key + " : " + value)

複製程式碼

如果是想獲取請求頭資訊的話:呼叫r.request.headers就可以獲取了。 除此之外還有raise_for_status(),當響應碼不是200的時候,會丟擲 HTTPError異常,可用於響應碼校驗;

Cookie

通過r.cookies即可獲得RequestsCookieJar物件,行為與字典類似; 如果想帶著cookies去訪問,可以在請求裡新增**cookies={'xxx':'yyy'}引數; 也可以通過requests.cookies.RequestsCookieJar()**呼叫set方法進行構造, 比如:jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere'),可以呼叫下述方法遍歷cookies:

for c in r.cookies:
    print(c.name + ":" + c.value)
複製程式碼

附:CookieJar與字典間的互轉

# 字典 -> CookieJar
cookies = requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)

# CookieJar-> 字典
cookies = requests.utils.dict_from_cookiejar(r.cookies) 
複製程式碼

重定向與請求歷史

除了HEAD請求,Requests會自動處理所有重定向,可以在執行請求的時候 使用**allow_redirects=False禁止重定向,可以呼叫history**函式追蹤請求 歷史,一個Response物件的列表,按照最老到最近的請求進行排序。

錯誤與異常

注:Requests 顯式丟擲 的異常都繼承自requests.exceptions.RequestException

  • 1.遇到網路問題,會丟擲**ConnectionError**異常
  • 2.請求超時,會丟擲**Timeout**異常
  • 3.請求超過了設定的最大重定向次數,會丟擲**TooManyRedirects**異常

Session會話物件

用於跨請求保持一些引數,最常見的就是保留cookies, Session物件還提供了Cookie持久化和連線池功能,

s = request.Session() # 建立會話
s.post('http://xxx.login',data={'xx':'xx'}) # 登入網址
s.get('http://xxx.user') # 登入後才能訪問的網址
s.close() # 關閉會話
複製程式碼

3.Requests實戰:抓取微信文章的圖片與視訊

推理分析環節

隨手開啟一個微信連結:mp.weixin.qq.com/s/JHioeDcop…

  • 1.標題 拿來做資料夾名字,很好拿,直接title標籤

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

  • 2.獲取圖片:不難發現圖片的標籤是這樣的

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

可以通過下面這段程式碼拿到:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

然後呢,圖片可能是PNG,JPEG或者GIF,觀察data-src可以看到: 尾部有個wx_fmt=jpeg,**split['='][-1]**就能拿到檔案格式,圖片名的 話:url.split("/")[-2],就有了這樣一段下載圖片的程式碼:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

  • 3.獲取音訊

這個就需要取巧了,直接看網頁結構的話:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

src裡的連結貼上賦值是不能開啟的,這個mpvoice貌似是採用的是 js渲染模組方案,安卓狗表示不知道是什麼,有興趣的可以看下這篇 文章:m.dian321.com/keji/117479… 感覺一時半夥也找不出規則,要不走一波手機抓包?

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

嘖嘖,原來就這麼簡單,所有隻需要拿到mediaid就可以啦, 而剛好就是voice_encode_fileid屬性,然後音訊名就直接用 時間戳.mp3的格式來命名把,所以有了下面兩段程式碼:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

  • 4.獲取視訊

這個就不好搞了,內嵌在iframe裡,貌似是一個flash播放器

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

複製了下url,網頁重新開啟:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

同樣是拿不到,手機抓一波包?

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

看到vkey這麼長,猜都猜到是加密後的東西了,要去推敲不知 得花到何年何月了,有沒有什麼取巧的辦法呢?對了,差點忘 了我妹用的那個視訊連結獲取網站 [http://v.ranks.xin/] 22

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

貼視訊地址,然後解析視訊,就可以得到可下載的視訊超連結了, 把前面那個src的連結貼下,清下chrome解析那裡,然後準備抓包, 點下解析後,可以看到發出了一個這樣的請求:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

點開,咦,這不是上一節我們剛瞭解的Ajax動態載入技術嗎?

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

一點不方,還有點雞凍,(≧▽≦)/ 看下Preview,喲喲,這難道是我們想要的超連結?

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

複製貼上,右鍵看下能否另存為?

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

穩如狗,接著就來一波解析,還有下載視訊的程式碼咯:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

核心的東西就這些啦,接著就簡單了,寫一個無限While迴圈, 然後獲取使用者的輸入,然後輸入Q直接exit()就可以了~

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

隨手試兩篇文章,執行結果:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

可以,很Gay,都抓到了,美滋滋~ 另外如果出現Max retries exceeded with url這樣的異常,可能就是 你的requests庫太舊了,可以走一波:pip install --upgrade requests 進行升級。


4.使用pyinstaller生成exe檔案

指令碼是有了,你也不可能在我妹電腦上裝個Python環境吧? 可以通過pyinstaller來生成一波exe檔案,然後就可以在我 妹的渣渣win本上執行了。

鍵入:pip install pyinstaller,安裝pyinstaller

新建一個資料夾,然後把我們的指令碼拷進去,我們還可以弄個應用圖示

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

接著命令列走一波:

pyinstaller -F -i wechat.ico CatchWeChatRes.py
複製程式碼

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

執行成功後能看到資料夾下多了幾個檔案:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

如果正常生成了exe檔案的話,是可以在dist目錄下找到的。

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

雙擊執行,貼個文章的url:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

成功下載到本地,沒毛病~

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

Tips

-i 是可選引數,代表有錯誤也繼續執行 -w 如果不需要命令列,可以加上-w

編譯中途出現過這個錯誤:

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

執行不了指令碼,後來發現是手多在檔案裡import了無關模組,刪掉就可以了;


5.小結

本來昨天就應該寫完了,因為公司搬家的原因,還有因為太冷 起不了床的原因,拖到下午才補完,尷尬~

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

後面會學Python裡自帶的圖形化模組Tkinter,到時再拼湊一個 簡單的圖形化介面介面吧~


本節原始碼下載

github.com/coder-pig/R…


來啊,Py交易啊

想加群一起學習Py的可以加下,智障機器人小Pig,驗證資訊裡包含: PythonpythonpyPy加群交易屁眼 中的一個關鍵詞即可通過;

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫

驗證通過後回覆 加群 即可獲得加群連結(不要把機器人玩壞了!!!)~~~ 歡迎各種像我一樣的Py初學者,Py大神加入,一起愉快地交流學♂習,van♂轉py。

小豬的Python學習之旅 —— 10.三分鐘上手Requests庫


相關文章