一、Requests庫

知識框架

一、簡介

Requests庫屬於Python的第三方庫,是公認的爬取網頁最好的第三方庫,可用pip的方式進行安裝:pip install requests,其官網為python-requests.org;一個網頁可以看做是一個爬蟲爬取信息的API。

#示例:>>>import requests>>>r = requests.get("http://www.baidu.com")>>>r.status_code200>>>r.text<!DOCTYPE html><!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>????o|??????????? ?°±??¥é??</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=????o|?????? class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>??°é??</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>??°???</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>è§?é¢?</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>è′′??§</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>??????</a> </noscript> <script>document.write(<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ " name="tj_login" class="lb">??????</a>);</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">??′?¤??o§???</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>?3?o?????o|</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>?????¨????o|?????èˉ?</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>???è§????é|?</a>&nbsp;?o?ICPèˉ?030173??·&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>#列印出來的HTML頁面是亂碼的#將r.encoding = utf-8>>>import requests>>>r = requests.get("http://www.baidu.com")>>>r.status_code200>>>r.encoding = utf-8>>>r.text<!DOCTYPE html><!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新聞</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地圖</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>視頻</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>貼吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登錄</a> </noscript> <script>document.write(<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ " name="tj_login" class="lb">登錄</a>);</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多產品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>關於百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必讀</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意見反饋</a>&nbsp;ICP030173&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>#r.encoding = utf-8之後頁面可以正常看到HTML頁面相關信息


二、Requests庫的七個方法

各方法說明:

(1)requests.request()

構造一個請求,是支撐以下各方法的基礎方法

(2)requests.get()

獲取HTML網頁的主要方法,對應於HTTP的GET

(3)requests.head()

獲取HTML網頁頭信息的方法,對應於HTTP的HEAD

(4)requests.post()

向HTML網頁提交POST請求的方法,如果POST的是字典則HTML自動編碼為form,如果POST的是字元串則HTML自動編碼為data,對應於HTTP的POST

(5)requests.put()

向HTML網頁提交PUT請求的方法,如果PUT的是字典則HTML自動編碼為form,如果PUT的是字元串則HTML自動編碼為data對應於HTTP的PUT

(6)requests.patch()

向HTML網頁提交局部修改請求,對應於HTTP的PATCH

(7)requests.delete()

向HTML網頁提交刪除請求,對應於HTTP的DELETE

各方法用法:

  • 方法一

requests.request(method, url, **kwargs)

method:七種請求方式

r = requests.request(GET,url,**kwargs)

r = requests.request(HEAD,url,**kwargs)

r = requests.request(POST,url,**kwargs)

r = requests.request(PUT,url,**kwargs)

r = requests.request(PATCH,url,**kwargs)

r = requests.request(delete,url,**kwargs)

r = requests.request(OPINIONS,url,**kwargs)

**kwargs對應13個控制訪問參數:

  • params:是指能夠增加到url中的參數,字典或位元組序列

