爬蟲入門教程⑦— jupyter與requests的初步使用

jupyter 是一個簡易的,方便的寫Python代碼的工具包,requests是Python里非常好用的用來發(fā)送 http 請求的包。

開始學(xué)習(xí)本教程之前,請確保你已經(jīng)安裝了Python,并且安裝了Python包 jupyterrequests 了。如果沒有,那請參照以下教程進行安裝:


1. jupyter的簡單使用

老規(guī)矩:Windows鍵+X鍵選擇 命令提示符。
打開了命令提示符,那么我們輸入命令: jupyter notebook 回車。
接著你的瀏覽器會自動打開下面的界面:
注:
如果沒有自動打開瀏覽器卻顯示了一個網(wǎng)址在窗口里面,那么是你電腦沒有設(shè)置默認瀏覽器或者默認瀏覽器設(shè)置錯誤導(dǎo)致的;
如果瀏覽器打開了網(wǎng)頁卻不顯示任何東西,無法正常使用,請檢查你的瀏覽器的版本是否比較陳舊,推薦使用Firefox、Chrome、QQ瀏覽器等使用非IE內(nèi)核或高等級IE內(nèi)核的瀏覽器。

jupyter notebook界面

接著我們點擊網(wǎng)頁右邊的 new,選擇 Python3。(我的jupyter多了個Python2的選項,那是因為我自己給jupyter配置了Python2,默認情況下,只有你當(dāng)前的Python版本的文件選項。)

創(chuàng)建Python文件

選擇了創(chuàng)建文件之后,瀏覽器打開了一個新的界面,這就是我們的代碼編輯界面啦,從此以后就可以開開心心寫代碼了。
我們在下面的In [ ]:那里輸入我們的第一個程序的第一條語句:
print("Hello World")
然后點擊畫面上方的Run按鈕,就運行我們的程序啦。效果如圖:

輸出Hello World


Requests: HTTP for Humans

這是 requests 的 slogan。非常簡單明了,我覺得翻譯成中文大概是:給人使用的 HTPP 請求庫
根據(jù)我個人經(jīng)驗來說,看到過很多初學(xué)者(也包括曾經(jīng)的我),都跟著網(wǎng)上很老的爬蟲教程,使用urllib、urllib2來發(fā)起請求。這樣的結(jié)果是什么?不僅寫代碼效率非常低下,而且代碼量比requests多得多,同時代碼也難以理解。
這幾個過時的庫一點也不友好,簡直不像是給人使用的。
所以從遇到requests的第一天起,我就永遠地拋棄了urllib之類的庫了。

requests的作者,是一位非常帥氣的攝影師小哥。目前requests在GitHub上已經(jīng)獲得了32062個Star。

下面我們來學(xué)習(xí)requests的基本使用。

?

2. import requests并發(fā)起一個請求

我們在jupyter的新的一個輸入里面,鍵入下面的代碼并點擊運行:

import requests  
print(requests.get("https://www.baidu.com"))  

注意:括號都是英文的括號哦
運行結(jié)果:

輸出get請求

import requests: 代碼文件里面引入requests這個包以便后面代碼的使用
print(requests.get("https://www.baidu.com")):用requests向百度首頁發(fā)起一個get請求,并打印出請求的結(jié)果(response對象)。
這就已經(jīng)完成了我們使用瀏覽器打開百度首頁的過程了。那為什么我們沒看到網(wǎng)頁也沒看到html呢?我們把代碼改成這樣再運行一次:

import requests
response = requests.get("https://www.baidu.com")
print(response.status_code)
print(response.content)

運行結(jié)果:

輸出請求結(jié)果

第一行的200,是我們這個請求的HTTP狀態(tài)碼,200表示請求成功,關(guān)于狀態(tài)碼前面已經(jīng)講解過了:爬蟲入門教程③— 必備知識基礎(chǔ)(二)HTTP請求簡介。

第二行開始就是輸出的我們獲取到的百度首頁的HTML代碼的二進制字符串,b'xxxxx'表示這個字符串是二進制的。
那我們怎么把二進制結(jié)果改成我們看得懂的中文結(jié)果呢?我們只需要對響應(yīng)的content(二進制)進行一次解碼,常見的解碼方式有gbk, utf-8。
Windows文件用的是gbk編碼,有一些比較古老的網(wǎng)頁也是用的gbk編碼?,F(xiàn)在大部分的網(wǎng)頁都是用的 utf-8 的編碼了。
我們怎么知道網(wǎng)頁用的哪個編碼呢?一般是看meta信息里面charset的值:

找編碼

當(dāng)然也可以猜,不報錯,不亂碼,那就對了。

