秋招季,用Python分析深圳程式設計師工資有多高?

  • 2019 年 10 月 8 日
  • 筆記

作者 | zone7

來源 | zone7

前言

多圖預警、多圖預警、多圖預警。秋招季,畢業也多,跳槽也多。我們的職業發展還是要順應市場需求,那麼各門程式語言在深圳的需求怎麼呢?工資待遇怎麼樣呢?zone 在上次寫了這篇文章之後 用Python告訴你深圳房租有多高 ,想繼續用 Python 分析一下,當前深圳的求職市場怎麼樣?順便幫一下秋招的同學。於是便爬取了某拉鉤招聘數據。以下是本次爬蟲的樣本數據:

樣本

本次統計數據量為 4658 ,其中某拉鉤最多能顯示 30 頁數據,每頁 15 條招聘資訊,則總為:

30 x 15 = 450

首頁爬取跳過一頁,則為 435 條,故數據基本爬完。其餘不夠數量的語言為該語言在深圳只有這麼多條招聘資訊。

統計結果

各語言平均工資 其中

  • 精準推薦
  • 自然語言
  • 機器學習
  • Go 語言
  • 影像識別

獨領風騷啊!!!平均工資都挺高的。區塊鏈炒得挺火的,好像平均薪資並沒有那麼高。我統計完之後,感覺自己拖後腿了,ma 的!!!要刪庫跑路了!(註:下圖為月薪,單位:K)

各語言平均薪資

平均工資計算方式:

某鉤 item

最高值與最低值,求平均數,如圖薪資則為:

(10k + 20k)/2 = 15k

最後,再總體求平均數。 公司福利詞雲 看福利還是挺豐富的,帶薪休假、下午茶、零食、節假日。

福利詞雲

公司發展級別排行 總體由 A 輪向 D 輪縮減,大部分公司不需要融資,嗯,估計是拿不到資本融資,但是自家人又有錢的。

公司發展級別

各語言工作年限要求與學歷要求 看看你的本命語言的市場需求怎麼樣?你達標了嗎?其中三至五年的攻城獅職位挺多的,不怕找不到工作。還有一個趨勢是,薪資越高,學歷要求越高高。看來學歷還是挺重要的。

Java

Java 工作年限要求

Java 學歷要求

Python

Python 工作年限要求

Python 學歷要求

C 語言

C 語言工作年限要求

C 語言學歷要求

機器學習

機器學習工作年限要求

機器學習學歷要求

影像識別

影像識別工作年限要求

影像識別學歷要求

自然語言

自然語言工作年限要求

自然語言學歷要求

區塊鏈

區塊鏈工作年限要求

區塊鏈學歷要求

Go 語言

Go 語言工作年限要求

Go

PHP

PHP 工作年限要求

PHP 學歷要求

爬蟲技術分析

  • 請求庫:selenium
  • HTML 解析:BeautifulSoup、xpath
  • 詞云:wordcloud
  • 數據可視化:pyecharts
  • 資料庫:MongoDB
  • 資料庫連接:pymongo

爬蟲程式碼實現

看完統計結果之後,有沒有躍躍欲試?想要自己也實現以下程式碼?以下為程式碼實現。 對網頁右擊,點擊檢查,找到一條 item 的數據:

網頁源碼

資料庫存儲結構:

