需求是催生项目和推进项目的不竭动力。
背景:
1.支付宝
在支付宝的城市服务中,定位到指定城市,是能够看一些医院提供了预约挂号接口的,显然A医院当之无愧也在其中。
简便易用的支付宝用户体验,即便是第一次来也好像是经常使用这项服务般熟练。找到A院,搜索妇产科,在list中有若干医生,有的标注无号源,有的标注可预约,大抵如下:
于是满怀激动的点击"可预约",可是弹出来的却不是我想要的结果--!
后来听到诸如凌晨12点会有号放出,但是最终也是收到同样冷冰冰的弹出窗口。对于用此招挂上号的我深表佩服,只是抛开这个不说,感觉A院在支付宝这块的投入太低,UI设计也很呆板,最主要的是抢不到号。
2.百度医生
相对来说,百度医生要比上面做的实诚的多,有就是有,没有就是没有。不管是PC端还是app端,用户界面更加柔和smooth。
于是我把希望寄托在这里,但是A院的号难抢,这是事实。而百度医生我觉得还有一块空白可以实现的就是监控机制,好比12306可以刷票一样,添加这个模块,相信app的下载量和使用量会提高一个"当量"。
很显然,这个功能,还没有,那我只能自己动手了~~~
我的思路
1.百度从医院拿数据,那我就从百度拿数据。我能够监控百度医生放出来的消息,就基本与医院同步了;
码前预热
1.框架选择
毫无疑问,我们采用selenium,一款web测试应用工具,模拟我在浏览器上的操作。可以基于IE、FF、Chrome等等浏览器,实现启动关闭浏览器/页面,在页面上点击、定位元素等相应操作。关于seleniumwebdriver的背景知识就不做介绍,一篇博文显然难以阐述清楚。
2.工具使用
在使用selenium过程中,页面元素的定位是个核心问题。我们可以使用By类下面的By.name,By.id,By.linkText分别获取获取name属性,id属性,超链接文本。这些方式的定位我们直接可以在DOM结构中看出来,其中比较复杂的是xpath,需要根据DOM结构实现定位,这时候我们需要一个工具可以实时的测试我们的xpath表达式是否能够正确定位到指定元素。
a.在Firefox浏览器中,我们可以安装插件FirePath
这里我们通过字符串".//*[@id='su']"就能够定位到"百度一下"这个按钮
b.在chrome里面,我们可以下载插件XPathHelper,有关它的用户,请参看
思路有了,工具齐了,那就开始着手做吧
1.启动chrome浏览器
需要下载chrome的驱动
System.setProperty("webdriver.chrome.driver","C:\\Users\\Administrator\\Downloads\\chromedriver_win32\\chromedriver.exe");WebDriverdriver=newChromeDriver();
2.定位元素执行动作
WebElementloginLink=driver.findElement(By.xpath(".//*[@id='u1']/a[7]"));loginLink.click();
3.等待页面加载完成
有时候在driver.get()到某个页面时,如果页面没有加载完成,这时候去定位元素容易抛出异常,所以需要加入等待页面加载完成的功能。这里将其封装在一个函数中:
publicstaticvoidwaitForLoad(WebDriverdriver){ExpectedCondition
4.遇到异常重新启动机制
监控的原理在于间歇性的点击相应的科室并监听页面中是否有想要的元素出现(如出现预约挂号),如果出现则点击进入相应界面,如果没有出现则一直监听。
但是在实测过程中,发现持续点击某科室会出现页面一直加载的情况,这时候会抛出异常,程序无法正常进行。
所以在这里捕获异常,通过递归调用的思想,关闭先前的driver对象,并调用自己重新生成一份监听driver对象,从而保证程序正常执行,提高了程序的健壮性。
try{WebDriverWaitwait=newWebDriverWait(driver,7000);wait.until(newExpectedCondition
5.成果展示
但从程序来说,可以现实自动抢号功能,已成功预约到非妇产科以外科室的号。