項目 | Java獲取Ajax頁面(半次元)—— PhantomJS實現(帶cookie登錄)

寫在前面

之前,爲了從半次元上下載coser小姐姐的照片,想寫個爬蟲保存網頁上的圖片鏈接,就直接用了Jsoup來讀取半次元的網頁。

這裏說一下,對於想寫Java爬蟲的小夥伴們來說,Jsoup算是很好用的html解析器,有興趣深入研究的可以嘗試下。
官網:https://jsoup.org/

但是,保存下來的html卻和瀏覽器F12審查元素顯示的不一樣,這才發覺半次元應該是用了Ajax動態加載網頁,而分析異步js又很麻煩(嗯就是懶)。。。

不得已,換方法。


Java+PhantomJs訪問網站

PhantomJS是一個可編寫腳本的無頭網頁瀏覽器。它可以運行在Windows,macOS,Linux和FreeBSD上。
官網:http://phantomjs.org/

所以這裏我們的思路就是用PhantomJs當做瀏覽器訪問網站,當然也包括瀏覽器進行的各種Ajax請求,這樣就能在Java中調用並得到一個完整的html,和你在用瀏覽器訪問的效果一樣。

1. 下載PhantomJs

  • 直接去這裏,根據你的系統下載安裝包。
  • 以win10爲例,解壓壓縮包後,我們需要的只有phantomjs.exe這個文件。
    (examples文件夾中有很多使用例子可以查看)

2. 編寫訪問網站的JavaScript腳本

  • 官網Quick Start裏有講到使用方法及代碼,這裏直接貼我訪問網站需要用到的代碼。
system = require('system')
address = system.args[1];
path = system.args[2]

var page = require('webpage').create();
var url = address; //訪問網址
var savePath = path; //截圖保存路徑,不寫默認保存的調用phantomjs的目錄

page.open(url, function (status) { 
	console.log("Status: " + status);
	if (status === 'success') {
		window.setTimeout(function () { //設置等待延遲,保證phantom能完整加載出頁面
			page.render(savePath + "webscreenshot.png"); //網頁截圖
			console.log(page.content); //網頁html文本
			phantom.exit();
		}, 5000);
	} else {
		console.log('Failed to post!');
		phantom.exit();
	}
});
  • 隨便嘮嘮:
  1. 截圖路徑是自己加的,後面保存截圖的時候用,不需要的可以不寫page.render()相關。
  2. 吐槽一下PhantomJs有時候很慢而且不穩定,受網速影響很大。爲了能保證獲取頁面加載完畢後的html文本,設置了js的setTimeout()方法,儘可能增加成功率。

3. Java調用PhantomJs執行腳本,獲取網頁html

  • 將phantomjs.exe和剛剛編寫的js腳本保存在你的某個目錄。
  • 你也可以先用cmd命令行測試一下腳本,這裏以win10爲例
    格式爲:[phantomjs.exe路徑] [腳本.js路徑] [網站url] [截圖保存路徑](截圖可選)
    例如:D:\phantomjs\phantomjs.exe D:\phantomjs\code.js https://bcy.net/u/12345678
  • 進入Java,編寫執行代碼。如下:
	/**
	 * 獲取ajax頁面內容
	 */
	public String getAjaxCotnent(String url, String path) {
		String exec = phantom + " " + codejs + " " + url + " " + path; //執行命令,替換成你自己的文件路徑
		
		try {
			Runtime rt = Runtime.getRuntime();
			Process p = rt.exec(exec);
			
			InputStream is = p.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			StringBuffer sbf = new StringBuffer();
			String tmp = "";
			while((tmp =br.readLine()) != null){  
				sbf.append(tmp);  
			}
			System.out.println(sbf.toString());  
			
			return sbf.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return "";
	}
  • **注意:**這裏是調用命令行執行腳本,你的phantomjs.exe、腳本文件及截圖文件的存儲目錄請不要帶有空格,否則命令行會將某段目錄文字當做執行程序,當然也就不能正常執行腳本了。

以上,我們就能在Java中調用PhantomJs腳本,得到瀏覽器進行Ajax請求後的html了


PhantomJs攜帶cookie,登錄狀態訪問網站

本來以爲大功告成了,卻又發現,有些小姐姐的作品限制了訪問權限。
比如登錄或者關注纔可查看:

PhantomJsjs\color{gray}{也許可以用PhantomJs模擬瀏覽器進行寫操作,但那樣無疑涉及到大量js腳本編寫,我又不是專門學這個的。。。}

所以呢,現在的網站都採用cookie保存用戶信息,方便自動登錄等操作。如果你要在登錄狀態下訪問網站,只需要給phantom加上cookie就好了。

1. 找到你的cookie

  • 使用chrome內核的瀏覽器,打開你要訪問的網站並登錄。
    注意:如果像上圖一樣,也請先手動關注作者後再進行如下操作。
  • 登錄後(一定登錄後,否則哪來的cookie),按F12或右鍵 > 審查元素,進入後選擇Network > Doc > 選擇文件 > Cookies,選擇你需要的cookie。
    以半次元爲例,這裏我們需要的是sessionid的value值。(如無文件請刷新頁面 )

2. phantom添加cookie

system = require('system')
address = system.args[1];
path = system.args[2]

var page = require('webpage').create();
var url = address;
var savePath = path;

//添加cookie,添加成功返回true,否則返回false
var flag = phantom.addCookie({
  'name'     : 'sessionid', //cookie的name
  'value'    : '換成你自己的value', //cookie的value
  'domain'   : '.bcy.net',
  'path'     : '/',
  'httponly' : false,
  'secure'   : false,
  'expires'  : 'Fri, 01 Jan 2038 00:00:00 GMT'
});
console.log(flag);

if(flag) {
	page.open(url, function (status) { 
		console.log("Status: " + status);
		if (status === 'success') {
			window.setTimeout(function () {
				page.render(savePath + "webscreenshot.png");
				console.log(page.content);
				phantom.exit();
			}, 5000);
		} else {
			console.log('Failed to post!');
			phantom.exit();
		}
	});
} else {
	console.log('cookies error')
}

這樣,我們就能攜帶cookie以登錄狀態訪問網站了

源碼地址:https://github.com/JohnnyJYWu/bcy-webcrawler-Java/tree/master/phantomjs
(包含phantomjs.exe)


結語

這篇文章是爲了下一篇文章做的準備。
項目 | Java+PhantomJs爬蟲實戰——半次元 下載高清原圖


第一次寫博,有不足之處歡迎各位大佬批評指正。
我的GitHub:https://github.com/JohnnyJYWu

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