很久没写过爬虫了,其实我挺喜欢写爬虫的,所以今天找了个时间写一个爬虫吧
先说为什么要写这个爬虫,因为我公司的电梯有一个广告牌子,每天上下班,吃饭的时候都被洗脑,“上智联你更值”
,一个智联的招聘广告,高晓松每天都叫我上智联…
广告这东西对吧,没用呀,得看数据呀,所以故事就这样子开始了…
没错啦!!!就是下边这个啦
实现步骤:
01: 先打开熟悉的百度搜索 智联
, 然后选择中山
, 搜索java
02: 浏览器抓包(具体流程阅图)
03: 到了这里我们就知道了浏览器的数据是怎么来的了,然后下一步我们就是模拟浏览器发送网络请求拿到数据啦~~
其实现在很多数据的加载都是异步的加载上来了,很少写死在html中了,有机会的话可以分析一下抓取html中的数据
这里使用的java,其实什么语言都无所谓,但是爬虫的话,python相对来说友好一点, 方便很多
package cn.shaines.spider.module.job;
import cn.shaines.spider.module.SpiderInterface;
import cn.shaines.spider.util.HappyUtil;
import cn.shaines.spider.util.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author houyu
* @createTime 2019/4/21 20:59
*/
public class ZhiLianZSSpider implements SpiderInterface {
HttpUtil httpUtil = HttpUtil.get(); // 自己封装的一个网络请求工具类,
HappyUtil happyUtil = HappyUtil.get(); // 自己封装的一个公用工具类
/**
* 处理薪资词云图
* @return
*/
private Object handlerSalary(){
List<Map<String, Object>> dataList = (List<Map<String, Object>>)process(null);
System.out.println("智联中山java招聘信息共: " + dataList.size() + " 条");
List<String> list = new ArrayList<>(dataList.size());
dataList.forEach((v) -> list.add((String)v.get("薪资待遇")));
Map<String, Integer> salaryMap = happyUtil.getAloneCountInList(list);
System.out.println("salaryMap = " + salaryMap);
return null;
}
/**
* 解析网页数据
* @param param
* @return
*/
@Override
public Object process(Map<String, Object> param) {
String html = getHtml(1);
JSONObject jsonObject = JSON.parseObject(html);
JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("results");
Map<String, Object> dataMap = null;
List<Map<String, Object>> dataList = new ArrayList<>(1024);
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 福利多多 = happyUtil.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 工作福利 = happyUtil.join(jobLight == null ? new String[]{} : jobLight.toArray(), ",");
dataMap.put("工作福利", 工作福利);
JSONArray skill = positionLabel.getJSONArray("skill");
String 掌握技能 = happyUtil.join(skill == null ? new String[]{} : skill.toArray(), ",");
dataMap.put("掌握技能", 掌握技能);
System.out.println("dataMap = " + dataMap);
dataList.add(dataMap);
}
return dataList;
}
/**
* 网络请求数据
* @param page
* @return
*/
private String getHtml(int page){
String url = "https://fe-api.zhaopin.com/c/i/sou?pageSize=1000&cityId=780&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=java&kt=3";
String html = httpUtil.getHtml(url);
// System.out.println(html);
return html;
}
/**
* main
*/
public static void main(String[] args) {
ZhiLianZSSpider zhiLianZSSpider = new ZhiLianZSSpider();
//zhiLianZSSpider.process(null);
zhiLianZSSpider.handlerSalary();
}
}
04: 控制台输出
dataMap = {区域名称=竹苑, 公司代码=CZ372359780, 工作制度=全职, 公司规模=20-99人, 公司名称=中山市日淘乐网络信息有限公司, 招聘人数=3, 更新时间=2019-04-21 19:22:21, 招聘网址=https://company.zhaopin.com/CZ372359780.htm, 岗位简介=软件/互联网开发/系统集成,互联网软件工程师, 公司类型=民营, 掌握技能=JS,Java,MySQL,HTML,CSS, 岗位名称=中高级JAVA开发工程师, 工作福利=带薪年假,交通补助,加班补助,绩效奖金,年底双薪,弹性工作,14薪,住房补贴, 工作年限=3-5年, 创建时间=2019-04-06 13:06:15, 福利多多=带薪年假,交通补助,加班补助,绩效奖金,年底双薪, 学历底线=大专, 结束时间=2019-05-16 13:06:15, 所属城市=中山, 详情网址=https://jobs.zhaopin.com/372359783250004.htm, 薪资待遇=6K-10K}
dataMap = {区域名称=竹苑, 公司代码=CZ633142420, 工作制度=全职, 公司规模=1000-9999人, 公司名称=朗新科技股份有限公司, 招聘人数=4, 更新时间=2019-04-03 19:27:05, 招聘网址=https://company.zhaopin.com/CZ633142420.htm, 岗位简介=软件/互联网开发/系统集成,Java开发工程师, 公司类型=合资, 掌握技能=, 岗位名称=高级应用开发工程师(java)(J10469), 工作福利=五险一金,交通补助,带薪年假,弹性工作,补充医疗保险,定期体检,员工旅游,节日福利, 工作年限=3-5年, 创建时间=2019-03-28 14:50:23, 福利多多=五险一金,交通补助,带薪年假,弹性工作,补充医疗保险, 学历底线=本科, 结束时间=2020-01-22 14:50:23, 所属城市=中山, 详情网址=https://jobs.zhaopin.com/CC633142422J00291422403.htm, 薪资待遇=10K-15K}
dataMap = {区域名称=湖滨北路, 公司代码=CZ318025530D00300163186, 工作制度=全职, 公司规模=10000人以上, 公司名称=中山达内科技有限公司, 招聘人数=3, 更新时间=2019-04-07 17:44:46, 招聘网址=https://company.zhaopin.com/CZ318025530D00300163186.htm, 岗位简介=软件/互联网开发/系统集成,PHP开发工程师, 公司类型=上市公司, 掌握技能=, 岗位名称=初级Java软件工程师, 工作福利=五险一金,年底双薪,绩效奖金,加班补助,餐补,股票期权,带薪年假,周末双休, 工作年限=不限, 创建时间=2019-03-29 17:15:03, 福利多多=五险一金,年底双薪,绩效奖金,加班补助,餐补, 学历底线=不限, 结束时间=2019-04-28 17:15:03, 所属城市=中山-西区, 详情网址=https://jobs.zhaopin.com/CC318025533J00146991002.htm, 薪资待遇=6K-8K}
dataMap = {区域名称=张家边, 公司代码=CZ369469780, 工作制度=全职, 公司规模=100-499人, 公司名称=QST青软实训, 招聘人数=2, 更新时间=2019-04-19 09:48:27, 招聘网址=https://company.zhaopin.com/CZ369469780.htm, 岗位简介=软件/互联网开发/系统集成,Java开发工程师, 公司类型=股份制企业, 掌握技能=C++,Java, 岗位名称=java讲师【中山】, 工作福利=周末双休,五险一金,年底双薪,餐补,节日福利,不加班,免费班车,定期体检, 工作年限=3-5年, 创建时间=2019-04-19 09:48:26, 福利多多=周末双休,五险一金,年底双薪,餐补,节日福利, 学历底线=本科, 结束时间=2019-05-19 09:48:26, 所属城市=中山-火炬开发区, 详情网址=https://jobs.zhaopin.com/CC369469780J00255567603.htm, 薪资待遇=8K-12K}
dataMap = {区域名称=上步, 公司代码=CZ120564550, 工作制度=全职, 公司规模=1000-9999人, 公司名称=深圳市长亮科技股份有限公司, 招聘人数=5, 更新时间=2019-04-08 11:23:43, 招聘网址=https://company.zhaopin.com/CZ120564550.htm, 岗位简介=软件/互联网开发/系统集成,软件工程师, 公司类型=上市公司, 掌握技能=, 岗位名称=Java开发工程师(互联网金融), 工作福利=五险一金,绩效奖金,包住,通讯补助,带薪年假,定期体检,员工旅游,节日福利, 工作年限=3-5年, 创建时间=2019-04-08 11:23:43, 福利多多=五险一金,绩效奖金,包住,通讯补助,带薪年假, 学历底线=本科, 结束时间=2019-05-08 11:23:43, 所属城市=中山, 详情网址=https://jobs.zhaopin.com/120564559253095.htm, 薪资待遇=10K-15K}
dataMap = {区域名称=, 公司代码=CZ130494460, 工作制度=全职, 公司规模=1000-9999人, 公司名称=深圳天源迪科信息技术股份有限公司, 招聘人数=1, 更新时间=2019-04-04 15:50:58, 招聘网址=https://company.zhaopin.com/CZ130494460.htm, 岗位简介=软件/互联网开发/系统集成,Java开发工程师, 公司类型=民营, 掌握技能=, 岗位名称=java开发工程师, 工作福利=周末双休,五险一金,年底双薪,带薪年假,节日福利,定期体检, 工作年限=3-5年, 创建时间=2019-04-04 15:50:57, 福利多多=周末双休,五险一金,年底双薪,带薪年假,节日福利, 学历底线=大专, 结束时间=2019-05-04 15:50:57, 所属城市=中山, 详情网址=https://jobs.zhaopin.com/CC130494465J00104064207.htm, 薪资待遇=8K-15K}
dataMap = {区域名称=竹苑, 公司代码=CZ232405810, 工作制度=全职, 公司规模=1000-9999人, 公司名称=北京东方国信科技股份有限公司, 招聘人数=1, 更新时间=2019-04-19 17:17:53, 招聘网址=https://company.zhaopin.com/CZ232405810.htm, 岗位简介=软件/互联网开发/系统集成,Java开发工程师, 公司类型=上市公司, 掌握技能=, 岗位名称=Java开发工程师(GY35clf), 工作福利=节日福利,五险一金,年底双薪,定期体检,带薪年假, 工作年限=3-5年, 创建时间=2019-04-19 17:17:52, 福利多多=节日福利,五险一金,年底双薪,定期体检,带薪年假, 学历底线=本科, 结束时间=2019-07-18 17:17:52, 所属城市=中山, 详情网址=https://jobs.zhaopin.com/CC232405817J00108223209.htm, 薪资待遇=8K-15K}
......
智联中山java招聘信息共: 94 条
salaryMap = {4.5K-8K=1, 薪资面议=2, 5K-8K=6, 6K-12K=3, 6K-8K=9, 15K-30K=1, 5K-10K=6, 8K-12K=5, 4K-7K=2, 10K-15K=6, 4K-6K=8, 10K-20K=4}
05: 数据可视化, 网上很多可视化工具,使用的一个比较简单的展示一下
结束语
- 看到数据的时候,我深呼吸了好几下,连忙安慰了一下自己.不哭,你要坚强…
- 信息的说明这里就不阐述了,看图说话吧
- 这里抓到的数据内容比较多,一个url就请求到了所有的信息了,这个是比较理想和比较舒服的
- 这里抓到的数据只有94条,说明中山的IT行业(java)的企业等需求不高呀
- 这里只分析了智联的中山java薪资,其实还可以可视化很多数据的,这里就不搞事了,有时间的话可以深入分析
- 这个故事还没结束,高晓松说了
上智联你更值
,所以下次我再抓58,或者Boss直聘等招聘的信息做一个对比,那就有意思了,是不是更值不是你<高*松>说了算,我看数据说话…