1. 程式人生 > >爬蟲原理與會話保持(cookies、session)詳解--python實現

爬蟲原理與會話保持(cookies、session)詳解--python實現

一、爬蟲原理

    我們知道網際網路是由大量計算機和網路構成的複雜系統,我們可以將其形象的比喻成一張蜘蛛網。網路的節點是計算機,計算機中儲存著大量的資料。爬蟲程式就是通過網路去採集指定計算機中資料的工具。一般來說,我們採集的資料大多是網頁上的資料,也就是我們平時可以在瀏覽器軟體上瀏覽網際網路上的web,因此爬蟲程式的道理也很簡單,就是模仿瀏覽器去獲取指定站點的網頁,通過機器來看我們需要採集資料的網頁,並把我們需要的資料的儲存起來。

1、HTTP原理

    網際網路在傳輸資料的時候需要遵循一定的規範格式,其中我們在使用瀏覽器瀏覽網頁的時候就需要遵循HTTP協議,中文名稱為超文字傳輸協議。HTTP協議主要用來傳輸超文字(網頁等)資料。類似的協議還有ftp(主要用來傳輸檔案)等
    我們需要採集指定計算機中的資料,那麼我們怎麼才能找到這臺計算機呢? HTTP協議使用URL來定位計算機和計算機中的資料資源。例如https://www.blog.csdn.net/hfutzhouyonghang

就是一個URL,在瀏覽器上輸入這串字元,就可以找到我的部落格了。https表示協議的名稱,httpshttp協議的加密版本。www.blog.csdn.net表示伺服器的域名,通過轉換可以變成ip地址,可以通過域名在茫茫網際網路上定位到csdn的伺服器。最後/hfutzhouyonghang該伺服器web站點下的資源。

2、HTTP請求

    我們在瀏覽器上輸入一個URL,按下回車之後很快就看到了頁面的內容,這其中包含了很複雜的過程,我們需要了解的是,我們的瀏覽器向URL指向的伺服器發出了http請求request,伺服器處理請求之後,返回響應response。瀏覽器根據response中的原始碼等內容進行解析,渲染之後我們就可以在瀏覽器上看到豐富多彩的內容了。其模型如下:

這裡寫圖片描述

2.1 HTTP request

    開啟瀏覽器的檢查元素,選擇一個請求:

這裡寫圖片描述

我們可有看到reques主要t由一下部分組成:

  1. Request URL:即我們的請求地址。
  2. Request Method:常用請求方法有兩種,一種是GET方法,其請求的引數會以明文形式加 在URL後面,因此具有一定的長度限制。一種POST方法,POST方法會將請求中的引數(例如,使用者名稱和密碼)加密後傳到伺服器。
  3. Request Header:header是比較重要的一部分,header攜帶了大量重要的資訊,我們在寫爬蟲程式時要格外注意,其中header包含的部分如下:
    • Accept: 用於瀏覽器可以接受哪些型別的圖片。
    • Accept-Lang:用於指定瀏覽器可有接受哪些語言。
    • Accept-Encoding:用於指定瀏覽器可以接受的內容編碼。
    • Host:用於指定請求資源的主機IP地址和埠號。
    • Cookie:用於維持使用者當前的會話,通常會有多個cookie。
    • Referer:表示請求從那個頁面發過來的
    • User-Agent:它為伺服器提供當前請求來自的客戶端的資訊,包括系統型別、瀏覽器資訊等。這個欄位內容在爬蟲程式種非常重要,我們通常可以使用它來偽裝我們的爬蟲程式,如果不攜帶這個欄位,伺服器可能直接拒絕我們的請求。
    • Content-Type:用來表示具體請求中媒體型別資訊,text/html 表示HTML格式,image/gif表示GIF圖片,application/json表示json資料等,更過的型別大家可以去百度上搜下。
  4. request body:請求體中放的內容時POST請求的表單資料,GET請求沒有請求體。

