[完整爬蟲]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 自帶的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;
		}
	}

 

最後將數據入庫,結束

 

可以在服務器裏設置定時任務,每半個小時獲取一次新聞,保存入庫

也可以在入庫之後發送給自己的手機,

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章