phantomjs初体验

最近老婆产检预约挂号,总是挂不到她想预约的那个医生的号,都是“预约已满”。于是想抓下网页做下有预约号时的提醒。

但是看了下挂号网页,是用ajax返回预约数据。如果用curl或者python requests需要先找到js里所描述的ajax方法以及对应的url。可能是js水平问题,我打开firebug在一堆XHR里兜兜转转了半天找到了疑似的url,构造了请求参数提交却始终没有得到正确的结果。

心烦意乱之下,想起之前用 phantomjs 脚本化截图kibana页面,了解到phantomjs可以模拟浏览器渲染执行js,于是想看看能不能有比较方便的方式得到我想要的结果。

安装

参照这里的步骤即可,是用编译好的二进制包,非常简单方便。

编写脚本

要加载一个页面,需要用到phantomjs的webpage组件创建一个webpage对象:

var page = require('webpage').create();  

加载页面:

page.open('http://www.xxxxx.com', function(status) {  
    console.log('page loaded');
});

然后在page.open里面模拟执行js语句(evalute):

page.open('http://www.xxxxx.com', function(status) {  
    var ret = page.evaluate(function(){
        return document.getElementsByClassName("btn07").length;
    };
    console.log(ret);
    phantom.exit();
});

页面是这样子的:

"已满"是个classname="btn btn07"的按钮:

于是document.getElementsByClassName("btn07").length如果不等于12就说明有预约号了。其实查看了其他页面,可预约的button的classname是"btn05",这样才比较靠谱。不过因为时间关系,没有仔细搞下去了。

执行脚本:

phamtonjs checkAppointment.js  

在预约已满的情况下会输出12,接下来就用shell去判断,然后决定是否调用发微信的脚本,这里比较简单就不提了。

效果

定时任务设成了10分钟跑一次,结果在接近凌晨0点的时候收到了提醒。不过脚本没有考虑日期,并不是老婆想要的预约时间,只好默默地回去修改脚本了。然而大概12点05分左右,正在改的时候发现了想要的那天有号了,就赶紧预约成功了,这脚本有空再改进算了。哈哈,挺好玩。

后记

at 2016/08/08 20:14:32

之前也玩过selenium,最近才发现seleniumwebdriver支持phantomjs,测试了下用selenium + phantomjs来实现登录推酷

from selenium import webdriver  
from selenium.webdriver.common.keys import Keys  
driver = webdriver.PhantomJS()  
# 打开页面
driver.get('http://www.tuicool.com/login')  
# 找到元素
email = driver.find_element_by_id('xlEmail')  
passwd = driver.find_element_by_id('xlPassword')  
btn = driver.find_element_by_class_name("btn-primary")  
# 提交表单
email.send_keys("abc@def.com")  
passwd.send_keys("secret")  
# 点击登录
btn.click()  
# 查看下是否正确登录
print driver.find_element_by_class_name('head-name').get_attribute('innerHTML')  

太强大了。记得几年前尝试selenium还需要打开个chrome,现在用phantomjs完全就可以实现脚本化了!

have fun.