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

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

標籤:Python


一句話概括本文

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

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


引言

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

  • 發送Get和Post請求
  • Cookie處理
  • 設置代理

還有一點urllib默認不支持壓縮,要返回壓縮格式,必須在
請求頭裏寫明 accept-encoding,然後獲取返回數據時要在
響應頭裏是否有accept-encoding以此判斷是否需要解碼,
非常繁瑣

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

我妹

保存微信文章裏的圖片,音頻,視頻啊,寫公司的文章要用到。

:這麼呆???

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

右鍵圖片保存,視頻打開chrome f12找到flash裏的視頻鏈接,
然後再發到http://v.ranks.xin/解析,得到下載的url,再進行下載
 
作爲技術宅的歐尼醬,肯定要寫個小腳本來幫她脫離這種
重複性的勞動,作爲交換條件,她需要打掃一週衛生。

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


1.Requests簡介

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

作者:Kenneth Reitz
Gayhub地址https://github.com/kennethreitz
官方倉庫https://github.com/requests/requests/
官方文檔http://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實戰:抓取微信文章的圖片與視頻

推理分析環節

隨手打開一個微信鏈接:http://mp.weixin.qq.com/s/JHioeDcopm-98R5lGVemqw

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

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

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

然後呢,圖片可能是PNG,JPEG或者GIF,觀察data-src可以看到:
尾部有個wx_fmt=jpegsplit[‘=’][-1]就能拿到文件格式,圖片名的
話:url.split(“/”)[-2],就有了這樣一段下載圖片的代碼:

  • 3.獲取音頻

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

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

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

  • 4.獲取視頻

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

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

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

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

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

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

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

複製粘貼,右鍵看下能否另存爲?

穩如狗,接着就來一波解析,還有下載視頻的代碼咯:

核心的東西就這些啦,接着就簡單了,寫一個無限While循環,
然後獲取用戶的輸入,然後輸入Q直接exit()就可以了~

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

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


4.使用pyinstaller生成exe文件

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

鍵入:pip install pyinstaller,安裝pyinstaller

新建一個文件夾,然後把我們的腳本拷進去,我們還可以弄個應用圖標

接着命令行走一波:

pyinstaller -F -i wechat.ico CatchWeChatRes.py

執行成功後能看到文件夾下多了幾個文件:

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

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

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

Tips

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

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

執行不了腳本,後來發現是手多在文件裏import了無關模塊,刪掉就可以了;


5.小結

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

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


本節源碼下載

https://github.com/coder-pig/ReptileSomething


來啊,Py交易啊

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

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


發佈了306 篇原創文章 · 獲贊 1857 · 訪問量 1661萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章