赞
踩
由于九月事件把爬虫推到风口浪尖
而我写这些只是分享技术
不涉及隐私等个人资料的获取
并且是在不会对对方服务器造成压力的情况下进行的爬取
特此声明
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<Map<String,String>>格式里面
使用的"},{"进行分隔
对获取到的数据用.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<String> list = new ArrayList<String>();
- 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<Map<String, Object>>集合
- */
- public List<Map<String, Object>> ScreenText(List<String> Clist) {
- List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
- 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<String, Object> map = new HashMap<String, Object>();
- 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;
- }
- }
最后将数据入库,结束
可以在服务器里设置定时任务,每半个小时获取一次新闻,保存入库
也可以在入库之后发送给自己的手机,
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。