专栏名称: 马哥Linux运维
马哥linux致力于linux运维培训,连续多年排名第一,订阅者可免费获得学习机会和相关Linux独家实战资料!
目录
相关文章推荐
运维  ·  再见,CDN 巨头:Akamai 宣布 ... ·  2 天前  
51好读  ›  专栏  ›  马哥Linux运维

我用Python又爬虫了拉钩招聘,给你们看看2019市场行情

马哥Linux运维  · 公众号  · 运维  · 2019-05-06 21:00

正文

本文转载自公号Python攻城狮,作者: Python攻城狮


数据采集

事情的起源是这样的,某个风和日丽的下午… 习惯性的打开知乎准备划下水,看到一个问题刚好邀请回答

于是就萌生了采集下某招聘网站Python岗位招聘的信息,看一下目前的薪水和岗位分布,说干就干。

先说下数据采集过程中遇到的问题,首先请求头是一定要伪装的,否则第一步就会给你弹出 你的请求太频繁,请稍后再试 ,其次网站具有多重反爬策略,解决方案是每次先获取session然后更新我们的session进行抓取,最后拿到了想要的数据。

Chrome浏览器右键检查查看 network ,找到链接 https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false


可以看到返回的数据正是页面的Python招聘详情,于是我直接打开发现直接提示 {"status":false,"msg":"您操作太频繁,请稍后再访问","clientIp":"124.77.161.207","state":2402} ,机智的我察觉到事情并没有那么简单

真正的较量才刚刚开始,我们先来分析下请求的报文,


可以看到请求是以 post 的方式传递的,同时传递了参数

datas = {
            'first''false',
            'pn': x,
            'kd''python',
        }

同时不难发现每次点击下一页都会同时发送一条 get 请求

这里我点了两次,出现两条get请求


经过探索,发现这个 get 请求和我们 post 请求是一致的,那么问题就简单许多,整理一下思路

关键词: python
搜索范围: 全国
数据时效: 2019.05.05

#!/usr/bin/env python3.4
# encoding: utf-8
"""
Created on 19-5-05
@title: ''
@author: Xusl
"""

import json
import requests
import xlwt
import time


# 获取存储职位信息的json对象,遍历获得公司名、福利待遇、工作地点、学历要求、工作类型、发布时间、职位名称、薪资、工作年限
def get_json (url, datas):
    my_headers = {
        "User-Agent""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
        "Referer""https://www.lagou.com/jobs/list_Python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=",
        "Content-Type""application/x-www-form-urlencoded;charset = UTF-8"
    }
    time.sleep(5)
    ses = requests.session()    # 获取session
    ses.headers.update(my_headers)  # 更新
    ses.get("https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=")
    content = ses.post(url=url, data=datas)
    result = content.json()
    info = result['content']['positionResult']['result']
    info_list = []
    for job in info:
        information = []
        information.append(job['positionId'])  # 岗位对应ID
        information.append(job['city'])  # 岗位对应城市
        information.append(job['companyFullName'])  # 公司全名
        information.append(job['companyLabelList'])  # 福利待遇
        information.append(job['district'])  # 工作地点
        information.append(job['education'])  # 学历要求
        information.append(job['firstType'])  # 工作类型
        information.append(job['formatCreateTime'])  # 发布时间
        information.append(job['positionName'])  # 职位名称
        information.append(job['salary'])  # 薪资
        information.append(job['workYear'])  # 工作年限
        info_list.append(information)
        # 将列表对象进行json格式的编码转换,其中indent参数设置缩进值为2
        # print(json.dumps(info_list, ensure_ascii=False, indent=2))
    # print(info_list)
    return info_list