2.2、HTTP response

    伺服器處理好使用者提交的請求後,向用戶返回響應,響應主要由一下三個部分組成:

  1. 響應狀態碼:狀態碼錶示伺服器的響應狀態,例如200代表伺服器正常響應,404表示頁面未找到,500表示伺服器內部錯誤等,具體可有在百度上查。
  2. 響應頭:響應頭包含了伺服器對請求的應答資訊,常見欄位如下:
    • Data:表示產生響應的時間。
    • Last-Modified:表示獲得的資源最後的修改時間。
    • Server:包含伺服器資訊,比如名稱、版本號等。
    • Content-Type:表示返回的資料型別是什麼。比如text/html 表示返回html文件。
    • Set-Cookie:告訴瀏覽器下次請求時需要帶上該欄位中的Cookie,這個非常重要,是伺服器識別使用者維持會話的重要手段。
    • Expires:指定響應的過期時間,可以是代理伺服器或者瀏覽器將載入的內容更新到快取中,如果再次訪問,就可以從快取中載入,縮短載入時間。
  3. 響應體:響應體的內容非常重要,如果說響應狀態碼、響應頭是包裹上的快遞單資訊,那麼響應體就是包裹裡的東西了。我們需要解析的就是響應體。我們在請求網頁時,其響應體就是html程式碼,請求一張圖片時,響應體內容就是圖片的二進位制資料。

二、Session和Cookies

    在瀏覽一些網站,比如購物的時候,我們常常需要先登陸,登陸過後我們可以連續訪問網站,並且可以將我們需要的購買的東西加入購物車。但是有時候我們中途過了一段時間沒有操作就需要重新登陸。還有某些網站,開啟網頁之後就已經登陸了。這些功能看起來來很神奇,其實都是Session和Cookie在發揮作用。

1,無狀態HTTP

    Http有個特點,即無狀態。什麼叫無狀態呢。Http無狀態是指Http協議對事務處理沒有記憶能力,當我們向伺服器傳送請求後,伺服器處理請求之後返回結果。這是一個獨立的過程,再次向伺服器發出請求,伺服器做出響應又是一次獨立的過程。不會有一條網線一直連著你的電腦和伺服器來完成你的所有請求。因此,伺服器並不知道收到的兩次請求是否來自同一個使用者。這種效果並不是我們想要的。為了保持前後的狀態,我們需要將前面所有請求中的資料再重傳一次,這是非常麻煩和浪費資源的。為了解決這個問題,用於保持HTTP連線狀態的Session和Cookies就出現了。

2、session與cookies

這裡寫圖片描述
    session是指從我們開啟一個網站開始至我們關閉瀏覽器一系列的請求過程。比如我們開啟淘寶網站,淘寶網站的伺服器就會為我們建立並儲存一個會話物件,會話物件裡有使用者的一些資訊,比如我們登陸之後,會話中就儲存著我們的賬號資訊。會話有一定的生命週期,當我們長時間(超過會話有效期)沒有訪問該網站或者關閉瀏覽器,伺服器就會刪掉該會話物件。
    cookies是指網站為了辨別使用者身份,進行會話跟蹤而儲存在本地終端的資料,cookies一般再電腦中的檔案裡以文字形式儲存。cookies其實是有鍵值對組成的,如下圖所示:
這裡寫圖片描述

3,會話維持

    當客戶端瀏覽器第一次請求伺服器時,伺服器會再response中設定一個Set-Cookies的欄位,用來標記使用者的身份,客戶端瀏覽器會把cookies儲存起來,cookies中儲存的有Session的id資訊。當客戶端瀏覽器再次請求該網站時,會把Cookies放在請求頭中一起提交給伺服器,伺服器檢查該Cookies即可找到對應的會話是什麼,再通過判斷會話來辨認使用者的狀態。
    當我們成功登陸網站時,網站會告訴客戶端應該設定哪些Cookies資訊,以保持登陸狀態。如果客戶端瀏覽器傳給伺服器的cookies無效或者會話過期,可能就會收到錯誤的響應或者跳轉到登陸頁面重新登陸。

