上次看了一下scrapy1.1的新手指南

决定写个小爬虫实验一下

目标网站是http://www.dm5.com/manhua-huofengliaoyuan
准备爬取漫画火凤燎原的已有章节,将图片保存到本地

开始一切顺利,从漫画目录页面开始,拿到了每一话(卷)的地址

然而访问后发现页面中的图片地址都是加过密的,找不到真实地址。
(网页源代码中没有,f12看network大概看了一下,也没有发现地址,所以应该是加密了)

后来试着打开了几个漫画网站,只有腾讯动漫能在页面中找到图片的连接。

决定试一试phantomjs

PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎。它原生支持多种web 标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVGPhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎。它原生支持多种web 标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVG。
<!-- more -->

以下使用火凤燎原第5卷第2页的地址http://www.dm5.com/m5342-p2/为例子
按着官网指南走一边。

安装phantomjs2.1.1

这里下载对应好的包
或者自己下载源码进行编译(据说自己编译巨慢)

我下载的是phantomjs-2.1.1-linux-x86_64.tar.bz2
解压缩,在目录里执行

./bin/phantomjs -v
-->2.1.1

话说这样执行没问题,也给了+x权限,但是ln -s 到/usr/bin目录下却无法执行。。
将phantomjs连接到python环境的bin目录下。

新手指南

官方新手指南
我是按着官方走,但是实验自己需要爬取的页面

Hello,World!

新建一个文档hello.js
内容:

# 在控制台打印日志
console.log('Hello, world!');
// 退出phantomjs
phantom.exit();

在hello.js目录下执行

phantomjs hello.js
--> Hello,world!

注意任何时候都不要忘记phantom.exit();
他用来让phantomjs退出

载入页面并将整个页面保存成图片

//创建一个webpage对象
var page = require('webpage').create();
// 打开页面
page.open('http://www.dm5.com/m5342-p2/', function(status) {
// 输出状态
console.log("Status: " + status);
if(status === "success") {
// 如果状态为success,将整个page保存为hfly.jpg(也可以是png,pdf, gif)
page.render('hfly.jpg');
}
phantom.exit();
});

执行代码后

http://oc1suuvql.bkt.clouddn.com/image/3f0da110-75fa-44be-b504-9f0b01a0dc89.jpg

感觉速度很慢,不过这是保存了整个页面,如果只保存图片会不会快一点?
官网真贴心,紧跟着就给了一个测速脚本

测试速度loadspeed.js

这个速度是phantomjs加载页面并且渲染页面的总耗时。

var page = require('webpage').create(),
system = require('system'),
t, address; if (system.args.length === 1) {
console.log('Usage: loadspeed.js <some URL>');
phantom.exit();
} t = Date.now();
// 读取控制台参数
address = system.args[1];
page.open(address, function(status) {
if (status !== 'success') {
console.log('FAIL to load the address');
} else {
t = Date.now() - t;
console.log('Loading ' + system.args[1]);
console.log('Loading time ' + t + ' msec');
}
phantom.exit();
});

执行,参数为要测试的地址
地址前面要加上http://或者https://

phantomjs loadspeed.js http://www.baidu.com
-->Loading time 5403 msec
phantomjs loadspeed.js http://www.dm5.com/m5342-p2/
-->Loading time 76584 msec

。。。
敢问你是不是在逗我?秒速五厘米很美、、秒速76厘米就是逗逼了。。
为什么这么慢?他怎么就这么慢?是我环境的问题嘛?
(因为我是用的虚拟机centos7,本地win7 pycharm remote evns,虚拟机的内存小cpu只分配了一个核心,可能渲染的就慢一些?)

早有耳闻phantomjs速度慢,没想到google诚不欺我。。
不行。。我要在本地win7上也试一下。
本地

phantomjs.exe loadspeed.js http://www.baidu.com
-->Loading time 701msec
phantomjs.exe loadspeed.js http://www.dm5.com/m5342-p2/
-->Loading time 5534 msec

我猜对了。。。
那我真是好尴尬,本地win7 安装python3 的各种包真是无力
搞个虚拟机专门用来配置python环境。。没想到phantomjs需要一定的性能。。

我再试试我的vps。。512M,1核,本地虚拟机是1核,768M。

phantomjs.exe loadspeed.js http://www.google.com
-->Loading time 415msec
phantomjs.exe loadspeed.js http://www.nba.com
-->Loading time 2800 msec
phantomjs.exe loadspeed.js http://www.dm5.com/m5342-p2/
-->Loading time 7993 msec

看来不是性能问题,是下载速度。。
我用的虚拟机是本地桥接,没想到网速会差这么多

!!又尼玛反转,剧情神打脸,啪啪啪啪

http://oc1suuvql.bkt.clouddn.com/image/ccf06c6b-c876-4f45-a194-ba04e5eea016.jpg

虚拟机的网速也是呱呱叫的
目前,唯一能解释的就是vmware不行,效率低(本身就是虚拟机)
但是vps也是虚拟机来着。。到底人家专业做的么?

小结:使用phantomjs,要么在本地机器上运行,要么直接放vps上运行。
用vmware,慢出个翔、、

代码评估(code evaluation)

不知道怎么翻译,明明就是分析代码然后取出需要的内容

使用evaluate()方法去审核页面代码,这个方法是沙盒式的,不会去执行页面外的js代码。
(也就是说在外面定义的变量不能在evalute方法中使用)
evalute方法是直接去操作page对象了,把处理后取得的内容返回。

evaluate()方法返回一个对象,也只能返回一个对象,不能包含函数。

