[完整爬虫]java爬虫基础对36Kr快讯数据进行爬取以及数据筛选过滤

由于九月事件把爬虫推到风口浪尖 

而我写这些只是分享技术

不涉及隐私等个人资料的获取

并且是在不会对对方服务器造成压力的情况下进行的爬取

特此声明

 

36Kr 也叫36氪,是一个我非常喜欢的网站,网罗天下资讯,而且页面整洁资讯一目了然,极大的开拓眼界,许多不管是金融方面科技方面我感觉是最新最全面,当然最终是准备爬取一下上面的资讯,当然是不会对对方服务器造成压力的情况下进行的爬取.

一.所需材料,涉及技术

  1. java 

  2. jsoup 爬取方法

  3. sql 数据库

  4. 一个可爱的脑子

  5. 当然还需要对H5结构的熟悉了解,以及json层次结构

 

分析数据源的方法我写过详细的博客,这里就不详细说明数据的获取方式了.

详情参考:([java爬虫]常用网页接口查找方法)这篇博客

 

这里就直接粘贴数据接口

https://36kr.com/api/newsflash?b_id=AAAA&per_page=BBBB

主要是b_id&per_page的参数

但要记住per_page的值不能超过30

因为访问的数量越多,后台就需要读取大量数据进行组装,消耗大量资源,切记不能对对方服务器造成压力的情况下进行爬取

因为访问的数量越多,后台就需要读取大量数据进行组装,消耗大量资源,切记不能对对方服务器造成压力的情况下进行爬取

因为访问的数量越多,后台就需要读取大量数据进行组装,消耗大量资源,切记不能对对方服务器造成压力的情况下进行爬取

例子
如b_id=10005&per_page=5
新闻从id为10005开始,返回5条数据
10005,10004,10003,10002,10001
五条数据

 

代码部分会写如何获取最新的新闻数据方法

 

下面是真实数据

