拉勾cookie解析(2019-05-20更新)

最近在爬拉勾,遇到一些問題,給後來的小夥伴總結一些經驗。這裏我們只談技術,不談代碼。如果不是爲了學習經驗的話,還請移步百度。

首先說一下拉勾的反爬:IP頻率限制,頭信息限制,cookie時時驗證。

  • IP頻率限制:這是最常用,也是最有效的反爬機制之一,並沒有測試拉勾的爬取閾值是多少。有興趣的可以自己去測一下。
  • 頭信息限制:拉勾對頭信息的要求很高,如果你的頭信息不全,會得到302或者無法訪問的情況,如果你的頭信息多了,有可能會給你投毒。這也很好解決,針對每個類型的URL定製headers
  • cookie時時驗證:這是拉勾做的最好的反爬機制了,這裏的時時可不是指每小時驗證一次cookie,而是每個請求驗證一次cookie。有人說這很正常啊,難道其他網站不是每條請求都驗證嗎?拉勾做的不同的地方在於,登錄之後的cookie在訪問一個新的URL之後是變化的,也就是說你從網頁複製的cookie在爬蟲中只能使用一次就會失效。而遊客cookie則是每請求5個URL就會強制302。

cookie本質上是一些鍵值對的集合,可以粗略的看成字典,而拉勾每次請求的cookie變化的主要有三個參數,

  • LGRID:值爲20190426111643-b773c320-67d1-11e9-b7c1-525400f775ce,前面的很容易看出是時間,後面的依我看應該是隨機生成的UUID(不知道的請百度)
  • Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6:值是一個時間戳,和上一個參數的時間差只有幾秒,或者完全相同,這個鍵前面是固定的,後面應該是某個的哈希值。
  • _gat:要麼不存在,要麼值爲1

經過很多值對比和百度,發現變化的時間爲上一次訪問的時間,_gat暫時還不知道有什麼作用,先不理他。那麼找到cookie值的不同有什麼用呢?難道還能找到他們的規律不成。當然不是,這些有的是隨機生成的值,肯定沒有規律的。上面的這些話只是在說明拉勾的cookie是一直變化的,所以直接複製cookie使用是不可行的。

這裏先記錄一下我遇到的兩個小問題,後面再說怎麼解決拉勾cookie:

1、 requests的session是不能維持你直接從瀏覽器複製然後加入到headers的cookie的,也就是說,你第一次訪問的時候是攜帶cookie的,但你在使用session的時候,session還是沒有cookie。解決方法:將字符串的cookie轉化爲字典,再轉化爲cookiejar對象傳給session。
具體代碼見:
https://blog.csdn.net/a583179/article/details/78904645
https://blog.csdn.net/falseen/article/details/46962011

2、在使用requests的時候出現:UnicodeEncodeError: ‘latin-1’ codec can’t encode character ‘\uff08’ in position 21: ordinal not in range(256)
原因:請求頭中含有特殊字符,無法被編碼爲’latin-1’。我的程序出錯是因爲referer參數的URL是我自己構建的,包含中文或一些其他字符。
解決方法:使用urllib.request.quote(URL)轉碼一下就行。另外,我百度的時候,出現這種錯誤的大多是連接數據庫時的錯誤。所以還是要看你的情況。

既然每次訪問之後的cookie是變化的,那麼瀏覽器是怎麼得到這種變化的呢?瀏覽器能得到內容說明他時時更新了cookie。最先想到的肯定是每次請求的響應頭裏可能攜帶Set-Cookie參數對cookie做了修改。但是並沒有,就算有的請求的響應頭裏確實有Set-Cookie,但也不是修改我上面說的兩個關於上一次訪問時間的值。

更新時間:2019-05-20

關於cookie的變化,是因爲拉勾在訪問某個頁面之後,會攜帶這一次的一些請求信息請求另一個API,API會返回set-cookie來修改cookie,請求鏈接大概爲 a.lagou.com/collect? 。而且它還會請求Google的一個接口,參數幾乎和這個API的一樣,猜測作用是驗證和記錄。但我模擬這兩個請求發現,攜帶登錄的cookie也只能訪問兩個頁面就302了。可能是我攜帶的參數不正確,因爲請求API所需的參數是20個,要想一個一個找到他們的構造方式太麻煩,所以我是直接複製的,通過幾次的變化來猜測參數,所以可能不準確。而且拉勾的程序員很精明,參數的命名全部不超過三個字符,通過抓包來全局搜索根本就找不到,比如參數a、參數z等。

另外在測試的過程中遇到一個小問題:
requests的session更新cookie再去發起請求之後,你已經更新的cookie裏的參數和值是不會變化的,在服務器返回Set-cookie之後,session做的並不是更新某一些參數而是添加它們,這就導致了cookie中有兩個同樣的參數,和拉勾原本的cookie不一致。
舉個例子:
我們原本的cookie字典爲{‘a’:1111,‘b’:2222},然後把它加入到session中
服務器返回的set-cookie爲’a’ = 0000,那麼你現在的cookie就變成了{‘a’:1111,‘a’:0000,‘b’:2222}。而不是直接更新a。(這只是用字典舉例,cookie對象並不是完全的對象,因爲可以包含相同的鍵)。但是你再次請求的時候,它纔會將後面添加的那個參數更新。暫時沒有找到解決方法,只能自己更新cookie,而不使用session。

我在拉勾的cookie上浪費了大量的時間,取得的效果比較低,其實在實際爬去過程中根本不需要攜帶登錄的cookie。只需要使用遊客cookie就能拿到所需的數據,當然當你某個IP獲取了大量的遊客cookie之後會被封,但是爬蟲想要大數據量,代理是肯定要的。

百度上的一些文章都是每發送一個POST請求前都向目標網頁發送一個GET請求來更新cookie,我測試了一下,這並不是更新cookie而是重新獲取一個新的cookie,這樣是不可取的,一個遊客cookie實際可以發送10個POST請求,5個GET請求,這樣做就太浪費cookie,可能直接導致IP被封的時間提前很多。所以我們可以每發送10個POST請求就重新獲取一個cookie(中間可以加一個適當的延遲),再加上代理池完全可以拿到拉勾整站的職位數據。我並沒有測試一個IP爬多長時間會被封,我試着間隔一秒來運行了10分鐘也沒有問題,這就已經足夠滿足實際需求了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章