都说 Python 赶超 Java,爬取拉勾网数据发现它的薪资已高至 50K!-阿里云开发者社区

开发者社区> 开发与运维> 正文

都说 Python 赶超 Java,爬取拉勾网数据发现它的薪资已高至 50K!

简介:

人工智能的快速发展以及大数据时代的来临,使得 Python 语言不仅在人工智能领域大放异彩,在数据处理上也有着得天独厚的优势,在 Web 开发、网络编程、自动化运维、游戏开发、金融等领域扮演着越来越重要的角色

百度搜索指数表明,2017 年 7 月份开始,Python 的搜索指数已经超过了 Java。Python 语言的热门由此可见一斑。

7623c9febb131d277efce4125bd1a3c44cbb08a6

本文中,笔者决定在拉勾网(一家为互联网从业者提供工作机会的招聘网站)上爬取相关 Python 职位信息,对职位数据(薪酬、学历要求、区域信息、工作经验等)进行图形可视化分析。

01

前期准备

1、网页分析

打开拉勾网网站搜索 Python,可以发现每页有 15 条职位信息数据,最多有 30 页数据可以查看,共 450 条职位信息。我们需要获取的信息包括:职位、公司名称、薪酬范围、所在区域、学历要求、工作经验、公司融资情况、公司人数、工作要求描述。

38b85e71d6d7dd6399ac901e9ce90a252d4b9574

2、请求数据分析

通过 Chrome 浏览器访问拉勾网,打开 Console 控制台可以发现,当进行翻页的时候,是通过 xhr 的请求方式请求的。通过观察,我们可以发现,URL 里面的 city 代表的是城市,post 参数 kd 代表的是搜索的职位,pn 是 page number,表示页码。

ca638d5c8376cd81150ef801afc17ab04a5d77c4

3、职位列表JSON返回数据的分析获取

406017dfb66bbaacb843ef79f2fef155b91720b4

通过 JSON 库进行数据的解析,获取相关信息。需要注意的是,我们需要记得保留 positionID,用于下一步获取工作描述信息。