def main():
    page = int(input('请输入你要抓取的页码总数:'))
    # kd = input('请输入你要抓取的职位关键字:')
    # city = input('请输入你要抓取的城市:')

    info_result = []
    title = ['岗位id''城市''公司全名''福利待遇''工作地点''学历要求''工作类型''发布时间''职位名称''薪资''工作年限']
    info_result.append(title)
    for x in range(1, page+1):
        url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
        datas = {
            'first''false',
            'pn': x,
            'kd''python',
        }
        try:
            info = get_json(url, datas)
            info_result = info_result + info
            print("第%s页正常采集" % x)
        except Exception as msg:
            print("第%s页出现问题" % x)
        
        # 创建workbook,即excel
        workbook = xlwt.Workbook(encoding='utf-8')
        # 创建表,第二参数用于确认同一个cell单元是否可以重设值
        worksheet = workbook.add_sheet('lagouzp', cell_overwrite_ok=True)
        for i, row in enumerate(info_result):
            # print(row)
            for j, col in enumerate(row):
                # print(col)
                worksheet.write(i, j, col)
        workbook.save('lagouzp.xls')


if  __name__ == '__main__':
    main()

日志记录

当然存储于excel当然是不够的,之前一直用 matplotlib 做数据可视化,这次换个新东西 pyecharts

了解pyecharts

pyecharts是一款将python与echarts结合的强大的数据可视化工具,包含多种图表

  • Bar(柱状图/条形图)

  • Bar3D(3D 柱状图)

  • Boxplot(箱形图)

  • EffectScatter(带有涟漪特效动画的散点图)

  • Funnel(漏斗图)

  • Gauge(仪表盘)

  • Geo(地理坐标系)

  • Graph(关系图)

  • HeatMap(热力图)

  • Kline(K线图)

  • Line(折线/面积图)

  • Line3D(3D 折线图)

  • Liquid(水球图)

  • Map(地图)

  • Parallel(平行坐标系)

  • Pie(饼图)

  • Polar(极坐标系)

  • Radar(雷达图)

  • Sankey(桑基图)

  • Scatter(散点图)

  • Scatter3D(3D 散点图)

  • ThemeRiver(主题河流图)

  • WordCloud(词云图)

用户自定义

  • Grid 类:并行显示多张图

  • Overlap 类:结合不同类型图表叠加画在同张图上

  • Page 类:同一网页按顺序展示多图

  • Timeline 类:提供时间线轮播多张图

另外需要注意的是从版本0.3.2 开始,为了缩减项目本身的体积以及维持 pyecharts 项目的轻量化运行,pyecharts 将不再自带地图 js 文件。如用户需要用到地图图表(Geo、Map),可自行安装对应的地图文件包。

  1. 全球国家地图: echarts-countries-pypkg (1.9MB): 世界地图和 213 个国家,包括中国地图

  2. 中国省级地图: echarts-china-provinces-pypkg (730KB):23 个省,5 个自治区

  3. 中国市级地图: echarts-china-cities-pypkg (3.8MB):370 个中国城市

也可以使用命令进行安装

pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg
数据可视化(代码+展示)
  • 各城市招聘数量


from pyecharts import Bar

city_nms_top10 = ['北京''上海''深圳''成都''杭州''广州''武汉''南京''苏州''郑州''天津''西安''东莞''珠海''合肥''厦门''宁波',
                  '南宁''重庆''佛山''大连''哈尔滨''长沙''福州''中山']
city_nums_top10 = [1499577221717161375443222111111111]

bar = Bar("Python岗位""各城市数量")
bar.add("数量", city_nms, city_nums, is_more_utils=True)
# bar.print_echarts_options() # 该行只为了打印配置项,方便调试时使用
bar.render('Python岗位各城市数量.html')  # 生成本地 HTML 文件


  • 地图分布展示(这个场景意义不大,不过多分析)



from pyecharts import Geo

city_datas = [('北京'149), ('上海'95), ('深圳'77), ('成都'22), ('杭州'17), ('广州'17), ('武汉'16), ('南京'13), ('苏州'7),
     ('郑州'5), ('天津'4), ('西安'4), ('东莞'3), ('珠海'2), ('合肥'2), ('厦门'2), ('宁波'1), ('南宁'1), ('重庆'1),
     ('佛山'1), ('大连'






请到「今天看啥」查看全文