智聯招聘爬蟲原始碼分析(一)
最近一直在關注秋招,雖然還沒輪到我,不過提前準備總是好的。近期聽聞今年秋招形勢嚴峻,為了更好的準備將來的實習、工作,我決定在招聘網站上爬取一些與資料有關的崗位資訊,藉以給自己將來的職業道路選擇提供參考。
一、原理
通過Python的requests庫,向網站伺服器傳送請求,伺服器返回相關網頁的原始碼,再通過正則表示式等方式在網頁原始碼中提取出我們想要的資訊。
二、網頁分析
2.1崗位詳情url
在智聯招聘網站中搜索'大資料',跳轉到大資料崗位頁面,接下來我們點開開發者選項,重新整理頁面,在Network面板的XHR中發現了這樣一個數據包:
XHR: XHR為向伺服器傳送請求和解析伺服器響應提供了流暢的介面,能夠以非同步方式從伺服器取得更多資訊,意味著使用者單擊後,可以不必重新整理頁面也能取得新資料
在新的頁面開啟後:
這個頁面裡出現的所有的崗位資訊都在裡面了:崗位名稱、公司名稱、薪水、地區、詳情介面的url都在該json裡。但是這些資訊都不是最重要的,我需要崗位要求以及崗位職責的要求。
將該json解析,得到如下結構的json資料:
code的值為HTTP的響應碼,200表示請求成功。而results陣列則是該頁面崗位資訊的資料。點開第一條資料(results的第一個元素):
頁面中出現的所有資料,以及相關的超連結都在這兒。其中,我們需要的是指向崗位詳情介面的超連結——'positionURL'。點選該連結,進去該崗位資訊詳情頁面:
好了,我們需要的資訊出現了,不過為了簡化頁面分析的操作,以及儘可能地不被反爬,我決定選擇移動適配的頁面。
再開啟開發者選項,在該崗位詳情頁面,重新整理:
在<meta>中找到'mobile-agent',提取後面的url——'url=//m.zhaopin.com/jobs/CZ745244850J00020982209/',開啟:
真清爽!
2.2 Xpath定位
XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文件中某部分位置的語言
分析該網頁的原始碼,尋找我們所需資訊的位置:
崗位名稱、月薪、公司、地區、學歷、年限資訊都在'//*[@id="r_content"]/div[1]/div/div[1]/div[1]/'下。
- title = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/h1/text()')
- pay = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/div[1]/text()')
- place = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[1]/text()')
- campanyName = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[2]/text()')
- edu = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[3]/text()')
崗位要求與崗位職責在同一個<div>標籤裡:
也爬出來:
- comment = selector.xpath('//*[@id="r_content"]/div[1]/div/article/div/p/text()')
好了,最複雜的部分搞定。
三、JSON資料包地址
我們將前三頁的資料包地址比對一下就能看出問題:
- https://fe-api.zhaopin.com/c/i/sou?pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474
- https://fe-api.zhaopin.com/c/i/sou?start=60&pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474
- https://fe-api.zhaopin.com/c/i/sou?start=120&pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474
- https://fe-api.zhaopin.com/c/i/sou?start=180&pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E5%A4%A7%E6%95%B0%E6%8D%AE&kt=3&_v=0.14571817&x-zp-page-request-id=ce8cbb93b9ad4372b4a9e3330358fe7c-1541763191318-555474
1.我們可以看出第一頁的url結構與後面的url結構有明顯的不同。
2.非首頁的url有明顯的規律性。
3.'kw=*&kt'裡的字元為'大資料'的UTF-8編碼。
所以我們對資料包有如下的操作:
- if __name__ == '__main__':
- key = '大資料'
- url = 'https://fe-api.zhaopin.com/c/i/sou?pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=' + key + '&kt=3&lastUrlQuery=%7B%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22%E5%A4%A7%E6%95%B0%E6%8D%AE%22,%22kt%22:%223%22%7D'
- infoUrl(url)
- urls = ['https://fe-api.zhaopin.com/c/i/sou?start={}&pageSize=60&cityId=489&kw='.format(i*60)+key+'&kt=3&lastUrlQuery=%7B%22p%22:{},%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22java%22,%22kt%22:%223%22%7D'.format(i) for i in range(1,50)]
- for url in urls:
- infoUrl(url)
四、原始碼結構
1、擷取整個結果介面的JSON資料包,從中提取出各個招聘欄的url。
2、進入招聘詳細資訊頁面,提取移動端url。
3、進入移動端介面,抓取需要的資訊。
五、原始碼
- '''''
- 智聯招聘——爬蟲原始碼————2018.11
- '''
- import requests
- import re
- import time
- from lxml import etree
- import csv
- import random
- fp = open('智聯招聘.csv','wt',newline='',encoding='UTF-8')
- writer = csv.writer(fp)
- '''''地區,公司名,學歷,崗位描述,薪資,福利,釋出時間,工作經驗,連結'''
- writer.writerow(('職位','公司','地區','學歷','崗位','薪資','福利','工作經驗','連結'))
- def info(url):
- res = requests.get(url)
- u = re.findall('<meta name="mobile-agent" content="format=html5; url=(.*?)" />', res.text)
- if len(u) > 0:
- u = u[-1]
- else:
- return
- u = 'http:' + u
- headers ={
- 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'
- }
- res = requests.get(u,headers=headers)
- selector = etree.HTML(res.text)
- # # 崗位名稱
- title = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/h1/text()')
- # # 崗位薪資
- pay = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[1]/div[1]/text()')
- # # 工作地點
- place = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[1]/text()')
- # # 公司名稱
- companyName = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[2]/text()')
- # # 學歷
- edu = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[3]/text()')
- # # 福利
- walfare = selector.xpath('//*[@id="r_content"]/div[1]/div/div[3]/span/text()')
- # # 工作經驗
- siteUrl = res.url
- workEx = selector.xpath('//*[@id="r_content"]/div[1]/div/div[1]/div[3]/div[1]/span[2]/text()')
- # # 崗位詳細
- comment = selector.xpath('//*[@id="r_content"]/div[1]/div/article/div/p/text()')
- writer.writerow((title, companyName, place, edu, comment, pay, walfare, workEx, siteUrl))
- print(title, companyName, place, edu, comment, pay, walfare, workEx, siteUrl)
- def infoUrl(url):
- res = requests.get(url)
- selector = res.json()
- code = selector['code']
- if code == 200:
- data = selector['data']['results']
- for i in data:
- href = i['positionURL']
- info(href)
- time.sleep(random.randrange(1,4))
- if __name__ == '__main__':
- key = '大資料'
- url = 'https://fe-api.zhaopin.com/c/i/sou?pageSize=60&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=' + key + '&kt=3&lastUrlQuery=%7B%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22%E5%A4%A7%E6%95%B0%E6%8D%AE%22,%22kt%22:%223%22%7D'
- infoUrl(url)
- urls = ['https://fe-api.zhaopin.com/c/i/sou?start={}&pageSize=60&cityId=489&kw='.format(i*60)+key+'&kt=3&lastUrlQuery=%7B%22p%22:{},%22pageSize%22:%2260%22,%22jl%22:%22489%22,%22kw%22:%22java%22,%22kt%22:%223%22%7D'.format(i) for i in range(1,50)]
- for url in urls:
- infoUrl(url)
Ps.因為某些原因,我打算每個月爬取智聯招聘、51job的崗位資訊一次,原始碼、優化都會以部落格的形式寫出來,歡迎關注~
原始碼地址:智聯招聘_爬蟲原始碼