三、程式碼實現

    我們以登陸豆瓣網為例,來看一下如何處理cookies資料,我們使用了Resquests第三方庫。
1. 首先我們構造一個header,並將header帶入請求中。

   import requests
   headers = {'Host': 'www.douban.com',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive'
           }
res = requests.get("https://www.douban.com/accounts/login",headers=headers)

#檢視狀態碼
>>>res.status_code
200
#檢視headers,注意第一次請求豆瓣,響應體中的Set-Cookies欄位
>>>res.headers
{'Date': 'Sat, 28 Jul 2018 14:47:46 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Keep-Alive': 'timeout=30', 'Vary': 'Accept-Encoding', 'X-Xss-Protection': '1; mode=block', 'X-Douban-Mobileapp': '0', 'Expires': 'Sun, 1 Jan 2006 01:00:00 GMT', 'Pragma': 'no-cache', 'Cache-Control': 'must-revalidate, no-cache, private', 'X-Frame-Options': 'SAMEORIGIN', 'Set-Cookie': 'bid=NURXfALBCrM; Expires=Sun, 28-Jul-19 14:47:46 GMT; Domain=.douban.com; Path=/', 'X-DOUBAN-NEWBID': 'NURXfALBCrM', 'X-DAE-Node': 'brand56', 'X-DAE-App': 'accounts', 'Server': 'dae', 'Strict-Transport-Security': 'max-age=15552000;', 'Content-Encoding': 'gzip'}
#檢視cookie,直接獲取cookie,將會獲取到cookieJar物件,事實上requests中就是用該物件儲存cookies的
>>>res.cookies
<RequestsCookieJar[Cookie(version=0, name='bid', value='NURXfALBCrM', port=None, port_specified=False, domain='.douban.com', domain_specified=True, domain_initial_dot=True, path='/', path_specified=True, secure=False, expires=1564325266, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False)]>

>>>for cookie in res.cookies:
    print(cookie.name+"\t"+cookie.value)
bid NURXfALBCrM
#我們可以將第一次請求的響應中的Set-cookies新增進來,事實上requests庫會自動幫我們做這些
>>>cookieJar = requests.cookies.RequestsCookieJar()
>>>for cookie in res.cookies:
    cookieJar.set(cookie.name,cookie.value)
>>>cookieJar
<RequestsCookieJar[Cookie(version=0, name='bid', value='NURXfALBCrM', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)]>

>>>for cookie in res.headers['Set-Cookie'].split(";"):
    key=cookie.split('=')[0]
    value=cookie.split('=')[1]
    cookieJar.set(key,value)
#看一下現在cookieJar中內容
>>>cookieJar
<RequestsCookieJar[Cookie(version=0, name=' Domain', value='.douban.com', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False), Cookie(version=0, name=' Expires', value='Sun, 28-Jul-19 14:47:46 GMT', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False), Cookie(version=0, name=' Path', value='/', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False), Cookie(version=0, name='bid', value='NURXfALBCrM', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)]>

#模擬登陸
>>>data = {
    'source':'None',
    'redir':'https://movie.douban.com/',
    'form_email':'*****',
    'form_password':'****'
}

