Python開發在北京的就業現狀分析
相信各位同學多多少少在拉鉤上投過簡歷,今天突然想了解一下北京Python開發的薪資水平、招聘要求、福利待遇以及公司地理位置。既然要分析那必然是現有數據樣本。本文通過爬蟲和數據分析為大家展示一下北京Python開發的現狀,希望能夠在職業規劃方面幫助到大家!!!
爬蟲
爬蟲的第一步自然是從分析請求和網頁源代碼開始。從網頁源代碼中我們并不能找到發布的招聘信息。但是在請求中我們看到這樣一條POST請求
如下圖我們可以得知
- url:https://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false
- 請求方式:post
- result:為發布的招聘信息
- totalCount:為招聘信息的條數
通過實踐發現除了必須攜帶headers之外,拉勾網對ip訪問頻率也是有限制的。一開始會提示 '訪問過于頻繁',繼續訪問則會將ip拉入黑名單。不過一段時間之后會自動從黑名單中移除。
針對這個策略,我們可以對請求頻率進行限制,這個弊端就是影響爬蟲效率。
其次我們還可以通過代理ip來進行爬蟲。網上可以找到免費的代理ip,但大都不太穩定。付費的價格又不太實惠。
具體就看大家如何選擇了
1思路
通過分析請求我們發現每頁返回15條數據,totalCount又告訴了我們該職位信息的總條數。
向上取整就可以獲取到總頁數。然后將所得數據保存到csv文件中。這樣我們就獲得了數據分析的數據源!
post請求的Form Data傳了三個參數
- first : 是否首頁(并沒有什么用)
- pn:頁碼
- kd:搜索關鍵字
2no bb, show code
- # 獲取請求結果
- # kind 搜索關鍵字
- # page 頁碼 默認是1
- def get_json(kind, page=1,):
- # post請求參數
- param = {
- 'first': 'true',
- 'pn': page,
- 'kd': kind
- }
- header = {
- 'Host': 'www.lagou.com',
- 'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=',
- 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
- }
- # 設置代理
- proxies = [
- {'http': '140.143.96.216:80', 'https': '140.143.96.216:80'},
- {'http': '119.27.177.169:80', 'https': '119.27.177.169:80'},
- {'http': '221.7.255.168:8080', 'https': '221.7.255.168:8080'}
- ]
- # 請求的url
- url = 'https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false'
- # 使用代理訪問
- # response = requests.post(url, headers=header, data=param, proxies=random.choices(proxies))
- response = requests.post(url, headers=header, data=param, proxies=proxies)
- response.encoding = 'utf-8'
- if response.status_code == 200:
- response = response.json()
- # 請求響應中的positionResult 包括查詢總數 以及該頁的招聘信息(公司名、地址、薪資、福利待遇等...)
- return response['content']['positionResult']
- return None
接下來我們只需要每次翻頁之后調用 get_json 獲得請求的結果 再遍歷取出需要的招聘信息即可
- if __name__ == '__main__':
- # 默認先查詢第一頁的數據
- kind = 'python'
- # 請求一次 獲取總條數
- position_result = get_json(kind=kind)
- # 總條數
- total = position_result['totalCount']
- print('{}開發職位,招聘信息總共{}條.....'.format(kind, total))
- # 每頁15條 向上取整 算出總頁數
- page_total = math.ceil(total/15)
- # 所有查詢結果
- search_job_result = []
- #for i in range(1, total + 1)
- # 為了節約效率 只爬去前100頁的數據
- for i in range(1, 100):
- position_result = get_json(kind=kind, page= i)
- # 每次抓取完成后,暫停一會,防止被服務器拉黑
- time.sleep(15)
- # 當前頁的招聘信息
- page_python_job = []
- for j in position_result['result']:
- python_job = []
- # 公司全名
- python_job.append(j['companyFullName'])
- # 公司簡稱
- python_job.append(j['companyShortName'])
- # 公司規模
- python_job.append(j['companySize'])
- # 融資
- python_job.append(j['financeStage'])
- # 所屬區域
- python_job.append(j['district'])
- # 職稱
- python_job.append(j['positionName'])
- # 要求工作年限
- python_job.append(j['workYear'])
- # 招聘學歷
- python_job.append(j['education'])
- # 薪資范圍
- python_job.append(j['salary'])
- # 福利待遇
- python_job.append(j['positionAdvantage'])
- page_python_job.append(python_job)
- # 放入所有的列表中
- search_job_result += page_python_job
- print('第{}頁數據爬取完畢, 目前職位總數:{}'.format(i, len(search_job_result)))
- # 每次抓取完成后,暫停一會,防止被服務器拉黑
- time.sleep(15)
ok! 數據我們已經獲取到了,最后一步我們需要將數據保存下來
- # 將總數據轉化為data frame再輸出
- df = pd.DataFrame(data=search_job_result,
- columns=['公司全名', '公司簡稱', '公司規模', '融資階段', '區域', '職位名稱', '工作經驗', '學歷要求', '工資', '職位福利'])
- df.to_csv('lagou.csv', index=False, encoding='utf-8_sig')
運行main方法直接上結果:
數據分析
通過分析cvs文件,為了方便我們統計,我們需要對數據進行清洗
比如剔除實習崗位的招聘、工作年限無要求或者應屆生的當做 0年處理、薪資范圍需要計算出一個大概的值、學歷無要求的當成大專
- # 讀取數據
- df = pd.read_csv('lagou.csv', encoding='utf-8')
- # 數據清洗,剔除實習崗位
- df.drop(df[df['職位名稱'].str.contains('實習')].index, inplace=True)
- # print(df.describe())
- # 由于CSV文件內的數據是字符串形式,先用正則表達式將字符串轉化為列表,再取區間的均值
- pattern = 'd+'
- df['work_year'] = df['工作經驗'].str.findall(pattern)
- # 數據處理后的工作年限
- avg_work_year = []
- # 工作年限
- for i in df['work_year']:
- # 如果工作經驗為'不限'或'應屆畢業生',那么匹配值為空,工作年限為0
- if len(i) == 0:
- avg_work_year.append(0)
- # 如果匹配值為一個數值,那么返回該數值
- elif len(i) == 1:
- avg_work_year.append(int(''.join(i)))
- # 如果匹配值為一個區間,那么取平均值
- else:
- num_list = [int(j) for j in i]
- avg_year = sum(num_list)/2
- avg_work_year.append(avg_year)
- df['工作經驗'] = avg_work_year
- # 將字符串轉化為列表,再取區間的前25%,比較貼近現實
- df['salary'] = df['工資'].str.findall(pattern)
- # 月薪
- avg_salary = []
- for k in df['salary']:
- int_list = [int(n) for n in k]
- avg_wage = int_list[0]+(int_list[1]-int_list[0])/4
- avg_salary.append(avg_wage)
- df['月工資'] = avg_salary
- # 將學歷不限的職位要求認定為最低學歷:大專
- df['學歷要求'] = df['學歷要求'].replace('不限','大專')
數據通過簡單的清洗之后,下面開始我們的統計
1繪制薪資直方圖
- # 繪制頻率直方圖并保存
- plt.hist(df['月工資'])
- plt.xlabel('工資 (千元)')
- plt.ylabel('頻數')
- plt.title("工資直方圖")
- plt.savefig('薪資.jpg')
- plt.show()
結論:北京市Python開發的薪資大部分處于15~25k之間
2公司分布餅狀圖
- # 繪制餅圖并保存
- count = df['區域'].value_counts()
- plt.pie(count, labels = count.keys(),labeldistance=1.4,autopct='%2.1f%%')
- plt.axis('equal') # 使餅圖為正圓形
- plt.legend(loc='upper left', bbox_to_anchor=(-0.1, 1))
- plt.savefig('pie_chart.jpg')
- plt.show()
結論:Python開發的公司最多的是海淀區、其次是朝陽區。準備去北京工作的小伙伴大概知道去哪租房了吧
3學歷要求直方圖
- # {'本科': 1304, '大專': 94, '碩士': 57, '博士': 1}
- dict = {}
- for i in df['學歷要求']:
- if i not in dict.keys():
- dict[i] = 0
- else:
- dict[i] += 1
- index = list(dict.keys())
- print(index)
- num = []
- for i in index:
- num.append(dict[i])
- print(num)
- plt.bar(left=index, height=num, width=0.5)
- plt.show()
結論:在Python招聘中,大部分公司要求是本科學歷以上。但是學歷只是個敲門磚,如果努力提升自己的技術,這些都不是事兒
4福利待遇詞云圖
- # 繪制詞云,將職位福利中的字符串匯總
- text = ''
- for line in df['職位福利']:
- text += line
- # 使用jieba模塊將字符串分割為單詞列表
- cut_text = ' '.join(jieba.cut(text))
- #color_mask = imread('cloud.jpg') #設置背景圖
- cloud = WordCloud(
- background_color = 'white',
- # 對中文操作必須指明字體
- font_path='yahei.ttf',
- #mask = color_mask,
- max_words = 1000,
- max_font_size = 100
- ).generate(cut_text)
- # 保存詞云圖片
- cloud.to_file('word_cloud.jpg')
- plt.imshow(cloud)
- plt.axis('off')
- plt.show()
結論:彈性工作是大部分公司的福利,其次五險一金少數公司也會提供六險一金。團隊氛圍、扁平化管理也是很重要的一方面。
至此,此次分析到此結束。有需要的同學也可以查一下其他崗位或者地區的招聘信息哦~
希望能夠幫助大家定位自己的發展和職業規劃。