寫在前面
之前,爲了從半次元上下載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();
}
});
- 隨便嘮嘮:
- 截圖路徑是自己加的,後面保存截圖的時候用,不需要的可以不寫page.render()相關。
- 吐槽一下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,登錄狀態訪問網站
本來以爲大功告成了,卻又發現,有些小姐姐的作品限制了訪問權限。
比如登錄或者關注纔可查看:
所以呢,現在的網站都採用cookie保存用戶信息,方便自動登錄等操作。如果你要在登錄狀態下訪問網站,只需要給phantom加上cookie就好了。
1. 找到你的cookie
- 使用chrome內核的瀏覽器,打開你要訪問的網站並登錄。
注意:如果像上圖一樣,也請先手動關注作者後再進行如下操作。 - 登錄後(一定登錄後,否則哪來的cookie),按F12或右鍵 > 審查元素,進入後選擇Network > Doc > 選擇文件 > Cookies,選擇你需要的cookie。
以半次元爲例,這裏我們需要的是sessionid的value值。(如無文件請刷新頁面 )
2. phantom添加cookie
- 這裏有官網addCookie()方法API
- 修改我們的js腳本代碼,添加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