什麼是requests庫
Requests庫是Python中的一個HTTP網路請求庫,用來簡化網路請求!
requests庫的安裝
如果在安裝python的同時安裝了pip,那麼可以直接使用pip來進行安裝。步驟是:
- win R 開啟執行視窗
- 輸入 cmd 進入命令列
- 輸入 pip install requests
至此,requests庫安裝成功
requests庫的使用
爬取第一個網頁
這裡以 “http://www.baidu.com“為例。
第一步匯入requests庫
import requests
第二步建立一個url,這裡是”http://www.baidu.com”
url = "http://www.baidu.com"
第三步對”http://www.baidu.com“發起一個get請求
response = requests.get(url)
這裡的response是一個物件,response 物件是伺服器傳送到客戶端的資料,response的屬性和方法後面會將
第四步可以呼叫response物件的方法將伺服器端的資料列印一下
print(response.text)
這裡返回的資料如下:
<!--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&tpl=mn&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>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度å‰å¿…读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>æ„è§å馈</a> 京ICPè¯030173å· <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
可以看到這裡的資料是亂碼,出現這種情況的原因是:response.text 的解碼是根據HTTP頭部對響應的編碼做出有根據的推測,推測的文字編碼。也就是說它的解碼方式只是一種推測,並不一定正確。
那如何修改編碼方式呢?
可以在列印之前增加一行:
response.enconding("utf-8")
這行的作用就是將編碼格式改為 utf-8 編碼,這對大多數網頁來說都是可行的。
再次列印結果如下所示:
<!--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&tpl=mn&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>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必讀</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意見反饋</a> 京ICP證030173號 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
到這裡就把請求 “http://www.baidu.com” 返回的資料獲取了。要注意這個資料並不是你點選“檢查”->“elements”裡面的東西。這一點在前文已經說過:小白學爬蟲(一) – 基礎知識。
下面給出完整程式碼
import requests
url = "http://www.baidu.com"
response = requests.get(url)
response.encoding = "utf-8"# 修改編碼格式
print(response.text)
在這個例子裡面遇到了一個問題,就是使用 response.text 出現亂碼問題;這個問題其實很常見,我們的解決方法是 使用reponse.encoding修改了編碼格式。這個方法是可行的,另外還可以直接使用 print(reponse.content.decode(“utf-8”)) 直接解碼。
於是程式碼就變成了這樣:
import requests
url = "http://www.baidu.com"
response = requests.get(url)
print(response.content.decode())
結果不變。response.content.decode()如果不寫引數,預設是 “utf-8”編碼,如果使用”utf-8”解碼出現問題,可以嘗試 response.content.decode(“gbk”) 使用gbk解碼。
獲取網頁原始碼的正確開啟方式
總結一下獲取網頁原始碼的正確開啟方式:
1,response.content.decode()
2, response.content.decode("gbk")
3, response.text
第一種也可以換成
response.encoding("utf-8")
print(response.text)
requests的reponse物件
reponse物件是爬蟲發起請求時伺服器返回的東西。
常見reponse方法
- response.text:列印返回的資料
- response.content:列印返回的資料
- response.status_code:返回狀態碼,具體可以參見:Response.StatusCode的HTTP…(他也是轉的)
- response.request,headers:返回請求頭
- response.headers:返回響應頭
response.text和response.content 都是列印返回的資料,它們的區別是什麼呢?
圖片來自requests入門 response的常用方法 response.text 和response.content的區別
在上面那個例子裡面加入
print(response.status_code) # 結果是200
print(response.request.headers)
結果是:
{'User-Agent': 'python-requests/2.19.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
加入
print(response.headers)
結果是:
{'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'Keep-Alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Wed, 01 Aug 2018 13:05:06 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:27:56 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}
大家可以參考我前一篇文章或者自行百度這寫東西是什麼,另外一張圖說明一下什麼是請求頭和響應頭。
傳送一個post請求(headers)
嘗試用百度翻譯翻譯“一個人並不是生來就要給打敗的,你儘可以消滅它,但就是打不敗它”,在百度翻譯中的結果是:“A man is not born to defeat. You can destroy it, but you can not defeat it.”
現在嘗試用程式來實現。
首先,試一下能不能正確訪問到百度翻譯的頁面
import requests
url = "http://fanyi.baidu.com/basetrans"
query_string = {"query":"一個人並不是生來就要給打敗的,你儘可以消滅它,但就是打不敗它",
"from":"zh",
"to":"en",}
reponse = requests.post(url,data = query_string)
print(reponse)
print(reponse.content.decode())
執行結果是:
<Response [200]>
post請求要提交資料,用程式來實現就是放在requests.post()的data引數中。可以看到我們提交的資料與瀏覽器是一樣的,但是卻並沒有得到響應,只返回了一個狀態碼 200。這個狀態嗎的意思是一切都是ok的,但是我們沒有接收到伺服器返回來的資料呀。可能的情況是伺服器已經發現了我們是一個爬蟲,而不是一個瀏覽器。所以我們就要裝的像一點,首先在程式裡面加上headers。
將上面瀏覽器裡面的headers附加到程式裡就變成了
import requests
url = "http://fanyi.baidu.com/basetrans"
query_string = {"query":"一個人並不是生來就要給打敗的,你儘可以消滅它,但就是打不敗它",
"from":"zh",
"to":"en",}
m_headers = {
"User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Mobile Safari/537.36"
}
reponse = requests.post(url,data = query_string,headers = m_headers)
print(reponse)
print(reponse.content.decode())
執行結果:
<Response [200]>
{"errno":0,"from":"zh","to":"en","trans":[{"dst":"A man is not born to defeat. You can destroy it, but you can not defeat it.","prefixWrap":0,"src":"\u4e00\u4e2a\u4eba\u5e76\u4e0d\u662f\u751f\u6765\u5c31\u8981\u7ed9\u6253\u8d25\u7684\uff0c\u4f60\u5c3d\u53ef\u4ee5\u6d88\u706d\u5b83\uff0c\u4f46\u5c31\u662f\u6253\u4e0d\u8d25\u5b83","relation":[],"result":[[0,"A man is not born to defeat. You can destroy it, but you can not defeat it.",["0|90"],[],["0|90"],["0|75"]]]}],"dict":[],"keywords":[{"means":["one"],"word":"\u4e00\u4e2a\u4eba"},{"means":["isn't","fault","blame","ain't","an't"],"word":"\u4e0d\u662f"},{"means":["have an instinct for"],"word":"\u751f\u6765\u5c31"},{"means":["beat","defeat","suffer a defeat","be defeated","vanquish"],"word":"\u6253\u8d25"},{"means":["can","may","passable","pretty good","Ok"],"word":"\u53ef\u4ee5"},{"means":["eliminate","perish","die out","annihilate","cut the throat of"],"word":"\u6d88\u706d"},{"means":["quite right","exactly","even if","even","namely"],"word":"\u5c31\u662f"},{"means":["unbeaten","undefeated","invincible"],"word":"\u4e0d\u8d25"}]}
可以看到在”dst”裡面已經有了翻譯的結果,和瀏覽器是一樣的。現在的程式和剛才的相比只是少了一個User-Agent結果就截然不同,有時候會出現加上了User-Agent但是還是不能得到資料,這時候就再加一些其他的東西,比如“Referer”、“Origin”、“Content-Type”這些欄位。儘量的讓自己的爬蟲像一個瀏覽器,後期可能還要像一個人一樣。
写评论
很抱歉,必須登入網站才能發佈留言。