`

2. 一个无界浏览器内核: PhantomJS + CasperJS

 
阅读更多
官网:http://casperjs.org/
API: http://docs.casperjs.org/en/latest/modules/index.html
官方例子: https://github.com/n1k0/casperjs/tree/master/samples

使用 CasperJS 进行简单的 UI 测试 http://www.oschina.net/translate/simpler-ui-testing-with-casperjs
CasperJS : 基于 PhantomJS 的javascript Web Crawler 工具 http://abbypan.blogspot.com/2013/02/casperjs-phantomjs-javascript-web.html
注: casperjs 命令是用 Python 脚本编写, 也可以使用 Python 来执行.


CasperJS它的设定参数方式:
var casper = require('casper').create({  
    verbose: true, 
    logLevel: 'debug', 
    pageSettings: { 
         loadImages:  false, 
         loadPlugins: true,  
         userAgent: 'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0' 
    },
    viewportSize: {
        width: 1024,
        height: 768
    },
    clientScripts:  [
        //'/home/pandy/PhantomJS/demo/toupiao/jquery.js' //引入jquery, 本地
        'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js' //引入jquery, 远程
        //但是类似this.test.assertExists(".rh_ui_icon li a:first","存在链接")测试失败,
        //还不知道原因和解决办法
    ],
    onError: function(self,m){//错误回调函数
        this.capture("error.png");
        console.log("onError===========================FATAL:" + m);
        self.exit();
    },
    onAlert: function (msg) {//alert的回调函数
        console.log("onAlert===========================msg:" + msg);
    }
}); 
//phantom.outputEncoding="gbk"; 
casper.options.viewportSize = {width: 1680, height: 924};

CasperJS的参数列表见API文档。
切入了jquery的使用方法可以参考:http://stackoverflow.com/questions/17860928/how-do-i-use-jquery-in-casperjs
var nameCount = this.evaluate(function() {
    var names = $('span.author-name')
    return names.length;
});
this.echo(nameCount);

需要在this.evaluate()方法内才能使用


CasperJS,基于PhantomJS的工具包 http://www.cnblogs.com/ziyunfei/archive/2012/09/27/2706254.html
CasperJS有什么作用呢?
我太懒了,所以直接引用CasperJS网站的介绍:
CasperJS是一个开源的,用JavaScript编写的,基于PhantomJS的导航脚本和测试工具 ,它简化了定义一个完成的导航操作所需的步骤,还提供了很有用的函数封装,方法,和语法糖,它可以完成下面这些常见任务:
定义 & 排序浏览器导航步骤
填充 & 提交表单
点击 & 跟踪链接
捕获网页截图 (还可以截取某一区域)
在远程DOM上进行断言测试
记录事件
下载资源,包括二进制文件
编写功能测试套件,结果保存为JUnit XML文件
抓取网页内容
进行导航操作


如果你在PhantomJS脚本中使用链式回调来进行导航操作,那是相当痛苦的.这种代码无论写起来,读起来,理解起来还是维护起来,都是噩梦:
var page = require('webpage').create();             //新建一个页面
page.open(url1, function(status) {                  //导航到第一个URL
    if (status == "fail") phantom.exit();           //如果发生错误,退出程序
    page.open(url2, function(status) {              //否则在页面加载完成的回调函数中继续导航到第二个URL,依次类推
        if (status == "fail") phantom.exit();
        page.open(url3, function(status) {
            if (status == "fail") phantom.exit();
            page.open(url4, function(status) {
                if (status == "fail") phantom.exit();
                // 我可以停下来了吗?
            });
        });
    });
});

CasperJS使用更方便的API解决了这种异步操作的问题:
var casper = require('casper').create();           //新建一个页面

casper.start(url1);                                //添加第一个URL
casper.thenOpen(url2);                             //添加第二个URL,依次类推
casper.thenOpen(url3);
casper.thenOpen(url4);
casper.run();                                      //开始导航



想要模拟用户通过点击链接来进行导航操作吗?没问题:
var casper = require("casper").create()                       //新建一个页面
casper.start('http://my.blog.tld/');                          //添加第一个URL
casper.thenClick('nav#menu a.blog');                          //在页面加载完成后,点击选择器指定的链接,进入一个新页面
casper.thenClick('.posts li a');                              //在新页面加载完成后,再次点击一个选择器指定的链接
casper.then(function() {                                      //在第二个新页面加载完成后,输出一些信息到控制台中
    this.echo('Page url is ' + this.getCurrentUrl());
    this.echo('Page title is ' + this.getTitle());
});

casper.run();                                                 //开始导航


注意:当click的选择匹配多个的时候,它只会点击第一个元素.

clickLabel()功能更强大
Signature: clickLabel(String label[, String tag])
New in version 0.6.1.
Clicks on the first DOM element found containing label text. Optionaly ensures that the element node name is tag:
// <a href="...">My link is beautiful</a>
casper.then(function() {
    this.clickLabel('My link is beautiful', 'a');
});

// <button type="submit">But my button is sexier</button>
casper.then(function() {
    this.clickLabel('But my button is sexier', 'button');
});



You have evaluate the jQuery code in the browser context using casper.evaluate 所有浏览器指定代码应该在casper.evaluate里面执行,比如下面使用jquery
使用jquery
You have evaluate the jQuery code in the browser context using casper.evaluate
execute code as if you were using the browser console.
var nameCount = this.evaluate(function() {
    var names = $('span.author-name')
    return names.length;
});
this.echo(nameCount);



你还可以使用coffeescript来编写如上功能的脚本:
var casper = require("casper").create()
casper.start "http://my.blog.tld/"
casper.thenClick "nav#menu a.blog"
casper.thenClick ".posts li a"
casper.then ->
    @echo "Page url is #{@getCurrentUrl()}"
    @echo "Page title is #{@getTitle()}"
casper.run()




填充和提交表单也并不难:
casper.start('http://admin.domain.tld/login/', function() {               //打开页面,并指定一个回调函数
    this.fill('form[id="login-form"]', {                                  //定位到一个form中
        'username': 'chuck',                                              //给name为username的表单控件填充值'chuck'
        'password': 'n0rr1s'                                              //给name为password的表单控件填充值'n0rr1s'
    }, true);                                                             //参数true,表示填充完毕后,立刻提交表单
});

casper.then(function() {
    this.echo(this.getTitle());                                           //新页面加载完成后,在控制台输出页面标题
});

casper.run();                                                             //开始导航

注意: 假如是ajax提交的话,一定要做wait,否在很难看到是否真的成功。最要截图来看是否成功。


页面截图: 给页面上指定的区域截图非常简单:
casper.start('http://domain.tld/page.html', function() {
    this.captureSelector('capture.png', '.article-content');                   //给页面中'.article-content'选择器匹配的元素截图,输出图片文件名为cpature.png,目录为当前目录
});
casper.run();

设定图片大小
this.capture("/mnt/D/work_documents/workspace_ide/phantomjs_casperjs/images/test.png",{
            top: 100,
            left: 100,
            width: 800,
            height: 400
        });



异步渲染页面: 有时(好吧,其实是经常),很多页面内容是通过Ajax或者其他的手段异步加载的.你可以等到某个元素出现时再执行想要的操作:
casper.start('https://twitter.com/casperjs_org', function() {
    this.waitForSelector('.tweet-row', function() {                  //等到'.tweet-row'选择器匹配的元素出现时再执行回调函数
        this.captureSelector('twitter.png', 'html');                 //成功时调用的函数,给整个页面截图
    }, function() {
        this.die('Timeout reached. Fail whale?').exit();             //失败时调用的函数,输出一个消息,并退出
    }, 2000);                                                        //超时时间,两秒钟后指定的选择器还没出现,就算失败 
});

测试

除了上面讲的这些功能之外,CasperJS真正的威力是它提供了功能测试的能力.例如,测试谷歌的搜索操作可以这样完成:
casper.start('http://www.google.fr/', function() {                                          //打开谷歌主页,添加页面加载完成时的回调函数
    this.test.assertTitle('Google', 'google homepage title is the one expected');           //检测页面标题是否是'Google',如果是,输出第二个参数指定的字符串
    this.test.assertExists('form[action="/search"]', 'main form is found');                 //检测页面中是否存在选择器指定的元素,如果存在输出第二个参数指定的字符串
    this.fill('form[action="/search"]', {                                                   //填充表单并提交,执行搜索操作
        q: 'foo'
    }, true);
});

casper.then(function() {
    this.test.assertTitle('foo - Recherche Google', 'google title is ok');                  //检测搜索结果页的页面标题是否正确    
    this.test.assertUrlMatch(/q=foo/, 'search term has been submitted');                    //检测搜索结果页的网址是否匹配指定的正则表达式
    this.test.assertEval(function() {
        return __utils__.findAll('h3.r').length >= 10;                                      //自定义一个检测函数
    }, 'google search for "foo" retrieves 10 or more results');
});

casper.run(function() {
    this.test.renderResults(true);                                                          //输出检测结果
});

运行上面的脚本会产生这样的结果:

输出结果还能导出为XUnit XML文件,可以用在持续集成服务器中,比如Jenkins.
对于记录来说,整个CasperJS测试套件使用自己的API写成,结果在visible on Travis-CI.


网上找到一个自动签到的例子:
var casper = require('casper').create({  
    verbose: true,
    logLevel: 'debug',
    pageSettings: {
         loadImages:  false,    
         loadPlugins: true,   
         userAgent: 'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0'
    }
});
//phantom.outputEncoding="gbk";
casper.options.viewportSize = {width: 1680, height: 924};
casper.start('http://bulo.hujiang.com/app/login?source=nbulo&returnurl=/home/');
casper.waitForSelector("form#myform input[name='txtUsername']",
    function success() {
        this.test.assertExists("form input[name='txtUsername']");
        this.fill("form",{
            'txtUsername':'shixiaobao17',
            'txtPassword':'×××××your password*****'
        },false);
        this.click("input#btnLogin");
    },
    function fail() {
        this.test.assertExists("form input[name='txtUsername']");
});
casper.waitFor(function check() {
    return this.getCurrentUrl().indexOf("bulo.hujiang.com/home")>-1;
}, function then() {
    console.log("登录成功!!!!!!!!!!!!");
}).then(function(){
    console.log("执行登录后的其它操作!!!!!!!!!!!!");
    if(this.exists("#btn_card_do")){
        this.click("#btn_card_do");
        this.waitForSelector("#my_hb_btn",function success(){
            console.log("打卡成功!");
        },function fail(){
            console.log("打卡失败!");
        });
    }else{
        console.log("今天已经打过卡啦!");
    }
});
casper.run(function() {this.test.renderResults(true);});




ajax:
var data, wsurl = 'http://api.site.com/search.json';

casper.start('http://my.site.com/', function() {
    data = this.evaluate(function(wsurl) {//主意在这里的function传入了url,才能使用的。
        return JSON.parse(__utils__.sendAJAX(wsurl, 'GET', null, false));
    }, {wsurl: wsurl});
});

casper.then(function() {
    require('utils').dump(data);
});



工具类:__utils__
必须再casper.evaluate()里面才能使用,并且替换当前实例
casper.start(url1,function(){
    var text = this.evaluate(function(url1) {
        __utils__.echo('plop');//注意这里的用法
        return 'abc';
    });
    this.echo("text="+text);//主意这里的用法
});



casperjs小结 http://blog.csdn.net/xiarendeniao/article/details/7740375
官网http://casperjs.org/
分享http://download.csdn.net/detail/xiarendeniao/5781445

环境:
[dongsong@localhost ~]$ casperjs --version 
1.0.0-RC2 
[dongsong@localhost ~]$ phantomjs --version 
1.7.0 

1.casperjs按照start()、then*()、wait*()、open()等流程往下做导航(注意,如果有语法错误,比如少个分号神马的,可能运行时就无任何提示的卡那里了)
  run()方法触发该流程,run()方法可以指定一个onComplete()方法供导航完成时回调
  exit()/die()退出

2.打印html源码可以用debugHTML();打印web页面用debugPage();获取网页快照用capture('xx.png')

3.填写表单或者输入框用fill()做(要求文本框有name属性)或者在evaluate()内部做(evaluate相当于casperjs和网页之间的gate)
  提交表单可以通过fill直接完成(有些提交是js控制的,这种方法就行不通了)或者用click()点击提交按钮
  下面给一个在evaluate内部做的例子(跟普通页面上的js编程类似)
// Querying for "Chuck Norris" on Google  
casper.start('http://google.fr/').thenEvaluate(function(term) {  
    document.querySelector('input[name="q"]').setAttribute('value', term);  
    document.querySelector('form[name="f"]').submit();  
}, {  
    term: 'Chuck Norris'  
});  
  
casper.run(); 

再给个填没有name属性的input框框的例子:
casper.waitForSelector('#xx', function then() {  
            recognizedCode = 'xxx';  
            this.evaluate(function(rtCode){  
                document.querySelector('input[class="xxx"]').value = rtCode; //1>可以用这种方式填input框框(without name attribute)  
                //document.querySelector('a[action-type="submit"]')[0].click(); //2>可以在这里提交哦!  
                //__utils__.findOne('input[class="WB_iptxt oauth_form_input oauth_form_code"]').value = rtCode; //1>也可以这样填input框框(without name attribute)  
            }, {rtCode:recognizedCode});  
            this.click('a[action-type="submit"]'); //2>也可以在这里提交!  
        },  
        function onTimeout() {  
            this.log('wait selector timeout', 'error')  
        },  
        timeout = 1000  
    );
 
参考:https://groups.google.com/forum/#!msg/casperjs/iybL4kdLqVg/Exw8v2pcUXAJ

4.日志console.log();或者由casperjs对象调用log()/echo()方法
  创建capserjs对象时可以指定日志级别、日志详尽程度、定制事件回调函数(OnError/onResourceReceived/httpStatusHandlers/...):
var casper = require("casper").create({  
        verbose: true,  
        logLevel: "debug",  
        onError: function(self,m){  
                this.capture("error.png");  
                console.log("FATAL:" + m);  
                self.exit();  
            }  
    }); 

还可以指定casper对象整个导航过程总的运行时间timeout,这样可以防止在程序因为网络原因或程序bug导致一直不退出,对应timeout的处理函数是onTimeout
与整个导航过程timeout和onTimeout相对应的是单步超时时间stepTimeout和单步超时处理函数onStepTimeout
   
5.调试时免不了要打印变量或者对象的信息
require("utils").dump(xxx);
 

 
6.命令行参数由cli模块操作,详见http://casperjs.org/cli.html
casperObj.cli.has(0)  
casperObj.cli.get(3)  
casperObj.cli.get('usename')  


 
7.selector,跟css选择器规则一样(详见谷歌/度娘)
  #xx                 选取以xx为id的html标签
  xx[attr='value']    选取属性attr值为value的xx类型html标签
  .xx                选取以xx为class的html标签
 
8.事件,用casperObj.on()来注册事件的回调函数,详见http://casperjs.org/events-filters.html
  要清除对某时间的监控和回调可以把回调函数设为空
  下面给个小例子
casper.on('resource.received', function(resource){  
        if (resource.redirectURL) {  
            var rUrl = resource.redirectURL;  
            if (rUrl.match(/\?code=(\w+)/g)) {  
                code = rUrl.substr(rUrl.search(/\?code=(\w+)/g)+6);  
                this.log("code=" + code,'info');  
                this.clear();  
                this.on('resource.received', function(resource) {});  
            } else  
                return;  
        } else  
            return;  
    });
 

9.单纯的把timeout设置得很长,而不设置对应的超时函数,那么设置的这个值是不起作用的,可能是casperjs的bug,实践多次证明过这个问题
   比如,使用casperjsObj.waitForSelector()等待某个选择器时想定制timeout那么要提供onTimeout函数才行

10.实践证明一个casperjs程序内部无法创建多个casperjs对象
     那么如果需要同时访问多个站点、且需要用一个站点的某些数据填写另一个站点某个form、且form页面在重新请求时不一样(比如验证码,用back()倒回去验证码就不一样了),怎么办呢?
     鸟人的解决方案是自己提供一个页面内嵌两个frame分别装载目标站点;这里又有个问题是casperjs对象不能直接获取iframe内部的标签,需要用casperjsObj.page.switchToChildFrame(0/1/2)进入iframe、用casperjsObj.page.switchToParentFrame()回到上级iframe或者全局的位置(需要注意的是这两个函数和其他普通js程序一样、只有在导航过程中的某个function内部才有效,否则会被casperjs忽视,casperjs只认start/open/thenOpen/run/then/wait*/each/..等导航,普通js程序需要在这些导航对应的function内部填充)

11.capserjsObj.captureSelector()会有误差,可以根据casperjsObj.getElementBounds()获取要拍照的选择器的边界然后人工修订后把边界值传入casperjsObj.capture()拍照

12.控制导航跳向某一步、查看有多少步,可以用label/goto/dumpSteps函数,函数实现和用法详见https://github.com/yotsumoto/casperjs-goto

13.循环控制,我们不可避免的需要重复做一些动作,把所有的URL放到一个数组里面用each函数来处理当然不错,但是很有局限性,如果要重复的动作不是打开页面而是点击某个按钮呢?
鸟人想到的解决办法是用waitFor()+Wait()来实现循环,结果不太理想,要嘛卡死直到timeout,要嘛飞快的死循环
//loop:隔一段时间就刷新一次简历(用waitFor和wait实现循环,貌似不靠谱儿!)  
        /*  
        casper.waitFor(function check(){  
                        this.wait(10000,  
                                function() {  
                                        this.click('a[title="简历刷新"]');  
                                        this.log('refreshed my resume');  
                                }  
                        );  
                        return false;  
                },  
                function then() {},  
                function onTimeout() {this.log('timeout: refresh loop competed.', 'error');},  
                timeout = 120000  
        );*/ 


网上寻来的解决方案是递归调用,casperjsObj调用run函数时可以传入一个结束时执行的函数,在这个函数里面可以加入【我们的循环体】和【递归的run调用】
参考:https://github.com/n1k0/casperjs/blob/master/samples/dynamic.js
function refresh()  
{  
        this.wait(10000,  
                function() {  
                        this.click('a[title="简历刷新"]');  
                        this.log('refreshed my resume');  
                }  
        );  
        this.run(refresh);  
}  
casper.run(refresh); 




解析HTML内容,选择器只支持css3和xpath方式.
1. 尝试解析链接
casper.then(function () {
    var links = this.evaluate(function () {
        var elements= __utils__.findAll(".rh_ui_icon a");
        var list=[];
        alert("elements.length="+elements.length);
        for(var i=0; i<elements.length; i++){
            alert(elements[i].innerHTML);
            list[list.length]=elements[i].innerHTML;
        }
        /*return Array.prototype.forEach.call(elements, function(e) {
            return e.getAttribute('href');
        });*/

        return list;
    });
    this.echo(JSON.stringify(links));
});


2. 返回一个数组
You dont need jQuery here:
casper.evaluate(function() {
    return [].map.call(__utils__.findAll('#id a'), function(node) {
        return node.getAttribute('href');
    });
});


3.遍历一个数组:回调函数的第二个参数,才是这个数组里面的元素
this.each(links, function (self, link) {
        console.log(self+":"+link);
    })


4. 关于each方法:回调函数的第一个参数是casper对象,第二个参数是数组的当前元素
var links = [
    'http://google.com/',
    'http://yahoo.com/',
    'http://bing.com/'
];

casper.start().each(links, function(self, link) {
    self.thenOpen(link, function() {
        this.echo(this.getTitle());
    });
});


自动投票
test.js
var casper = require('casper').create({  
    verbose: true,
    //logLevel: 'debug',
    pageSettings: {
         loadImages:  false,    
         loadPlugins: true,   
         userAgent: 'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0'
    }
});
//phantom.outputEncoding="gbk";
casper.options.viewportSize = {width: 1680, height: 924};
//方法一, 投票是直接使用url的方式来记票,这种处理方式太他#妈^的闹*残不负责了.
casper.start('http://www.xxxxxx.com/toupiao?id=42',function(){  
    this.capture("c:/test.png",{  
        top: 00,  
        left: 0,  
        width: 1024,  
        height: 768  
    });
	var date = new Date();
    this.echo(date.getTime()+"====================>capture over");  
});
casper.run();


第一个调用js的toupiao.bat
casperjs c:\test.js


然后再增加一个循环来call这个callTouPiao.bat, 设定重复投1w次票
set /a i=1
:c
call c:\toupiao.bat
if %i% lss 10000 set /a i+=1&goto :c
pause
分享到:
评论

相关推荐

    phantomjs + casperjs

    PhantomJS是一个基于Webkit的无头浏览器,它允许开发者在没有用户界面的情况下运行JavaScript,这对于自动化任务和性能测试来说极其方便。而CasperJS则是一个建立在PhantomJS之上的高级脚本框架,它提供了更易用的...

    06-phantomjs+selenium示例2.py

    06_phantomjs+selenium示例2.py06_phantomjs+selenium示例2.py06_phantomjs+selenium示例2.py06_phantomjs+selenium示例2.py06_phantomjs+selenium示例2.py06_phantomjs+selenium示例2.py06_phantomjs+selenium示例2...

    05-phantomjs+selenium示例1.py

    05_phantomjs+selenium示例1.py05_phantomjs+selenium示例1.py05_phantomjs+selenium示例1.py05_phantomjs+selenium示例1.py05_phantomjs+selenium示例1.py05_phantomjs+selenium示例1.py05_phantomjs+selenium示例1...

    phantomjs+实现代码

    在"phantomjs+实现代码"这个主题中,我们可以探讨以下几个重要的知识点: 1. **无头浏览器**:无头浏览器是指没有用户界面的浏览器,它们在后台运行,通常用于自动化任务。PhantomJS就是一种无头浏览器,它允许...

    phantomjs和casperjs下载地址.zip

    CasperJs 是一个基于 PhantomJs 的工具,其比起 PhantomJs 可以更加方便的进行 navigation。 推荐使用PhantomJs1.9版本的 phantomjs和casperjs下载地址,casperjs下载地址,phantomjs下载地址

    phantomjs&casperjs

    CasperJS则是一个基于PhantomJS的高级脚本框架,它扩展了PhantomJS的功能,使其更易于编写测试脚本。CasperJS提供了一套友好的API,用于导航、点击、填写表单、检查元素存在性等,使得Web自动化测试变得更加简洁和...

    flaming-octo-puss:PhantomJS CasperJS的视觉调试-允许您查看浏览器正在渲染什么

    这个小技巧使用的是一种简单的技术:PhantomJS或CasperJS通过captureBase64('png')捕获屏幕,然后将图像发布到接收服务器,然后通过socket.io将其发送到显示的浏览器它是嵌入式图像。 下面是它的工作原理: 设置...

    Node.js-phantom-用于集成PhantomJS的NodeJS模块

    PhantomJS则是一个无头浏览器,它可以全自动化地执行JavaScript,非常适合网页抓取和自动化测试,尤其在处理需要DOM渲染的任务时非常有用。 **PhantomJS模块在Node.js中的集成** `phantom`模块是将PhantomJS集成到...

    基于C#.NET+PhantomJS+Sellenium的高级网络爬虫系统设计与实现

    PhantomJS是一个无头浏览器,它能够在没有用户界面的情况下运行,非常适合于执行JavaScript并获取页面渲染后的结果。在爬虫系统中,PhantomJS被用来加载那些依赖JavaScript的动态网页,确保爬取的数据与用户实际看到...

    taobaospider:淘宝商品信息爬取:selenium + phantomJS + pyqurey + mongo

    "taobaospider"是一个项目名称,表明这是一个用于爬取淘宝商品信息的工具。"selenium + phantomJS + pyqurey + mongo"揭示了该项目使用的技术栈,包括自动化浏览器测试库Selenium,无头浏览器 PhantomJS,Python的...

    phantomjs-2.1.1-windows.zip

    PhantomJS是一个基于Webkit内核的无头浏览器,它允许开发者在没有用户图形界面的情况下运行JavaScript代码,广泛应用于自动化测试、网页截图、网络爬虫等领域。标题"phantomjs-2.1.1-windows.zip"表明这是一个针对...

    casperjs:使用 PhantomJs 和 CasperJs 测试 Web 应用程序

    PhantomJS 是一个无头浏览器,它允许你在没有用户界面的情况下运行 Web 页面,非常适合进行自动化测试。安装 PhantomJS 可以通过以下几种方式: 1. **直接下载二进制文件**:访问 PhantomJS 的官方网站,找到对应...

    人工智能-项目实践-C#-基于C#.NET+PhantomJS+Sellenium的高级网络爬虫程序 可执行Javascript

    在本项目实践中,我们探索了如何使用C#.NET框架结合PhantomJS和Selenium构建一个高级的网络爬虫程序,该程序能够处理JavaScript渲染的网页并执行JavaScript代码,从而更全面地获取网络数据。以下是对这个项目的详细...

    计算机毕业设计:Python+去哪儿携程机票爬虫

    Findtrip是一个基于Scrapy的机票爬虫,目前整合了国内两大机票网站(去哪儿 + 携程) ## Introduction Findtrip is a webspider for flight tickets by Scrapy,which contains two major china ticket websites ---...

    java+phantomjs+echarts导出图片到服务器.zip

    java+phantomjs+echarts导出图片到服务器,包含JAVA测试类,phantomjs 文件,echarts-convert.js

    phantomjs-2.1.1-windows.zip下载良心2积分

    PhantomJS是一款基于Webkit内核的无头浏览器,它是一个开源项目,广泛应用于自动化测试、网页截屏、网络监控等多个领域。标题提到的是 PhantomJS 的一个特定版本——2.1.1,针对Windows操作系统。由于官网下载速度较...

    phantomjs 2.1.1-windows版

    PhantomJS是一个开源的Webkit库,它提供了一个无头浏览器环境,可以在命令行界面下运行JavaScript代码,执行网页自动化任务。这个“phantomjs 2.1.1-windows”版本是专为Windows操作系统设计的,它包含了所有必要的...

    C#使用Selenium+PhantomJS抓取数据

    在进行网络爬虫开发时,有时我们需要处理那些依赖JavaScript动态渲染的网页,这时C#结合Selenium与PhantomJS就成为一个有效的解决方案。本文将详细介绍如何在C#环境中利用Selenium WebDriver和PhantomJS来抓取此类...

    phantomjs-2.1.1-linux-x86_64.tar.bz2 截图工具

    PhantomJS是一个基于Webkit的服务器端JavaScript API,它允许开发者在无头浏览器环境中执行脚本,进行网页抓取、自动化测试以及屏幕截图等任务。这个"phantomjs-2.1.1-linux-x86_64.tar.bz2"是PhantomJS的Linux 64位...

    Automating the Web Using PhantomJS and CasperJS

    Learn to use PhantomJS and CasperJS to automate your interaction with the web to perform numerous tasks such as data scraping, network monitoring, page rendering, and browser testing in a programmatic...

Global site tag (gtag.js) - Google Analytics