爬虫分析智联_深圳_JAVA_薪资水平(对比中山)
找时间再续爬虫啦 智联爬虫未完现续~~~
上一篇博客获取了中山的JAVA薪资水平, 并且数据可视化, 这次主要在于获取深圳的JAVA薪资水平, 顺便和中山对比一下, 你会发现一线城市和二线城市的IT薪资差异了…
上一篇博客 [ 爬虫分析智联_中山_java_薪资水平 ]
http://shaines.cn/u/shy/blogs/25
https://blog.csdn.net/JinglongSource/article/details/89441095
进入今天主题
01: 智联深圳招聘
了解页面之后,我们看看大概有多少数据, 浏览器滚动条拖到最后, 然后发现没有显示最大页面, 所以我们尝试输入50页, 输入的数字被改写成了12, 也就是说输入框被js监听了, 如果输入大于总页数, 会被动态改写为列表数据的最大页数, 也就是12,至此 就知道了原来智联中深圳JAVA招聘列表一共12页, 综合上一篇博客的数据抓包就可以大概猜测出 一共数据有: 90 * 12 = 1080
抓包在这里就不过多阐述了, 参考上一篇博客 [ 爬虫分析智联_中山_java_薪资水平 ]
http://shaines.cn/u/shy/blogs/25
https://blog.csdn.net/JinglongSource/article/details/89441095
02: JAVA获取数据并且入库
由于这里数据量有点多, 为了处理方便, 这里选择写入数据库(mysql)
封装了一个小工具类DbUtil
上代码如下:
package cn.shaines.spider.module.job;
import cn.shaines.spider.module.SpiderInterface;
import cn.shaines.spider.util.DbUtil;
import cn.shaines.spider.util.EasyUtil;
import cn.shaines.spider.util.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.sql.SQLException;
import java.util.*;
/**
* 智联 深圳 爬虫
* @author houyu
* @createTime 2019/4/27 12:20
*/
@SuppressWarnings({"WeakerAccess", "Duplicates"})
public class ZhiLianSZSpider implements SpiderInterface {
// 自己封装的一个网络请求工具类,
HttpUtil httpUtil = HttpUtil.get();
// 自己封装的一个公用工具类
EasyUtil easyUtil = EasyUtil.get();
// 定义一个标识创建一次表
private int iscreatetableflag = 0;
// 定义开始的位置
private int start = 0;
// 定义表名
private String tableName = "智联深圳JAVA招聘信息";
/**
* 处理薪资
* @return
*/
private Object handlerSalary(){
List<Map<String, Object>> dataList = null;
try {
dataList = DbUtil.executeQuery("SELECT 薪资待遇 FROM " + tableName);
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("智联深圳java招聘信息共: " + dataList.size() + " 条");
List<String> list = new ArrayList<>(dataList.size());
dataList.forEach((v) -> list.add((String)v.get("薪资待遇")));
System.out.println(list);
List<String> tempList = new ArrayList<>(dataList.size() * 10);
list.forEach(v -> {
if (v.contains("-")){
String[] split = v.split("-");
double startNum = Double.parseDouble(split[0].replace("K", ""));
double endNum = Double.parseDouble(split[1].replace("K", ""));
while (startNum < endNum + 1) {
double num = startNum++;
String numStr = num + "";
if (!numStr.contains(".0")){
tempList.add(numStr);
}else {
tempList.add(numStr.replace(".0", ""));
}
}
}else {
tempList.add(v);
}
});
System.out.println(tempList);
Map<String, Integer> salaryMap = easyUtil.getAloneCountInList(tempList);
System.out.println("\r\nsalaryMap = " + salaryMap);
return null;
}
/**
* 解析网页数据
* @param param
* @return
*/
@Override
public Object process(Map<String, Object> param) {
List<Map<String, Object>> dataList = null;
while (true){
String html = getHtml();
JSONObject jsonObject = JSON.parseObject(html);
JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("results");
// 如果数据集合为空,跳出循环
if (jsonArray.isEmpty()){
break;
}
Map<String, Object> dataMap;
dataList = new ArrayList<>(jsonArray.size());
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject data = jsonArray.getJSONObject(i);
dataMap = new HashMap<>(16);
String 更新时间 = data.getString("updateDate");
String 结束时间 = data.getString("endDate");
String 所属城市 = data.getJSONObject("city").getString("display");
String 详情网址 = data.getString("positionURL");
String 福利多多 = easyUtil.join(data.getJSONArray("welfare").toArray(), ",");
String 薪资待遇 = data.getString("salary");
String 工作年限 = data.getJSONObject("workingExp").getString("name");
dataMap.put("更新时间", 更新时间);
dataMap.put("结束时间", 结束时间);
dataMap.put("所属城市", 所属城市);
dataMap.put("详情网址", 详情网址);
dataMap.put("福利多多", 福利多多);
dataMap.put("薪资待遇", 薪资待遇);
dataMap.put("工作年限", 工作年限);
String 公司代码 = data.getJSONObject("company").getString("number");
String 公司规模 = data.getJSONObject("company").getJSONObject("size").getString("name");
String 公司名称 = data.getJSONObject("company").getString("name");
String 公司类型 = data.getJSONObject("company").getJSONObject("type").getString("name");
String 招聘网址 = data.getJSONObject("company").getString("url");
dataMap.put("公司代码", 公司代码);
dataMap.put("公司规模", 公司规模);
dataMap.put("公司名称", 公司名称);
dataMap.put("公司类型", 公司类型);
dataMap.put("招聘网址", 招聘网址);
String 岗位简介 = data.getJSONObject("jobType").getString("display");
String 招聘人数 = data.getString("recruitCount");
String 创建时间 = data.getString("createDate");
String 岗位名称 = data.getString("jobName");
String 学历底线 = data.getJSONObject("eduLevel").getString("name");
String 工作制度 = data.getString("emplType");
String 区域名称 = data.getString("businessArea");
dataMap.put("岗位简介", 岗位简介);
dataMap.put("招聘人数", 招聘人数);
dataMap.put("创建时间", 创建时间);
dataMap.put("岗位名称", 岗位名称);
dataMap.put("学历底线", 学历底线);
dataMap.put("工作制度", 工作制度);
dataMap.put("区域名称", 区域名称);
JSONObject positionLabel = JSON.parseObject(data.getString("positionLabel"));
JSONArray jobLight = positionLabel.getJSONArray("jobLight");
String 工作福利 = easyUtil.join(jobLight == null ? new String[]{} : jobLight.toArray(), ",");
dataMap.put("工作福利", 工作福利);
JSONArray skill = positionLabel.getJSONArray("skill");
String 掌握技能 = easyUtil.join(skill == null ? new String[]{} : skill.toArray(), ",");
dataMap.put("掌握技能", 掌握技能);
System.out.println("dataMap = " + dataMap);
if (iscreatetableflag == 0){
DbUtil.createTable(tableName, dataMap.keySet().toArray(new String[]{}));
iscreatetableflag = 1;
}
DbUtil.insertData(tableName, dataMap);
dataList.add(dataMap);
}
try {
// 适当停顿, 避免封IP
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return dataList;
}
/**
* 网络请求数据
* @return
*/
private String getHtml(){
// String url = String.format("https://fe-api.zhaopin.com/c/i/sou?start=%d&pageSize=90&cityId=765&kw=JAVA&kt=3", start);
String url = String.format("https://fe-api.zhaopin.com/c/i/sou?start=%d&pageSize=90&cityId=765&kw=JAVA&kt=3&rt=134542fe834e4a019404bf10c52124b3&_v=0.04244049&x-zp-page-request-id=6d260c9fff0d4668a158babf5ae396e0-1556345376278-699243", start);
String html = httpUtil.getHtml(url);
// System.out.println(html);
System.out.println("\r\nstart = " + start + "\r\n");
start += 90;
return html;
}
/**
* main
*/
public static void main(String[] args) {
ZhiLianSZSpider zhiLianZSSpider = new ZhiLianSZSpider();
//zhiLianZSSpider.process(null);
zhiLianZSSpider.handlerSalary();
}
}
整体代码和中山的那个差不多, 只是添加了一个循环获取页数而已
抓包的URL https://fe-api.zhaopin.com/c/i/sou?start=%d&pageSize=90&cityId=765&kw=JAVA&kt=3&rt=134542fe834e4a019404bf10c52124b3&_v=0.04244049&x-zp-page-request-id=6d260c9fff0d4668a158babf5ae396e0-1556345376278-699243
这里需要注意,这里的分页没有pageIndex的概念, 而是start(开始页数), 也就是说
默认每页90(pageSize=90)
第一页 start 0
第二页 start 90
第三页 start 180
…
03: 观察数据并且构造数据可视化
- 数据库刚好数据为1080条, 看来数据抓取是完整的…
- 可视化工具我使用了网上的一个小工具 http://www.olchart.com/
下载好数据模板 然后处理一下数据上传上去就可以一键生成可视化图表…
03: 数据可视化
先回顾中山的薪资水平
本次可视化深圳JAVA薪资水平
重点来了, 这里不做任何评论, 看数据说话…
智联·中山·JAVA
vs 智联·深圳·JAVA
结束语
- 本次抓取智联深圳JAVA薪资水平,顺便对比一下中山的薪资
- 其实智联广州JAVA数据也抓取了, 但是让数据可视化这方面比较耗时, 等有时间了再捣腾吧…
- 故事尚未结束, 还是因为没有对比过其他招聘网站的数据, 我们仍然不能相信高晓松说的
上智联 你更值
这一波广告 - 下一步, 如果有时间了抓取一个比较方便的招聘网站对比一下智联, 这个故事就算完啦…
学习与交流:
[email protected]
[email protected]
BLOG:
www.shaines.cn
项目坐标:
https://github.com/HouYuSource/spider
了解我的都知道,每篇博客都会上一张搞笑图片[奸笑]