于是我們在輸出二進制響應(yīng)后面加上.decode('utf-8'),把二進制字符轉(zhuǎn)換成字符串:

import requests
response = requests.get("https://www.baidu.com")
print(response.status_code)
print(response.content.decode('utf-8'))

輸出如下:


中文編碼結(jié)果

現(xiàn)在就能看懂了,我們成功打開了百度的首頁!
是的,requests發(fā)起一個請求就是這么簡單。

要發(fā)起 post 請求,也同樣簡單

import requests
form = {'username': 'admin','password': 'admin123456'}
response = requests.post("https://www.baidu.com", data=form)
print(response.content.decode('utf-8'))

這就向百度首頁,發(fā)起了一個post請求,并且?guī)狭藘蓚€參數(shù),參數(shù)名是username和password,值是admin和admin123456。post請求我們一般用于對網(wǎng)頁發(fā)送數(shù)據(jù),比如登錄,發(fā)送圖片、文件等等。如果請求方式弄錯了,很可能得不到正確的響應(yīng)的哦

?

3. requests.session的使用

這里要介紹一下cookie:

Cookie,有時也用其復(fù)數(shù)形式 Cookies,指某些網(wǎng)站為了辨別用戶身份、進行 session 跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)。

cookie就相當(dāng)于一個令牌,你拿著它去訪問網(wǎng)站,網(wǎng)站就能辨別你是誰了。所以如果你登錄了,你去訪問其他需要登錄的網(wǎng)頁,都可以直接訪問,因為瀏覽器在你訪問的時候,默認會帶上cookie。cookie的添加、刪除、更新是在服務(wù)器返回的響應(yīng)里獲取到的。

requests.get() 是發(fā)送請求常用的一個辦法。它不能做到的是對cookie的持久化: 上一個請求獲取到的cookie,沒辦法簡單地傳遞到下一個請求去,這樣兩個requests.get()請求之間沒有辦法產(chǎn)生聯(lián)系。如果是對于需要登錄的網(wǎng)站來說,這是毀滅性的,我們會一直卡在登錄界面。
下面要引入的就是requests的session。它能夠自動管理cookie,也能夠進行cookie的持久化。用法也很簡單:

import requests
http_session = requests.session()
response = http_session.get("https://www.baidu.com")
print(response.content.decode('utf-8'))

我們定義了一個http_session用來作為我們的session。然后我們使用這個http_seesion發(fā)出的每個請求,都會自動帶上cookie,也會自動處理網(wǎng)站服務(wù)器返回的對cookie的操作。
這些過程對我們不可見,而我們只需要使用就好了!簡直完美!

?

4. 把從瀏覽器獲取到的cookie添加到session里來繞過登錄

注:此小節(jié)為進階教程,不理解可暫時跳過。

首先補充一下cookie的知識:

  • 原因:http請求是無狀態(tài)的,也就是說,你的每一次請求,網(wǎng)站服務(wù)器都會認識是一次新的請求。

  • 問題:既然每一次請求都是新的請求,那么網(wǎng)站識別用戶就遇到困難了:一個網(wǎng)站需要服務(wù)于多個用戶,每個用戶的需要呈現(xiàn)的內(nèi)容可能是不同的。如果每次請求都是全新的,服務(wù)器會不知道是誰發(fā)過來的,進而就可能造成一個混亂的局面,把A的消息發(fā)給了B,C的郵件給了A等等。

  • 解決方案:服務(wù)器如果需要識別你的身份,那它就給你發(fā)送一個或多個cookie(如果不需要對你進行特異性識別,那就沒必要設(shè)置cookie了),之后你的每個請求默認會帶上服務(wù)器設(shè)置的cookie(瀏覽器自動處理)。由于服務(wù)器給每個用戶的分配的cookie的值是不同的,那服務(wù)器就可以輕松地通過cookie的值來識別用戶了。

  • 拓展:既然服務(wù)器是通過cookie這個令牌識別你是誰的,那么只要你的請求帶上了任意一個人的cookie去訪問服務(wù)器,那么服務(wù)器就會認為你就是那個人。所以在以前有中間人攻擊這個事情,黑客就是通過攔截你的請求,找到你的cookie,自己偽裝成你,然后幫他發(fā)廣告或者是進行一些其他的危險操作以獲得利潤。

如果我們需要爬取一個需要登錄的網(wǎng)站,但是他的登錄流程非常麻煩,甚至需要輸入驗證碼。我們有沒有什么比較輕便的辦法來解決這個問題呢?
當(dāng)然有:我們在瀏覽器上登錄了,然后把瀏覽器上的網(wǎng)站發(fā)送給你的cookie,按照格式添加到我們的session里面,那么我們就無需登錄,成功偽裝成了瀏覽器里面的自己的賬號了,進而可以直接進行爬取了(每個請求帶上cookie,服務(wù)器就會認為我們是已經(jīng)登錄過了)。