def get_lagou(page,city,kd):
url = "https://www.lagou.com/jobs/positionAjax.json"
querystring = {"px": "new", "city": city, "needAddtionalResult": "false", "isSchoolJob": "0"}
payload = "first=false&pn=" + str(page) + "&kd="+str(kd)
cookie = "JSESSIONID=" + get_uuid() + ";"\
"user_trace_token=" + get_uuid() + "; LGUID=" + get_uuid() + "; index_location_city=%E6%88%90%E9%83%BD; " \
"SEARCH_ID=" + get_uuid() + '; _gid=GA1.2.717841549.1514043316; ' \
'_ga=GA1.2.952298646.1514043316; ' \
'LGSID=' + get_uuid() + "; " \
"LGRID=" + get_uuid() + "; "
headers = {'cookie': cookie,'origin': "https://www.lagou.com",'x-anit-forge-code': "0",'accept-encoding': "gzip, deflate, br",'accept-language': "zh-CN,zh;q=0.8,en;q=0.6",'user-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",'content-type': "application/x-www-form-urlencoded; charset=UTF-8",'accept': "application/json, text/javascript, */*; q=0.01",'referer': "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD",'x-requested-with': "XMLHttpRequest",'connection': "keep-alive",'x-anit-forge-token': "None",'cache-control': "no-cache",'postman-token': "91beb456-8dd9-0390-a3a5-64ff3936fa63"}
response = requests.request("POST", url, data=payload.encode('utf-8'), headers=headers, params=querystring)
# print(response.text)
hjson = json.loads(response.text)
for i in range(15):
positionName=hjson['content']['positionResult']['result'][i]['positionName']
companyId = hjson['content']['positionResult']['result'][i]['companyId']
positionId= hjson['content']['positionResult']['result'][i]['positionId']
salary = hjson['content']['positionResult']['result'][i]['salary']
city= hjson['content']['positionResult']['result'][i]['city']
district= hjson['content']['positionResult']['result'][i]['district']
companyShortName= hjson['content']['positionResult']['result'][i]['companyShortName']
education= hjson['content']['positionResult']['result'][i]['education']
workYear= hjson['content']['positionResult']['result'][i]['workYear']
industryField= hjson['content']['positionResult']['result'][i]['industryField']
financeStage= hjson['content']['positionResult']['result'][i]['financeStage']
companySize= hjson['content']['positionResult']['result'][i]['companySize']
job_desc = get_job_desc(positionId)
positionName_list.append(positionName)
salary_list.append(salary)
city_list.append(city)
district_list.append(district)
companyShortName_list.append(companyShortName)
education_list.append(education)
workYear_list.append(workYear)
industryField_list.append(industryField)
financeStage_list.append(financeStage)
companySize_list.append(companySize)
#job_desc_list.append(job_desc)

4、获取工作信息描述

通过观察发现,打开具体职位的详细页面时,URL 里面的数值(例如下图的 URL 里面的 4789029)就是职位的 positionID,该 positionID 可以通过上一步的职位列表 JSON 返回数据获取。

6466cd79bd83421c0d9c2384abdf23b0461e31a5

通过 requests 请求页面信息,再通过 xpath 获取工作描述信息。

def get_job_desc(id):
url = "https://www.lagou.com/jobs/"+str(id)+".html"
cookie = "JSESSIONID=" + get_uuid() + ";"\
"user_trace_token=" + get_uuid() + "; LGUID=" + get_uuid() + "; index_location_city=%E6%88%90%E9%83%BD; " \
"SEARCH_ID=" + get_uuid() + '; _gid=GA1.2.717841549.1514043316; ' \
'_ga=GA1.2.952298646.1514043316; ' \
'LGSID=' + get_uuid() + "; " \
"LGRID=" + get_uuid() + "; "
headers = {'cookie': cookie,'origin': "https://www.lagou.com",'x-anit-forge-code': "0",'accept-encoding': "gzip, deflate, br",'accept-language': "zh-CN,zh;q=0.8,en;q=0.6",'user-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",'content-type': "application/x-www-form-urlencoded; charset=UTF-8",'accept': "application/json, text/javascript, */*; q=0.01",'referer': "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD",'x-requested-with': "XMLHttpRequest",'connection': "keep-alive",'x-anit-forge-token': "None",'cache-control': "no-cache",'postman-token': "91beb456-8dd9-0390-a3a5-64ff3936fa63"}
response = requests.request("GET", url, headers=headers)
x = etree.HTML(response.text)
data = x.xpath('//*[@id="job_detail"]/dd[2]/div/*/text()')
return ''.join(data)

02

数据获取 —— 爬虫

1、设置 cookies 和 headers

如果不设置相关信息,会不允许爬取,返回提示:“您操作太频繁,请稍后再访问”。所以,我们需要设置 headers 和 cookies 信息。

def get_lagou(page,city,kd):
url = "https://www.lagou.com/jobs/positionAjax.json"
querystring = {"px": "new", "city": city, "needAddtionalResult": "false", "isSchoolJob": "0"}
payload = "first=false&pn=" + str(page) + "&kd="+str(kd)
cookie = "JSESSIONID=" + get_uuid() + ";"\
"user_trace_token=" + get_uuid() + "; LGUID=" + get_uuid() + "; index_location_city=%E6%88%90%E9%83%BD; " \
"SEARCH_ID=" + get_uuid() + '; _gid=GA1.2.717841549.1514043316; ' \
'_ga=GA1.2.952298646.1514043316; ' \
'LGSID=' + get_uuid() + "; " \
"LGRID=" + get_uuid() + "; "
headers = {'cookie': cookie,'origin': "https://www.lagou.com",'x-anit-forge-code': "0",'accept-encoding': "gzip, deflate, br",'accept-language': "zh-CN,zh;q=0.8,en;q=0.6",'user-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",'content-type': "application/x-www-form-urlencoded; charset=UTF-8",'accept': "application/json, text/javascript, */*; q=0.01",'referer': "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD",'x-requested-with': "XMLHttpRequest",'connection': "keep-alive",'x-anit-forge-token': "None",'cache-control': "no-cache",'postman-token': "91beb456-8dd9-0390-a3a5-64ff3936fa63"}

2、延时设置和分页爬取

避免爬取速度过快被封,设置延时时间为 3-5 秒。通过 for 循环进行分页数据的爬取。

def main(pages,city,job):
for n in range(1, pages+1):
get_lagou(n,city,job)
time.sleep(round(random.uniform(3, 5), 2))
write_to_csv(city,job)

03

数据存储与处理

1、CSV 数据存储

由于数据量不大,最多 450 条数据,采用 CSV 的存储方式。

2、数据处理

● 薪酬数据处理

后续统计月薪的占比,由于薪酬范围是可以自定义范围,没有一个统一的标准。例如薪酬可以是 10k-20k、5k-8k、11k-18k、10k-16k 等情况,后续不利于薪酬范围的可视化,所以将薪酬归纳分类到这几种:2k 以下、2k-5k、5k-10k、10k-15k、15k-25k、25k-50k、50k 以上。

假如薪酬为 10k-20k, 则认为在 10k-15k、15k-25k 这两种归类里面都包含。采用正则表达式进行归类汇总:

def salary_categorize(salarys):
dict = {'2k以下': 0, '2k-5k': 0, '5k-10k': 0,'10k-15k':0,'15k-25k':0,'25k-50k':0,'50k以上':0}
for salary in salarys:
if re.match('^[0-1]k-*|.*-[0-1]k$',salary)!=None:
dict['2k以下'] += 1
if re.match('^[2-4]k-*|.*-[2-4]k$',salary)!=None:
dict['2k-5k'] += 1
if re.match('^[5-9]k-*|.*-[5-9]k$', salary)!=None:
dict['5k-10k'] += 1
if re.match('^1[0-4]k-*|.*-1[0-4]k$', salary)!=None:
dict['10k-15k'] += 1
if re.match('^1[5-9]k-*|^2[0-4]k-*|.*-1[5-9]k$|.*-2[0-4]k$', salary)!=None:
dict['15k-25k'] += 1
if re.match('^2[5-9]k-*|^[3-4][0-9]k-*|.*-2[5-9]k$|.*-[3-4][0-9]k$', salary)!=None:
dict['25k-50k'] += 1
if re.match('^[5-9][0-9]k-*|.*-[5-9][0-9]k$|^\d{3,}k-*|.*-\d{3,}k$', salary)!=None:
dict['50k以上'] += 1
return dict
● 行业信息处理

公司所属行业可以是多个,一般以逗号分隔,但存在部分是以顿号和空格分隔的情况,还有可能存在没有写明相关行业的情况。对此,通过 Python 的 re 库可以处理多个分隔符分隔的数据,所属行业为空,则跳过。

dfd90ddd06cfa19409e659db4e2f74ee2ed30b85


def industryField_counts(csv_file):

industryFields = []

d = pd.read_csv(csv_file, engine='python', encoding='utf-8')

info = d['industryField']

for i in range(len(info)):

try:

data = re.split('[,、 ]',info[i])

except:

continue

for j in range(len(data)):

industryFields.append(data[j])

counts = Counter(industryFields)

return counts

04

数据可视化与解读

1、公司相关情况分析

7feb555d2b4f61a95e22fa75449c13e2657acb8b

从行业情况和公司规模来看,移动互联网占有 40% 的需求,数据服务+大数据+人工智能占了 10% 的比例。Python 非常强大,适合的领域包括 Web 开发、网络编程、爬虫、云计算、人工智能、自动化运维等,所以不管公司规模是大还是小,融资情况如何,都普遍需要 Python 相关的职位的人才。

2、城市需求分析

3a1aa680683b001f179f76008ff66e677a99e912

从上图分析,可以发现,需求量主要集中在中国三大经济圈:京津冀,长三角,珠三角。主要分布在北京(40%)、上海(16%)、深圳(15%)、广州(6%)、成都(6%)和杭州(6%)这 6 个城市。而北京的互联网创业气氛冠绝中国,注册在北京的互联网公司远远高于在其他城市的公司,需求量也是最大的。

3、薪酬与工作经验分析

7eba25c44609a7c82c2e869cfa5378df16345df5

从工作经验的要求来看,大部分集中在 3-5 年和 1-3 年这两个区间,至于工作经验和薪酬之间的相关性,观察发现,1-3 年工作经验的薪酬普遍在 15-25K,符合正态分布的规律,3-5 年工作经验的薪酬普遍在 15k-25k 和 25k-50k 这两个区间,以 15k-25k 这个区间的居多。达到 5-10 年工作经验的,薪酬在 25k-50K 这个区间的居多。

4、学历要求和工作经验分析

ef00e578f7246c4de495ba4223020cb32b7ec27e

从学历要求来看,大部分都要求至少本科以上,这部分占了约 80% 的比例。所以不要在相信读书无用论这种观点了,学历至少是工作的敲门砖。

工作经验上,普遍要求是 1-5 年,这部分占了 84% 的比例。1年以下和经验不限的,占了约 9%,5-10 年的占了约 7% 的比例。

05

总结

TIOBE 8 月编程语言指数排行榜已经公布了,排名前三的虽然依旧是 Java、C、C++。但 Python 非常接近 TIOBE 索引的前 3 位。Python 这样的上涨趋势,同样可以在 TIOBE 索引排行中体现,互联网业界也开始普遍采用 Python。Python 编程语言最初是 Perl 的继承者,用于编写构建脚本和各种粘合软件。但后来逐渐进入其他领域。如今,在大型嵌入式系统中运行 Python 是很常见的。因此,Python 完全有可能进入前三名,甚至在未来取代 Java 成为新的第一名。

ae76ab49c745c54a57c1c64f3858e21b570838b5

从目前 Python 的就业前景来看,总结如下:

● Python 就业情况乐观,从 TIOBE 8 月编程语言指数排行榜以及百度指数的搜索数来看,Python 的受欢迎程度越来越高。
● 在中国地区,Python 相关职位的需求量,依然集中在三大经济圈,特别是在北京、上海、深圳这几个城市。从行业需求来看,主要集中在移动互联网、数据服务、大数据分析等行业。

● 从拉勾网的数据分析可知,大部分 Python 的相关职位都要求在本科和本科以上,工作经验要求在 1-5 年的居多。因为 Python 在大数据和人工智能领域的爆发性发展, 导致 Python 方向岗位的薪水在水涨船高,从数据分析来看,月薪在 10K-50K 不等。


原文发布时间为:2018-09-3

本文作者:lowelong

本文来自云栖社区合作伙伴“CDA数据分析师”,了解相关信息可以关注“CDA数据分析师”。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章