因爲須要,本人須要對大街網招聘信息進行分析,故寫了個爬蟲進行爬取。這裏我將記錄一下,本人爬取大街網的思路。程序員
附:爬取得數據僅供本身分析所用,並未用做其它用途。 ajax
附:本篇適合有必定 爬蟲基礎 crawler 觀看,有什麼沒搞明白的,歡迎你們留言,或者私信博主。sql
首先,打開目標網址 www.dajie.com ,在職位搜索中 輸入所需職業或關鍵信息 (我這演示的是 程序員),而後可獲得新的連接地址 https://so.dajie.com/job/search?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&from=job瀏覽器
咱們能夠看到 ,數據的排序方式有2種,一種是 默認 ,一種是 時間 ,當你點擊的時候你能夠看到 數據的排序方式發生了變化,可是網頁連接卻沒有變化,並且點擊 下一頁 的時候頁面的連接也沒有發生變化,其緣由是 當你對其操做時,它經過服務器
JS獲取ajax數據進行變換填充,因此若是你要獲取所需數據,你只能經過獲取其ajax數據。(固然還有模擬JS渲染,獲得頁面,我沒有嘗試過,這裏也不作多述)cookie
那麼如何獲取到其數據呢?session
當你單擊 下一頁 等操做時,經過抓包(XHR中)能夠查看到ajax數據的來源,查看的時候能夠看到其返回的是200(所需的數據),但當你在新的頁面打開時,卻發現返回的是299,不是你想要的結果。如一下這個連接就是對其進行時間排序所得app
的ajax(https://so.dajie.com/job/ajax/search/filter?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&order=1&city=&recruitType=&salary=&experience=&page=1&positionFunction=&_CSRFToken=&ajax=1)dom
可是若是你是單獨打開它的時候,它返回的是一個錯誤的頁面,這應該是 大街網 反爬蟲的一種手段。 ide
找到了返回的ajax地址連接,咱們該如何正確的打開這個連接呢?
當咱們打開這個 連接時(https://so.dajie.com/job/search?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&from=job)會發現服務器端回返回一個 Cookie
所以 當你訪問 (https://so.dajie.com/job/ajax/search/filter?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&order=1&city=&recruitType=&salary=&experience=&page=1&positionFunction=&_CSRFToken=&ajax=1)
連接時,你必需要傳入服務器返回的cookie 纔可以獲取到正確的結果。
下面附上本人寫的代碼,僅供參考。
其中須要注意的是:這些代碼僅提供一個思路,裏面的不少變量、類都是我項目裏面的。
這裏統一作一下解釋
#from myproject.dajie import Jobs, IpAgentPool 指引入 Ip 池,Jobs所須要爬取得 關鍵字集合.(下面演示時用不到的)
#from myproject import agentPool 引入 Agent池, 用做假裝瀏覽器使用
1 from myproject.dajie import Jobs, IpAgentPool 2 from myproject import agentPool 3 import http.cookiejar 4 import urllib.request 5 import urllib.parse 6 import random 7 import re 8 #import pymssql 9 10 class dj(): 11 12 def __init__(self): 13 # -----BASEURL 爲目標網站的URL 14 # -----ToSearchJob 爲須要搜尋的工做 15 # -----Agent 爲Agent池,用於假裝瀏覽器 16 # -----opener 爲本身建造的一個opener,配合cookiejar可用於存儲cookies 17 def Myopener(self): 18 cookie = http.cookiejar.CookieJar() 19 return urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie)) 20 21 self.BASEURL = "https://www.dajie.com/" 22 # self.ToSearchJob=Jobs.TheJobNeedToSearch 23 self.AgentPool = agentPool.userAgent 24 self.IpPool = IpAgentPool.ipPool 25 26 self.opener = Myopener(self=self) 27 28 pass 29 30 def getContext(self): 31 url="https://so.dajie.com/job/search?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&from=job" 32 33 header=\ 34 { 35 "User-Agent":agentPool.userAgent[int(random.random()*4)], 36 "Referer":"https://so.dajie.com/job/search?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&from=job" 37 } 38 39 head=[] 40 41 for key,value in header.items(): 42 head.append((key,value)) 43 44 self.opener.addheaders=head 45 46 #session_cookie用於保存服務器返回的cookie,並將其保存 47 # 48 #其實只須要保存 session_cookie["SO_COOKIE_V2"] 便可,其他的是多餘的。服務器在進行驗證的時候,只會驗證 SO_COOKIE_V2 49 # 50 session_cookie={} 51 session=self.opener.open("https://so.dajie.com/job/search?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&from=job") 52 print((session.info())) 53 54 session_cookie["DJ_RF"]= re.findall(r"DJ_RF=.+?;",str(session.info()))[0].split("=")[1] 55 session_cookie["DJ_EU"]=re.findall(r"DJ_EU=.+?;",str(session.info()))[0].split("=")[1] 56 session_cookie["DJ_UVID"] = re.findall(r"DJ_UVID=.+?;", str(session.info()))[0].split("=")[1] 57 session_cookie["SO_COOKIE_V2"] = re.findall(r"SO_COOKIE_V2=.+?;", str(session.info()))[0].split("=")[1] 58 59 #data 包含的是所須要傳入的 cookie 60 data=\ 61 { 62 "DJ_RF":session_cookie["DJ_RF"].strip(";"), 63 "DJ_EU":session_cookie["DJ_EU"].strip(";"), 64 "DJ_UVID":session_cookie["DJ_UVID"].strip(";"), 65 "SO_COOKIE_V2":session_cookie["SO_COOKIE_V2"].strip(";"), 66 "__login_tips":1, 67 } 68 #將 數據解析爲傳入數據的格式 69 _data=urllib.parse.urlencode(data,"utf-8") 70 print("______________") 71 print(_data) 72 # 73 #_url 指的是ajax的連接地址 74 _url="https://so.dajie.com/job/ajax/search/filter?keyword=%E7%A8%8B%E5%BA%8F%E5%91%98&order=1&city=&recruitType=&salary=&experience=&page=1&positionFunction=&_CSRFToken=&ajax=1" 75 req=self.opener.open(_url,data=_data.encode("utf-8")) 76 77 print("-----------------") 78 print(req.read().decode("utf-8")) 79 80 #print(req.read().decode("utf-8")) 81 82 83 84 if __name__=="__main__": 85 _dj=dj() 86 _dj.getContext()
最後附上運行結果的截圖