// 获得页面标题
url = 'http://www.dm5.com/m5342-p2/'
// 创建webpage对象
var page = require('webpage').create();
page.open(url, function(status) {
if(status === "success"){
// 从page对象里,evalute出来title(不知道怎么翻译。。)
var title = page.evaluate(function() {
return document.title;
});
console.log('Page title is ' + title);
}else {
console.log('failed');
}
phantom.exit();
});

执行后输出页面标题

通常一个网页自己也有console输出,在chrome里f12选择console就能看到。
这个输出在phantomjs里是不会被显示出来的
evaluate方法里的console.log也不会显示(因为相当于网页自己的console输出了。)
如果想要输出
需要重写onConsoleMessage方法

url='http://www.dm5.com/m5342-p2/'
var page = require('webpage').create();
page.onConsoleMessage = function(msg) {
console.log('Page title is ' + msg);
};
page.open(url, function(status) {
page.evaluate(function() {
console.log(document.title);
});
phantom.exit();
});

我尼玛。
为啥会有一个百度的广告。
估计是这个网站使用了百度推广或者统计吗?
但是chrome里看控制台,却没有这个百度的输出
不知道为啥

只要phantomjs脚本运行起来,就可以使用css 选择器和标准的js DOM 操作。
所以需要了解一下css selector 和 DOM 操作

自动化任务

由于phantomjs可以加载和操作web界面,所以可以用它来做自动化。
详见page automation tasks

网络监控

歪了歪了,,我只想拿页面上的图片。。
但是官方指南只是介绍大概功能,鉴于这是最后一点内容。也一并记录下来好了

phantomjs 有网络通信的检查功能,很适合用来做网络行为的分析。
当接受到请求时,可以通过重写onResourceRequested和onResourceReceived回调函数来实现接收到资源请求和资源接受完毕的监听。
详见network monitoring

// 网络监听
url='http://www.dm5.com/m5342-p2/'
var page = require('webpage').create();
page.onResourceRequested = function(request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function(response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(url);

这样在webpage载入的时候,会把所有网络请求的请求内容和响应内容打印到控制台。

官方例子

里面有很多样例代码,可以直接看,不同的再去翻手册
Examples

记录一下拿图片地址的代码

果然官方指南只是大略的介绍一下

拿图片地址的文件get_pic_url.js

// 接受漫画网页地址
url = system.args[1];
var page = require('webpage').create();
page.open(url, function(status) {
if(status === "success"){
// 处理页面
var pic_url = page.evaluate(function() {
// DOM操作
return document.getElementById('cp_image').getAttribute('src');
});
console.log(pic_url);
}else{
console.log('failed');
}
phantom.exit();
});

执行 phantomjs get_pic_url.js http://www.dm5.com/m5342-p2/
输出图片地址。

总结

phantomjs是一个无界面的浏览器。
所以在代码最后一定要加入phantom.exit()方法确保其退出。

phantomjs加载页面以后
用evaluate()方法对渲染后的页面代码进行操作,此函数值操作页面,和我们执行的js不在一个域。

phantomjs可以做自动化测试,网络监听等工作。

phantomjs2.1 初体验的更多相关文章

  1. .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验

    不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...

  2. Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验

    Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...

  3. Spring之初体验

                                     Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...

  4. Xamarin.iOS开发初体验

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0

  5. 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...

  6. 【Knockout.js 学习体验之旅】(1)ko初体验

    前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...

  7. 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验

    在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...

  8. 百度EChart3初体验

    由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...

  9. Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验

    Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出E ...

随机推荐

  1. C++ ------ 创建对象 new 和不 new 的区别

    1.作用域不同 不用new:作用域限制在定义类对象的方法中,当方法结束时,类对象也被系统释放了,(安全不会造成内存系统泄漏). 用new:创建的是指向类对象的指针,作用域变成了全局,当程序结束时,必须 ...

  2. 微信小程序传值

    方式一:通过设置id方式传值 <button class="btninvest" bindtap="goinvet" id="{{item.tx ...

  3. array_diff使用注意

    $lost_ids = array_diff($all_ids,$old_ids); //array_diff,$old_ids不可以为null否则返回为null;array_diff起不到效果~~~

  4. MySQL下创建序列及创建自定义函数方法介绍

    工作过程中需要将基于DB2数据库的应用以及数据迁移到MySQL中去,在原应用中,大量使用了SEQUENCE,考虑尽量减少代码的修改,决定在迁移后的应用中继续保留SEQUENCE的使用,这就要求在MyS ...

  5. kvm虚拟机

    ###查看虚拟机的状态 [root@fgeserver2 ~]# virsh list --all Id Name State------------------------------------- ...

  6. 2015/9/29 Python基础(20):类的授权

    类的授权 1.包装包装在Python编程世界中时经常会被提到的一个术语.它是一个通用的名字,意思是对一个已存在的对象进行包装,不管它是数据类型,还是一段代码,可以是对一个已存在的对象,增加新的,删除不 ...

  7. 谈谈"求线段交点"的几种算法(js实现,完整版)

    "求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法总结一下, 希望对大家有所帮助.  ...

  8. 【BZOJ】1901: Zju2112 Dynamic Rankings

    [题意]带修改的查询区间第k小 [算法]树状数组套可持久化线段树 [题解]对于树状数组上的每个节点,维护可持久化权值线段树(节点为权值),从而达到查询前缀和的目的. 对于每次修改,在待修改线段树基础上 ...

  9. 引用类型 ( 对象定义 )——Function 类型

    本文地址:http://www.cnblogs.com/veinyin/p/7607798.html  函数实际上是对象,也具有属性和方法,函数名实际上是指向函数对象的指针 function sum( ...

  10. Oracle笔记之用户管理

    1. 创建用户 创建用户使用create user语句,需要DBA权限: CREATE USER tom IDENTIFIED BY mot; 2. 更改用户密码 修改别人的密码需要DBA权限,或者a ...