{"code":0,
"timestamp":1571904380,
"timestamp_rt":1571904380,
"data":{"items":[
{
"id":187910,
"project_id":1,
"column_id":72,
"post_id":null,
"is_top":0,
"pin":0,
"title":"金柚网2019人力资源产业生态论坛在杭举办",
"catch_title":"",
"description":"36氪获悉,2019中国(浙江)人力资源服务博览会开幕,来自全国的120家人力资源机构参展。在金柚网“重塑·创新·激活人效·智享未来” 2019人力资源产业生态论坛上,金柚网助理总裁兼产品发展部总监陈鸿飞表示,数字化将在数据沉淀、效率提升、智能决策与交付提升方面显著提升人力资源服务质量与水平,金柚网将以“AI+人力资源”为发展动能,持续打造数字化人力资源全流程服务平台。",
"cover":"",
"news_url_type":"",
"news_url":"",
"user_id":16754887,
"published_at":"2019-10-24 15:10:44",
"created_at":"2019-10-24 15:10:44",
"updated_at":"2019-10-24 15:10:44",
"counters":{"view_count":13,
"pv":12,
"pv_mobile":0,
"pv_app":1,
"comment":0},
"extraction_tags_arr":[],
"extraction_tags":"[]",
"column":{
"id":72,
"name":"其他",
"bg_color":"#000000",
"type":"normal"
},"db_counters":[{"id":287449590,
"entity_type":"newsflash",
"entity_id":187910,
"count_type":"favorite",
"key":"kr_newssite_counter:newsflash_187910_favorite",
"value":1,
"created_at":"2019-10-24 15:28:00",
"updated_at":"2019-10-24 15:28:00",
"entity_id_old":null
},{
"id":287441265,
"entity_type":"newsflash",
"entity_id":187910,
"count_type":"pv",
"key":"kr_newssite_counter:newsflash_187910_pv",
"value":12,
"created_at":"2019-10-24 15:14:51",
"updated_at":"2019-10-24 15:49:07",
"entity_id_old":null
},{
"id":287449996,
"entity_type":"newsflash",
"entity_id":187910,
"count_type":"pv_app",
"key":"kr_newssite_counter:newsflash_187910_pv_app",
"value":1,
"created_at":"2019-10-24 15:28:34",
"updated_at":"2019-10-24 15:28:34",
"entity_id_old":null}],
"user":{
"id":16754887,
"name":"李欣",
"avatar_url":""
},"news_url_title":"",
"station_info":null
},{
"id":187909,
"project_id":1,
"column_id":72,
"post_id":null,
"is_top":0,
"pin":0,
"title":"金柚网2019人力资源产业生态论坛在杭举办",
"catch_title":"",
"description":"36氪获悉,2019中国(浙江)人力资源服务博览会开幕,来自全国的120家人力资源机构参展。在金柚网“重塑·创新·激活人效·智享未来” 2019人力资源产业生态论坛上,金柚网助理总裁兼产品发展部总监陈鸿飞表示,数字化将在数据沉淀、效率提升、智能决策与交付提升方面显著提升人力资源服务质量与水平,金柚网将以“AI+人力资源”为发展动能,持续打造数字化人力资源全流程服务平台。",
"cover":"",
"news_url_type":"news_url",
"news_url":"http://baijiahao.baidu.com/s?id=1648179606039764976&wfr=spider&for=pc",
"user_id":16754887,
"published_at":"2019-10-24 14:56:29",
"created_at":"2019-10-24 14:56:29",
"updated_at":"2019-10-24 14:56:29",
"counters":{
"view_count":39,
"pv":39,
"pv_mobile":0,
"pv_app":0,
"comment":0},
"extraction_tags_arr":[],
"extraction_tags":"[]",
"column":{
"id":72,
"name":"其他",
"bg_color":"#000000",
"type":"normal"},
"db_counters":[
{"id":287430436,
"entity_type":"newsflash",
"entity_id":187909,
"count_type":"pv",
"key":"kr_newssite_counter:newsflash_187909_pv",
"value":39,
"created_at":"2019-10-24 14:58:21",
"updated_at":"2019-10-24 15:58:10",
"entity_id_old":null
},{
"user":{
"id":16754887,
"name":"李欣",
"avatar_url":""},
"news_url_title":"原文链接",
"station_info":null
},{
]
}
}

接口返回json格式数据

数据比较多,涉及到的参数也比较详细

这里就需要对json格式比较熟悉可以快速的进行数据筛选

 

[完整爬虫]java爬虫基础对36Kr快讯数据进行爬取以及数据筛选过滤_第1张图片[完整爬虫]java爬虫基础对36Kr快讯数据进行爬取以及数据筛选过滤_第2张图片

 

对这种数据进行筛选的方法有很多,也有很多便利的方法

我这里就使用java 自带的String中的方法

由于是使用json格式所以新闻存储在List>格式里面

使用的"},{"进行分隔

对获取到的数据用.split()方法,分割出来

 

下面是代码

 

首先是如何获取到最新的新闻

https://36kr.com/api/newsflash?b_id=AAAA&per_page=BBBB

接口需要两个值,一个是从那条新闻开始获取,一个是获取几条数据

所以获取最新的新闻就需要获取最新的新闻的ID

/**
	 * 当前最新的新闻ID 
	 * @return 返回 int 类型 的id
	 */
	public int newID() {
		int front = 0;
		int later = 0;
		String textno1 = "";
		String newsURL = "https://36kr.com/newsflashes";
		try {
			// 爬取方法(每个人获取数据的方法不同,所以就不具体写爬取方法了)
			String information = Getinformation(newsURL);
			front = information.indexOf("newsflashList");
			textno1 = information.substring(front);
			front = textno1.indexOf("id");
			later = textno1.indexOf("project_id");
			textno1 = textno1.substring(front + 4, later - 2);
			front = Integer.parseInt(textno1);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return front;
		}
	}

之后就可以根据自己需要填写需要返回的新闻条数

 

如果是定时任务获取数据可以先获取最新id,在获取数据库内最新的新闻id,做差值

得到距离上次爬取新生成的新闻数

来准确的获取新生成的数据,节省时间,节省资源

 

再贴一份有关数据库做差获取新闻方法

/**
	 * 处理并返回新网址
	 * @param NEWID 页面最新ID
	 * @param SQLID 数据库最新ID
	 * @return
	 */
	public String newurl(int SQLID, int NEWID) {
		String http = "https://36kr.com/api/newsflash?b_id=AAAA&per_page=BBBB";
		String BBBB = "";
		if (SQLID == 0) {
			BBBB = "30";
		} else {
			BBBB = String.valueOf(NEWID - SQLID);
		}
		http = http.replace("AAAA", String.valueOf(NEWID));
		http = http.replace("BBBB", BBBB);
		return http;
	}

 

当有了接口链接就可以进行获取数据了

 

数据分割方法

/**
	 * 数据分割方法
	 * @param information 源码
	 * @return 分割后的集合
	 */
	public List roughsaix(String information) {
		List list = new ArrayList();
		try {
			String[] Array = information.split("\\}\\,\\{");// 拆分为String数组
			for (int i = 0; i < Array.length; i++) {
				list.add(Array[i]);// 转化为集合
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return list;
		}
	}

 

数据筛选方法

/**
	 * 数据筛选方法
将刚刚分割后的数据传入
	 * @param Clist 
	 * @return 返回整理好的数据List>集合
	 */
	public List> ScreenText(List Clist) {
		List> listmap = new ArrayList>();
		int front;
		int later;
		// 所提取的值
		String time;// created_at
		String ID;// id
		String title;// title
		String summary;// summary
		String newsurl;
		// 记录当前爬取详情
		try {
			for (String information : Clist) {
				Map map = new HashMap();
				front = information.indexOf("title\":\"");
				later = information.indexOf("catch_title");
				if (front != -1 && later != -1) { // 判断是否为要爬取的目标
					// title
					title = information.substring(front + 8, later - 3);
					
					front = information.indexOf("id\":");
					later = information.indexOf("project_id");
					// ID
					ID = information.substring(front + 4, later - 2);

					
					front = information.indexOf("description");
					later = information.indexOf("cover");
					// summary
					summary = information.substring(front + 14, later - 3);

					// url
					front = information.indexOf("\"news_url\":\"http");
					later = information.indexOf("user_id");
					if (front != -1) {
						newsurl = information.substring(front + 12, later - 3);
					} else {
						newsurl = null;
					}
					
					front = information.indexOf("created_at");
					later = information.indexOf("updated_at");
					// time
					time = information.substring(front + 13, later - 3);
					
					map.put("id", ID);// 数据id
					map.put("url", url);// 外部链接
					map.put("title", title);// 存储标题
					map.put("text", summary);// 新闻主体
					map.put("time", time);// 新闻时间

                    //保存 也可以直接入库
					listmap.add(map);
					
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return listmap;
		}
	}

 

最后将数据入库,结束

 

可以在服务器里设置定时任务,每半个小时获取一次新闻,保存入库

也可以在入库之后发送给自己的手机,

[完整爬虫]java爬虫基础对36Kr快讯数据进行爬取以及数据筛选过滤_第3张图片

 

 

 

 

 

你可能感兴趣的:(java爬虫,完整爬虫方法)