美文网首页Python新世界
都说 Python 赶超 Java,爬取拉勾网数据发现它的薪资已

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

作者: 919b0c54458f | 来源:发表于2018-09-07 16:11 被阅读6次

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

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

    Python很容易学!小编有弄一个交流,互问互答,资源共享的交流学习基地,如果你也是Python的学习者或者大牛都欢迎你来!㪊:548+377+875!一起 学习共同进步!

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

    01

    前期准备

    1、网页分析

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

    2、请求数据分析

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

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

    通过 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 返回数据获取。

    通过 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 库可以处理多个分隔符分隔的数据,所属行业为空,则跳过。

    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、公司相关情况分析

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

    2、城市需求分析

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

    3、薪酬与工作经验分析

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

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

    从学历要求来看,大部分都要求至少本科以上,这部分占了约 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 成为新的第一名。

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

    ● Python 就业情况乐观,从 TIOBE 8 月编程语言指数排行榜以及百度指数的搜索数来看,Python 的受欢迎程度越来越高。

    ● 在中国地区,Python 相关职位的需求量,依然集中在三大经济圈,特别是在北京、上海、深圳这几个城市。从行业需求来看,主要集中在移动互联网、数据服务、大数据分析等行业。

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

    相关文章

      网友评论

        本文标题:都说 Python 赶超 Java,爬取拉勾网数据发现它的薪资已

        本文链接:https://www.haomeiwen.com/subject/aoycgftx.html