怎么獲取瀏覽器的cookie呢?
F12打開調(diào)試模式,然后選中NetWork(網(wǎng)絡(luò))。接著鼠標(biāo)點到網(wǎng)頁上去,按F5刷新界面。我們馬上可以看到在調(diào)試窗口里面的列表有一個接一個的請求出現(xiàn)了,我們找到第一個請求(通常是第一個,具體請看請求的網(wǎng)址),點擊一下,就顯示出了這個請求的具體信息了。
接著再找到Request Header里面的Cookie

找到cookie

在我的截圖里面,百度給我發(fā)送了非常多的cookie,你可能沒這么多,但是也不影響,畢竟這只是個示例。

  • 接著我們把所有的cookie復(fù)制下來。
  • 每一條cookie是以;隔開的,所以我們先以;把這些cookies分開,分割為一條條的cookie。
  • 對于每條cookie我們再以第一個=把一條cookie分為 name 和 value 兩個部分。
  • 然后我們把這些key-value的數(shù)據(jù),添加到一個dict里面
  • 最后把cookie添加到 http_session 的cookies里面。

舉個例子,復(fù)制下來的cookies字符串為
"sessionid=124586245;name=pikaqiu;FDS=fdsa=okok;how=areyou"
首先我們以;切割這個字符串得到了下面這幾條cookie

"sessionid=124586245"
"name=pikaqiu"
"FDS=fdsa=okok"
"how=areyou"

然后我們再把這幾條cookie轉(zhuǎn)換成requests能夠接受的格式:

cookies = {
           'sessionid': '124586245',
           "name": "pikaqiu",
            "FDS": "fdsa=okok",
            "how": "areyou",
          }

最后再把這個cookie添加到requests提供的http_session里面,之后這個session就會自動為我們處理cookie了,包括每個請求發(fā)送cookie,修改和刪除cookie的信息。

下面以上圖的百度舉個例子,下面就是采用了我自己的cookie訪問百度的例子:

import requests
http_session = requests.session()
cookies = {'BAIDUID': 'CC97B75E17BC78:FG=1',
            'BIDUPSID': 'CC97B75E17FE0BEEBC78',
            'PSTM': '15700',
            'BDSFRCVID': 'th-sJeC626F0ZTQA',
            'H_BDCLCKID_SF': 'tJPjVC0yt',
            'ispeed_lsm': '2',
            'H_PS_645EC': '00e6qFET6oh4QC9Q',
           }  # 為了減少篇幅,我刪掉了后面的幾個cookie,你們可不能偷懶哦~
requests.utils.add_dict_to_cookiejar(http_session.cookies, cookies)
response = http_session.get("https://www.baidu.com")
print(response.content.decode('utf-8'))

通過把瀏覽器的cookie添加到程序里面,然后用程序來進行訪問,我們就可以節(jié)約用程序登錄的步驟,專心進行我們其他的操作了。這個辦法同樣適用于一些不需要登錄,但是對cookie有要求的網(wǎng)站。

本節(jié)到此結(jié)束,下一節(jié)會是關(guān)于如何從HTML字符串里面提取出我們需要的內(nèi)容的教程。感謝觀看。


傳送門:

下一章:

所有的章節(jié):

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 會話(Session)跟蹤是Web程序中常用的技術(shù),用來跟蹤用戶的整個會話。常用的會話跟蹤技術(shù)是Cookie與Se...
    chinariver閱讀 5,792評論 1 49
  • 在爬蟲入門系列(一):快速理解HTTP協(xié)議中介紹了 HTTP 協(xié)議,Python 提供了很多模塊來基于 HTTP ...
    liuzhijun閱讀 528評論 0 9
  • 1. 概述 本文主要介紹網(wǎng)絡(luò)爬蟲,采用的實現(xiàn)語言為Python,目的在于闡述網(wǎng)絡(luò)爬蟲的原理和實現(xiàn),并且對目前常見的...
    Lemon_Home閱讀 3,124評論 0 21
  • 會當(dāng)凌絕頂,一覽眾山小。這是我高中的語文老師帶我們游玩時,在課堂上常念的一句。很多時候,無論是登山望遠亦或有什么心...
    大巫見小巫panda閱讀 262評論 0 0
  • 文/瘋自在 揮袂清風(fēng),腹中文武,應(yīng)許吾者。 落筆從容,才華半點,掩白衣高雅。 攤開韻底,吟寬未敢,拈賦自當(dāng)瀟灑。 ...
    小瘋子自在閱讀 420評論 5 32

友情鏈接更多精彩內(nèi)容