0%

【C#】如何在Server Side執行phantomjs對網頁進行快照

phantomjs如何使用,詳細請參考參考黑暗執行緒前輩的文章

首先寫了一支snapshot.js放到phantomjs的根目錄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var page = require('webpage').create(),
system = require('system'),
edmid,
address;

address = system.args[1];
edmid = system.args[2];
path = system.args[3];

page.open(address,function(status){

page.render(path + '/' + edmid+'.png');
phantom.exit();
});

這支JS需要傳遞三個參數,1.網址 2.圖片的名稱 3.拍好的圖片存的路徑
在cmd的執行方式如下
這次的功能是要在網站上按下一個按鈕後就對特定的網頁進行快照,程式如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//phantomjs在伺服器上的根目錄資料夾
string path = HostingEnvironment.MapPath(@"~/phantomjs");
//因為拍照可能需要數秒的時間,避免網頁被hand住所以切出執行緒來進行。故抓MapPath的方式需要改成 HostingEnvironment.MapPath
//這裡是我把拍好的圖片放到哪個資料夾的路徑
string snapshotPath = HostingEnvironment.MapPath("~/phantomjs/snapshot");

//透過Process這個類別來對cmd操作
using (System.Diagnostics.Process exep = new System.Diagnostics.Process())
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.Start();

//StandardInput的資訊流指定給StreamWriter ,這樣只要透過StreamWriter寫指令就等於對cmd下command了
StreamWriter sw = p.StandardInput;
sw.WriteLine(@"cd\");
sw.WriteLine(string.Format(@"{0}:", path.Substring(0, 1)));
sw.WriteLine(@"cd " + path);
sw.WriteLine(string.Format(@"phantomjs snapshot.js {0} {1} {2}", 網址, 圖片名稱, snapshotPath ));
sw.Close();
p.WaitForExit();
}

重點在於只要自己透過cmd操作過phantomjs.exe來拍照,依樣畫葫蘆的透過Process逐步的下指令就可以達成了!!

另外phantomjs是將要被拍照的DOM元件抓下來在進行組合拍照,有了這個特性你就可以對想拍照的網站進行一些修改。例如載入JQuery把某個區塊移除之類的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* Wait until the test condition is true or a timeout occurs. Useful for waiting
* on a server response or for a ui change (fadeIn, etc.) to occur.
*
* @param testFx javascript condition that evaluates to a boolean,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param onReady what to do when testFx condition is fulfilled,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
*/
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 250); //< repeat check every 250ms
};

var page = require('webpage').create(),
system = require('system'),
edmid,
address;

edmid = system.args[1];
address = 'http://xxx.com.tw/'+ edmid;

// Open Twitter on 'sencha' profile and, onPageLoad, do...
page.open(address, function (status) {
// Check for page load success
if (status !== "success") {
console.log("Unable to access network");
} else {
// Wait for 'signin-dropdown' to be visible
waitFor(function() {
// Check in the page if a specific element is now visible
return page.evaluate(function() {
return ($("body").prop("class") == "allready" );
//return $("#signin-dropdown").is(":visible");
});
}, function() {
console.log("body allready now.");
page.render('D:\\test\\'+edmid+'.png');
phantom.exit();
});
}
});