由於想要找到一個數據分析的工做,可以瞭解到市面上現有的職位招聘信息也會對找工做有所幫助。python
今天就來爬取一下智聯招聘上數據分析師的招聘信息,並存入本地的MySQL。mysql
打開智聯招聘首頁,選擇數據分析師職位,跳轉進入數據分析師的詳情頁面。咱們須要抓取的數據都呈如今這裏。sql
既然咱們想要的數據都在這個頁面上,那麼就對頁面分析一下,這些數據都是用什麼方式傳輸的。數據庫
首先右鍵查看網頁源代碼,發現職位信息並不在源代碼裏面。也就是說,職位信息是經過其餘來源加載的,並非直接寫入這個網頁的代碼裏。json
右鍵檢查,找到network一覽進行查看,發現職位信息實際上是來源於接口返回的一個json格式的數據。因此咱們要抓取的數據就來源於這個接口:api
由2.1,咱們已經找到數據來源的url爲 dom
https://fe-api.zhaopin.com/c/i/sou?pageSize=90&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.55861702&x-zp-page-request-id=112663d962234d3e8ca52b6e9d5ab4ea-1545222165002-62086url
這個url中包含了不少參數,分別對應在職位搜索時加入的條件:spa
pageSize:指每一頁顯示的職位數量,也就是經過url一次取多少數設計
cityId:指職位的城市劃分,489表明全國
workExperience:指職位要求的工做經驗
education:職位要求的學歷水平
companyType:公司的經營類別
employmentType:職位的性質,如實習/全職/兼職
jobWelfareTag:福利
kw:搜索關鍵字,若是關鍵字包含漢字,則進行url轉碼。如:此處,數據分析師轉碼爲%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88
kt/_v/x-zp-request-id:暫時沒有弄明白具體是指什麼
上面的url只是搜索結果第一頁對應的來源,而咱們的搜索結果實際上是有不少頁進行展現的。
經過一樣的方式,能夠拿到搜索結果接下來幾頁對應的url。
以第二頁對應的url爲例:
https://fe-api.zhaopin.com/c/i/sou?start=90&pageSize=90&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.55861702&x-zp-page-request-id=112663d962234d3e8ca52b6e9d5ab4ea-1545222165002-62086
對比以後,發現:區別之處僅僅在於第二頁對應的url加入了一個start參數。
start=90,即爲第二頁的搜索結果。結合pageSize參數,每一頁展現90條職位信息。也就是說,start=90表示第二頁,start=180表示第三頁......
咱們就知道了如何去獲得每一頁搜索結果對應的數據來源了。
既然咱們已經發現了,每一頁的職位信息都來自於訪問接口後返回的json格式的數據,咱們就能夠直接訪問接口而後讀取json就能夠獲得想要的職位信息了。
步驟以下:
1) 設定關鍵字訪問接口,得到包含職位信息的json數據
2) 從返回的json中提取須要的數據,存入本地MySQL中
由於這些職位數據是沒有通過登錄就能夠獲取的,並且在請求頭中並無發現什麼特別的信息。嘗試後發現,智聯招聘對傳輸職位信息的這個接口沒有作什麼反爬限制,直接使用urllib包的urlopen()方法就能夠得到數據。
import pymysql import urllib import json import time import random # 在sql中建立表 def create_table_mysql(): db = pymysql.connect(host='localhost', user='root', password='mysqlkey', db='test_db', port=3306) # 建立遊標對象cursor cursor = db.cursor() # 執行SQL,若是表存在就刪除 cursor.execute('DROP TABLE IF EXISTS zlzp_sjfx') # 建立表 create_table_sql = """ CREATE TABLE zlzp_sjfx( job_number CHAR(100) COMMENT '記錄編號', job_type_big_num CHAR(100) COMMENT '職業大分類編號', job_type_big_name CHAR(100) COMMENT '職業大分類名稱', job_type_medium_num CHAR(100) COMMENT '職業細分類編號', job_type_medium_name CHAR(100) COMMENT '職業細分類名稱', company_num CHAR(100) COMMENT '公司編號', company_url CHAR(200) COMMENT '公司對應url', company_name CHAR(100) COMMENT '公司名稱', company_size_num CHAR(100) COMMENT '公司規模編號', company_size CHAR(100) COMMENT '公司規模', company_type_num CHAR(100) COMMENT '公司類型編號', company_type CHAR(100) COMMENT '公司類型', job_url CHAR(200) COMMENT '職位對應url', working_exp_num CHAR(100) COMMENT '工做經驗編號', working_exp CHAR(100) COMMENT '工做經驗', edu_level_num CHAR(100) COMMENT '教育水平編號', edu_level CHAR(100) COMMENT '教育水平', job_salary CHAR(100) COMMENT '工資', job_type CHAR(100) COMMENT '工做類型', job_name CHAR(100) COMMENT '工做類型', job_location_lat CHAR(100) COMMENT '經度', job_location_lon CHAR(100) COMMENT '緯度', job_city CHAR(100) COMMENT '工做城市', job_updatetime CHAR(100) COMMENT '更新時間', job_createtime CHAR(100) COMMENT '建立時間', job_endtime CHAR(100) COMMENT '結束時間', job_welfare CHAR(100) COMMENT '工做福利' )""" try: # 建立表 cursor.execute(create_table_sql) # 提交執行 db.commit() print('table zlzp_sjfx create done') except: # 回滾 db.rollback() print('table zlzp_sjfx create not done') return db, cursor db, cursor = create_table_mysql() time_0 = time.time() for i in range(500): url = 'https://fe-api.zhaopin.com/c/i/sou?start={}&pageSize=90&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.89067574&x-zp-page-request-id=866368d6313e41c38a6e600b1c5d8082-1545034860140-256948'.format(i*90) if i==0: url = 'https://fe-api.zhaopin.com/c/i/sou?pageSize=90&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.89067574&x-zp-page-request-id=866368d6313e41c38a6e600b1c5d8082-1545034860140-256948' page = urllib.request.urlopen(url).read() data = json.loads(page) time.sleep(random.uniform(1.2, 2.1)) add_sql = """ INSERT INTO zlzp_sjfx (job_number, job_type_big_num, job_type_big_name,job_type_medium_num,job_type_medium_name,company_num,company_url,company_name, company_size_num, company_size, company_type_num, company_type, job_url, working_exp_num, working_exp, edu_level_num, edu_level, job_salary, job_type, job_name, job_location_lat, job_location_lon, job_city, job_updatetime, job_createtime, job_endtime, job_welfare) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) """ for each_job in data['data']['results']: add_data = ( each_job['number'], # 編號 each_job['jobType']['items'][0]['code'], # 職業大分類編號 each_job['jobType']['items'][0]['name'], # 職業大分類名稱 each_job['jobType']['items'][1]['code'], # 職業細分類編號 each_job['jobType']['items'][1]['name'], # 職業細分類名稱 each_job['company']['number'], # 公司編號 each_job['company']['url'], # 公司對應url each_job['company']['name'], # 公司名稱 each_job['company']['size']['code'], # 公司規模編號 each_job['company']['size']['name'], # 公司規模 each_job['company']['type']['code'], # 公司類型編號 each_job['company']['type']['name'], # 公司類型 each_job['positionURL'], # 職位對應url each_job['workingExp']['code'], # 工做經驗編號 each_job['workingExp']['name'], # 工做經驗 each_job['eduLevel']['code'], # 教育水平編號 each_job['eduLevel']['name'], # 教育水平 each_job['salary'], # 工資 each_job['emplType'], # 工做類型 each_job['jobName'], # 工做名稱 each_job['geo']['lat'], # 經度 each_job['geo']['lon'], # 緯度 each_job['city']['display'], # 工做城市 each_job['updateDate'], each_job['createDate'], each_job['endDate'], '/'.join(each_job['welfare']) # 工做福利 ) cursor.execute(add_sql, add_data) try: db.commit() print('page', i, 'done!用時', time.time()-time_0) except: db.rollback() print('page', i, 'not done') # 關閉遊標 cursor.close() # 關閉數據庫鏈接 db.close()