>>>kv = {key1:value1, key2:value2,}>>>r = requests.request(GET, http://python123.io/ws, params=kv)>>>print(r.url)http://python123.io/ws?key1=value1&key2=value2

  • data:字典、位元組序列或文件對象,重點是作為向伺服器提交資源時使用
  • json:JSON格式的數據,(JavaScript Object Notation, JS 對象標記) 是一種輕量級的數據交換格式,作為內容向url伺服器提交
  • headers:字典,HTTP定製頭

>>>hd = {user-agent: Chrome/10}#模擬瀏覽器瀏覽>>>r = requests.request(POST, http://python123.io/ws, headers=hd)

  • cookies:字典或者CookieJar, 從HTTP協議中解析cookie
  • auth:元組類型,支持HTTP認證功能
  • files:字典類型,傳輸文件

>>>fs = {file: open(data.xls, rb)}>>>r = requests.request(POST, http://python123.io/ws, files=fs)

  • timeout:設定的超時時間以秒為單位

>>>r = requests.request(GET, http://python123.io/ws, timeout=10)

  • proxies:字典類型,設定訪問代理伺服器,可以增加登錄認證,可以有效隱藏IP地址

>>>pxs = {http: http://user:pass@10.10.10.1:1234 https: https://10.10.10.1:4321}>>>r = requests.request(GET, http://www.baidu.com, proxies=pxs)

  • allow_redirects:TrueFalse,默認為True,這個欄位是一個開關表示是否允許對url進行重定向
  • stream:TrueFalse,默認為True,獲取內容立即下載,默認為立即下載
  • verify:TrueFalse,默認為True,認證SSL(Secure Sockets Layer 安全套接層)證書的欄位
  • cert:保存本地SSL證書路徑的欄位

說明:其餘六種方法都是通過調用request方法來實現的,例如get方法源代碼:

def get(url, params=None, **kwargs): """Sends a GET request. :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. :param **kwargs: Optional arguments that ``request`` takes. :return: :class:`Response <Response>` object :rtype: requests.Response """ kwargs.setdefault(allow_redirects, True) return request(get, url, params=params, **kwargs)

  • 方法二

requests.get(url,params=None,**kwargs)

r = request.get(url)

get(url)--->構造一個向伺服器請求資源的Request對象,這個對象是Requests庫內部生成的

request.get(url)--->返回一個包含伺服器資源的Response對象,包含從伺服器返回的所有的相關資源

url:擬獲取頁面的url鏈接

params:url中的額外參數,字典或位元組流格式,可選

**kwargs對應12個控制訪問參數

  • 方法三

requests.head(url,**kwargs)

**kwargs對應13個控制訪問參數

  • 方法四

requests.post(url,data=None,json=None,**kwargs)

**kwargs對應11個控制訪問參數

  • 方法五

requests.put(url,data=None,**kwargs)

**kwargs對應12個控制訪問參數

  • 方法六

requests.patch(url,data=None,**kwargs)

**kwargs對應12個控制訪問參數

  • 方法七

requests.delete(url,**kwargs)

**kwargs對應13個控制訪問參數

三、Requests庫的兩個對象

(1)Response對象:

示例:

>>>import requests>>>r = requests.get("http://www.baidu.com")>>>print(r.status_code)200#狀態碼為200,訪問成功>>>type(r)<class requests.models.Response>>>>r.headers{Server: bfe/1.0.8.18, Date: Wed, 28 Feb 2018 08:54:53 GMT, Content-Type: text/html, Last-Modified: Mon, 23 Jan 2017 13:28:37 GMT, Transfer-Encoding: chunked, Connection: Keep-Alive, Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform, Pragma: no-cache, Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/, Content-Encoding: gzip}

說明:該對象包含爬蟲返回的全部內容,通常用r.status_code來查看HTTP請求的返回狀態,如果是200,接下來可以用r.text、r.encoding、r.apparent_encoding、r.content來解析網頁內容。

Response對象的五個屬性:

r = r.status_code(HTTP請求的返回狀態,200表示成功,其餘表示失敗)

r = r.text(獲取url對應頁面的字元串形式內容)

r = r.encoding(從HTTP header中通過charset欄位猜測的響應內容編碼方式,如果header中不存在charset欄位則默認為編碼為ISO-8859-1,這種編碼不能解析中文)

r = r.apparent_encoding(從內容中分析出的響應內容編碼方式,比r.encoding更準確)

r = r.content(HTTP響應內容的二進位形式,比如一副二進位編碼的圖片,可以通過r.content轉換成圖片)

(2)Request對象:略

四、Requests庫的異常處理

requests.ConnectionError(網路連接錯誤異常,DNS<Domain Name System,域名系統>查詢失敗、拒絕連接等)

requests.HTTPError(HTTP錯誤異常)

requests.URLRequired(URL缺失錯誤異常)

requests.TooManyRedirects(超過最大重定向次數,產生重定向異常,複雜鏈接訪問時會產生的錯誤)

requests.ConnectTimeout(連接遠程伺服器超時異常)

requests.Timeout(請求URL超時,是指從發出URL請求到返回結果整個過程產生超時異常)

說明:異常時調用專門與異常打交道的方法Response對象中的r.raise_status方法,如果不是200,產生異常requests.HTTPError

五、通用代碼框架

import requestsdef getHTMLText(url): try: r = requests.get(url, timeout=30) r.raise_for_status()#如果狀態碼不是200,引發HTTPError異常 r.encoding = r.apparent_encodering return r.text except: return "產生異常"if __name__ == "__main__": url = "http://www.baidu.com" print(getHTMLText(url))

推薦閱讀:

python中 if-else 與 try-except的轉換 與while 與 whileTrue-try-except的轉換
輪帶逛終極版! 抓取輪子哥(vczh)全部知乎動態
愛奇藝人物信息scrapy-redis
PYTHON爬蟲將相對路徑轉化為絕對路徑
回顧一個月的爬蟲學習

TAG:爬蟲計算機網路 | 網頁爬蟲 | python爬蟲 |