#使用Session物件提交請求,相當於在瀏覽器中連續操作網頁,而如果直接使用```request.post()```,則相當沒提交一次請求,則開啟一個瀏覽器,我們在實際使用瀏覽器的經驗告訴我們,這樣是不行的。
>>>session = requests.Session()
>>>res =session.post('https://www.douban.com/accounts/login',headers=headers,cookies=cookieJar,data=data)
>>>res.status_code
200
#此時,如果實在瀏覽器的話,我們應該可以看到已經登陸成功,並且跳轉到了https://movie.douban.com/,頁面,使用這個Session直接訪問的我的賬號,檢查一下,是否是我的賬號在登入狀態。
>>>res = session.get('https://www.douban.com/accounts')
>>>res.text
'<!DOCTYPE html>\n<html lang="zh-CN">\n  <head>\n    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n    <meta property="wb:webmaster" content="572c54c2cc00c6fb" />\n    <meta name="referrer" content="always">\n    \n    <title>\n    smart_hang的帳號\n</title>\n 

我們看到已經成功登陸豆瓣網,並使用Cookie和Session保持登入狀態,這樣我們就可以更好的採集資料啦!

相關推薦

爬蟲原理會話保持cookiessession--python實現

一、爬蟲原理     我們知道網際網路是由大量計算機和網路構成的複雜系統,我們可以將其形象的比喻成一張蜘蛛網。網路的節點是計算機,計算機中儲存著大量的資料。爬蟲程式就是通過網路去採集指定計算機中資料的工具。一般來說,我們採集的資料大多是網頁上的資料,

順序表和連結串列的優缺點區別特點

順序表和連結串列由於儲存結構上的差異,導致它們具有不同的特點,適用於不同的場景。本節就來分析它們的特點,讓讀者明白 "在什麼樣的場景中使用哪種儲存結構" 更能有效解決問題。 通過系統地學習順序表和連結串列我們知道,雖然它們同屬於線性表,但資料的儲存結構有本質的不同: 順序表儲存資料,需預先申請一整塊足夠

JDBC 資料庫連線池DBCPC3P0

前言   這段時間狀態有一點浮躁,希望自己靜下心來。還有特別多的東西還沒有學懂。需要學習的東西非常的多,加油! 一、JDBC複習   Java Data Base Connectivity,java資料庫連線,在需要儲存一些資料,或者拿到一些資料的時候,就需要往

微信小程式-06 tab選項卡滑動切換列表Itemscroll swiper資料的獲取等所用到的都有了

目錄   示例圖片 WXML js WXSS 示例圖片 WXML <view > <scroll-view scroll-x="true" class="tab-h" scroll-left="{{scrollLeft}}

ElasticSearch 簡介外掛安裝logstashkibana

文章目錄 簡介 安裝 elasticsearch安裝 kibana安裝 logstash 安裝 logstash windows 安裝 kanaba 中新增logstash

javaweb:會話管理和儲存會話資料的兩種技術CookieSession

會話: 什麼是會話? •會話可簡單理解為:使用者開一個瀏覽器,點選多個超連結,訪問伺服器多個web資源,然後關閉瀏覽器,整個過程稱之為一個會話。 會話過程中要解決的一些問題? •每個使用者與伺服器進行互動的過程中,各自會有一些資料,程式要想辦法儲存每個使用者的

Linux下靜態庫動態庫.a.so

ref:http://niefei.blog.ccidnet.com/blog/ccid/do_showone/tid_42855.html 1. 介紹   使用GNU的工具我們如何在Linux下建立自己的程式函式庫?一個“程式函式庫”簡單的說就是一個檔案包含了一些編譯好的程式碼和資料,這些編譯好的程式碼和資

vue-x儲存本地儲存localstoragesessionstorage

sessionstorage 也稱會話快取,當用戶關閉瀏覽器視窗後,資料就會被刪除; localstorage 儲存的資料沒有時間限制,只要不刪除,都會存在 vue-x 一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以

ICCV2017 | 一文GAN之父Ian Goodfellow 演講《生成對抗網路的原理應用》附完整PPT