/* 1 */  {      "_id" : ObjectId("5b8b89328ffaed60a308bacd"),      "education" : "本科",# 學習要求      "companySize" : "2000人以上",# 公司人數規模      "name" : "python開發工程師",# 職位名稱      "welfare" : "「朝九晚五,公司平台大,發展機遇多,六險一金」",# 公司福利      "salaryMid" : 12.5,# 工資上限與工資下限的平均數      "companyType" : "移動互聯網",# 公司類型      "salaryMin" : "10",# 工資下限      "salaryMax" : "15",# 工資上限      "experience" : "經驗3-5年",# 工作年限      "companyLevel" : "不需要融資",# 公司級別      "company" : "XXX技術有限公司"# 公司名稱  }  

由於篇幅原因,以下只展示主要程式碼:

# 獲取網頁源碼數據  # language => 程式語言  # city => 城市  # collectionType => 值:True/False  True => 資料庫表以程式語言命名   False => 以城市命名  def main(self, language, city, collectionType):      print(" 當前爬取的語言為 => " + language + "  當前爬取的城市為 => " + city)      url = self.getUrl(language, city)      browser = webdriver.Chrome()      browser.get(url)      browser.implicitly_wait(10)      for i in range(30):          selector = etree.HTML(browser.page_source)  # 獲取源碼          soup = BeautifulSoup(browser.page_source, "html.parser")          span = soup.find("div", attrs={"class": "pager_container"}).find("span", attrs={"action": "next"})          print(              span)  # <span action="next" class="pager_next pager_next_disabled" hidefocus="hidefocus">下一頁<strong class="pager_lgthen pager_lgthen_dis"></strong></span>          classArr = span['class']          print(classArr)  # 輸出內容為 -> ['pager_next', 'pager_next_disabled']          attr = list(classArr)[0]          attr2 = list(classArr)[1]          if attr2 == "pager_next_disabled":#分析發現 class 屬性為  ['pager_next', 'pager_next_disabled'] 時,【下一頁】按鈕不可點擊              print("已經爬到最後一頁,爬蟲結束")              break          else:              print("還有下一頁,爬蟲繼續")              browser.find_element_by_xpath('//*[@id="order"]/li/div[4]/div[2]').click()  # 點擊【下一頁】按鈕          time.sleep(5)          print('第{}頁抓取完畢'.format(i + 1))          self.getItemData(selector, language, city, collectionType)# 解析 item 數據,並存進資料庫      browser.close()  

爬蟲分析實現

# 獲取各語言樣本數量  def getLanguageNum(self):      analycisList = []      for index, language in enumerate(self.getLanguage()):          collection = self.zfdb["z_" + language]          totalNum = collection.aggregate([{'$group': {'_id': '', 'total_num': {'$sum': 1}}}])          totalNum2 = list(totalNum)[0]["total_num"]          analycisList.append(totalNum2)      return (self.getLanguage(), analycisList)    # 獲取各語言的平均工資  def getLanguageAvgSalary(self):      analycisList = []      for index, language in enumerate(self.getLanguage()):          collection = self.zfdb["z_" + language]          totalSalary = collection.aggregate([{'$group': {'_id': '', 'total_salary': {'$sum': '$salaryMid'}}}])          totalNum = collection.aggregate([{'$group': {'_id': '', 'total_num': {'$sum': 1}}}])          totalNum2 = list(totalNum)[0]["total_num"]          totalSalary2 = list(totalSalary)[0]["total_salary"]          analycisList.append(round(totalSalary2 / totalNum2, 2))      return (self.getLanguage(), analycisList)    # 獲取一門語言的學歷要求(用於 pyecharts 的詞雲)  def getEducation(self, language):      results = self.zfdb["z_" + language].aggregate([{'$group': {'_id': '$education', 'weight': {'$sum': 1}}}])      educationList = []      weightList = []      for result in results:          educationList.append(result["_id"])          weightList.append(result["weight"])      # print(list(result))      return (educationList, weightList)    # 獲取一門語言的工作年限要求(用於 pyecharts 的詞雲)  def getExperience(self, language):      results = self.zfdb["z_" + language].aggregate([{'$group': {'_id': '$experience', 'weight': {'$sum': 1}}}])      totalAvgPriceDirList = []      for result in results:          totalAvgPriceDirList.append(              {"value": result["weight"], "name": result["_id"] + "  " + str(result["weight"])})      return totalAvgPriceDirList    # 獲取 welfare 數據,用於構建福利詞雲  def getWelfare(self):      content = ''      queryArgs = {}      projectionFields = {'_id': False, 'welfare': True}  # 用字典指定      for language in self.getLanguage():            collection = self.zfdb["z_" + language]          searchRes = collection.find(queryArgs, projection=projectionFields).limit(1000)          for result in searchRes:              print(result["welfare"])              content += result["welfare"]      return content    # 獲取公司級別排行(用於條形圖)  def getAllCompanyLevel(self):      levelList = []      weightList = []      newWeightList = []      attrList = ["A輪", "B輪", "C輪", "D輪及以上", "不需要融資", "上市公司"]      for language in self.getLanguage():          collection = self.zfdb["z_" + language]          # searchRes = collection.find(queryArgs, projection=projectionFields).limit(1000)          results = collection.aggregate([{'$group': {'_id': '$companyLevel', 'weight': {'$sum': 1}}}])          for result in results:              levelList.append(result["_id"])              weightList.append(result["weight"])      for index, attr in enumerate(attrList):          newWeight = 0          for index2, level in enumerate(levelList):              if attr == level:                  newWeight += weightList[index2]          newWeightList.append(newWeight)      return (attrList, newWeightList)