由于九月事件把爬虫推到风口浪尖
而我写这些只是分享技术
不涉及隐私等个人资料的获取
并且是在不会对对方服务器造成压力的情况下进行的爬取
特此声明
36Kr 也叫36氪,是一个我非常喜欢的网站,网罗天下资讯,而且页面整洁资讯一目了然,极大的开拓眼界,许多不管是金融方面科技方面我感觉是最新最全面,当然最终是准备爬取一下上面的资讯,当然是不会对对方服务器造成压力的情况下进行的爬取.
java
jsoup 爬取方法
sql 数据库
一个可爱的脑子
当然还需要对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 自带的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
最后将数据入库,结束
可以在服务器里设置定时任务,每半个小时获取一次新闻,保存入库
也可以在入库之后发送给自己的手机,