當地時間 10月 22 日到10月29日,兩年一度的計算機視覺國際頂級會議 International Conference on Computer Vision(ICCV 2017)在義大利威尼斯開幕。Google Brain 研究科學家Ian Goodfellow在會上作為主題為《生成對抗網路(G

Kotlin——最詳細的抽象類abstract內部類嵌套類

unit 建議 git 功能 pen 情況 master 這也 html 在前面幾個章節中,詳細的介紹了Kotlin類的類別中的數據類、密封類、接口類以及枚舉類。在這個章節中會對Koltin的抽象類和內部類作出一個詳細的講解。如果對上面所提到的類的類別還不是很清晰的,請閱

Android控制元件之SlidingDrawer滑動式抽屜例項

SlidingDrawer效果想必大家也見到過,它就是1.5模擬器上進入應用程式列表的效果。下面是截圖  一、簡介    SlidingDrawer隱藏屏外的內容,並允許使用者通過handle以顯示隱藏內容。它可以垂直或水平滑動,它有倆個View組成,其

資料探勘-分類器的ROC曲線及相關指標ROCAUCACC

關於ROC曲線有幾篇老部落格。有一篇是一位博士寫的,不過不知道為什麼,那篇文章老是有迷之錯誤,從13年開始,一直訂正到17年,依舊存在錯誤,如舉例有問題、概念混淆(因為其文章包含了太多的概念,導致文法上的指代不清)。 >ROC(Receiver Operating

WEB狀態管理機制剖析cookiesession

1、狀態管理     (1)狀態管理的含義         將瀏覽器與web伺服器之間多次互動當做一個整體來看待,並且將多次互動所涉及的資料(即狀態)儲存下來。     (2)如何進行狀態管理   

linux 下所有格式打包壓方法tarbz2rar

01-.tar格式 解包:[*******]$ tar xvf FileName.tar 打包:[*******]$ tar cvf FileName.tar DirName(注:tar是打包,不是壓縮!) 02-.gz格式 解壓1:[*******]$ gunzip FileName.gz 解壓2:[**

JMeter學習—006—JMeter 命令列非GUI模式-分散式遠端執行指令碼及檢視指定結果日誌

JMeter分散式執行指令碼,以更好的達到預設的效能測試(併發)場景,前文解說了jmeter使用命令列執行各個引數的作用以及命令列使用範例,那麼此文就繼續前文,針對 JMeter 的命令列模式之分散式遠端執行模式進行詳細解說。一、應用場景 1、無需互動介面或受環境限制(l

手動安裝cloudera manager 5.xtar包方式

text res 三種 href none bin -i min devel 官方共給出了3中安裝方式:第一種方法必須要求所有機器都能連網,由於最近各種國外的網站被墻的厲害,我嘗試了幾次各種超時錯誤,巨耽誤時間不說,一旦失敗,重裝非常痛苦。第二種方法下載很多包。第三種方法對

PCA 主成分分析 寫給初學者 結合matlab轉載

整數 變量 行為 保持 sum osc 入參 函數 data 一、簡介 PCA(Principal Components Analysis)即主成分分析,是圖像處理中經常用到的降維方法,大家知道,我們在處理有關數字圖像處理方面的問題時,比如經常用的圖像的查詢

(轉)View Transform視圖變換

camera 1.0 posit 朝向 復制 3d圖 過程 product 變量 原文作者講得太好了,唯有這篇讓我對視圖矩陣了解的清晰了很多。 ----------------------------------------------------------------

BlockingQueue阻塞隊列

明顯 緩存 thread 生產者消費者 演示 mce 生成 log spa 註意:該隨筆內容完全引自http://wsmajunfeng.iteye.com/blog/1629354,寫的很好,非常感謝,復制過來算是個積累,怕以後找不到。 一. 前言   在新增的Concu

非旋 treap 結構體數組版無指針,有圖有真相

ati sin closed 基準 隨機函數 例題 偽隨機 作用 拆分 非旋 $treap$ (FHQ treap)的簡單入門 前置技能 建議在掌握普通 treap 以及 左偏堆(也就是可並堆)食用本blog 原理 以隨機數維護平衡,使樹高期望為logn級別