日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JS渲染引擎比較HtmlUnit/Selenium/PhantomJs

 bylele 2019-01-23

現(xiàn)如今的爬蟲再也不是簡單的爬取靜態(tài)頁面,解析Html文本這么簡單,許多單頁面應(yīng)用,異步請(qǐng)求調(diào)用,頁面初始化js渲染等技術(shù)的使用,使得傳統(tǒng)的通過發(fā)起http請(qǐng)求獲得的Document無法直接使用。因此,基于實(shí)際業(yè)務(wù)需求,在爬取某電商平臺(tái)數(shù)據(jù)時(shí),發(fā)現(xiàn)其頁面特定位置為js渲染,固此,由此一文,基于實(shí)際代碼測試,分析HtmlUnit/Selenium/PhantomJs三類流行的js渲染引擎。

-HtmlUnit

1
2
3
4
5
<code>1) 內(nèi)置Rhinojs瀏覽器引擎,沒有哪一款瀏覽器使用該內(nèi)核
2) 解析速度一般
3) 解析JS/CSS差
4) 無瀏覽器界面
</code>

- Selenium

1
2
3
4
5
<code><code>1) Seleninum 1+ WebDriver = Selenium
2) 基于本地安裝的瀏覽器,需打開瀏覽器
3) 需要引用相應(yīng)的WebDriver,正確配置webdriver的路徑參數(shù)
4) 在爬取大量js渲染頁面時(shí)明顯不合適
</code></code>

- PhantomJs

1
2
3
4
5
<code><code><code>1) 神器,短小精悍
2) 可本地化運(yùn)行,也可作為服務(wù)端運(yùn)行
3) 基于webkit內(nèi)核,性能及表現(xiàn)良好
4) 完美解析絕大部分頁面
</code></code></code>

基于實(shí)測結(jié)果,在爬取大量任務(wù)時(shí),推薦將PhantomJs作為服務(wù)端使用,此處,分別介紹本地及遠(yuǎn)程服務(wù)端使用例子(也可查看官網(wǎng)example)

本地

需要構(gòu)造目標(biāo)執(zhí)行的js文件,利用命令行調(diào)用PhantomJS
示例:
window平臺(tái)下
PhantomJs.exe target.js param1

對(duì)應(yīng)的本地target.js可參考如下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
<code><code><code>"use strict";
var page = require('webpage').create();
var system = require('system');
if (system.args.length !== 2) {
    console.log('Usage: server.js <some port="">');
    phantom.exit(1);
} else {
    var url = system.args[1];
    page.open(url, function (status) {
            console.log(page.content);
            phantom.exit();
            }
        });</some></code></code></code>

在java程序中,通過調(diào)用控制臺(tái)執(zhí)行命令

1
2
3
4
5
6
7
8
9
10
<code><code><code>        Runtime runtime = Runtime.getRuntime();
        Process p = runtime.exec("D:/phantomjs.exe target.js url);
        InputStream is = p.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        StringBuffer sb = new StringBuffer();
        String tmp = "";
        while((tmp = br.readLine())!=null){
            sb.append(tmp);
        }
        return sb.toString();</code></code></code>

搭建遠(yuǎn)程服務(wù)器

保證遠(yuǎn)程服務(wù)器指定端口開啟
示例:
在阿里ecs上開啟指定端口,如3003
打開控制臺(tái),在安全組中添加自定義TCP連接,可訪問的ip組設(shè)置為0.0.0.0/0,同時(shí)配置入網(wǎng)和出網(wǎng)端口

操作步驟

1) 官網(wǎng)下載exe文件至指定位置(linux平臺(tái)同理)
2) 新建一個(gè)server.js文件
3) 命令行運(yùn)行PhantomJS server.js即可開啟服務(wù)
4) 本地通過在瀏覽器或者java代碼中提交http請(qǐng)求,即可獲得響應(yīng),url為 https://遠(yuǎn)程服務(wù)器ip地址:端口號(hào)/https://自定義url

此處server.js為關(guān)鍵,其設(shè)置了服務(wù)器的監(jiān)聽端口及響應(yīng)請(qǐng)求邏輯
server.js示例代碼:

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
<code><code><code>"use strict";
var page = require('webpage').create();
var server = require('webserver').create();
var system = require('system');
var host, port;
if (system.args.length !== 2) {
    console.log('Usage: server.js <some port="">');
    phantom.exit(1);
} else {
    port = system.args[1];
    var listening = server.listen(port, function (request, response) {
        console.log("GOT HTTP REQUEST");
        console.log(JSON.stringify(request, null, 4));
        // we set the headers here
        response.statusCode = 200;
        response.headers = {"Cache": "no-cache", "Content-Type": "text/html"};
        // this is also possible:
        response.setHeader("databee", "databee");
        // now we write the body
        // note: the headers above will now be sent implictly
        //response.write("<title></title>");
        // note: writeBody can be called multiple times
       // var url = "

提供本地發(fā)起請(qǐng)求Java代碼示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<code><code><code>        URL url = new URL(finalUrl);//finalUrl此時(shí)為get請(qǐng)求url
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        InputStream is = null;
        BufferedReader br = null;
        if (conn.getResponseCode() == 200) {
            is = conn.getInputStream();
        } else {
            is = conn.getErrorStream();
        }
        br = new BufferedReader(new InputStreamReader(is));
        String line = "";
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();</code></code></code>

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多