前面咱们的预定脚本已经自动将姓名填入了网页,如今来处理剩下的部分html
前面提到过自动输入姓名信息,其实证件号码、手机号码、2020年贺岁币(第一批)这三条信息也是能够自动输入的。python
输入的方式实际上是同样的,下面是代码:git
ele_identNo = driver.find_element_by_xpath('//*[@id="identNo"]') ele_identNo.send_keys(paras['identNo']) ele_mobile = driver.find_element_by_xpath('//*[@id="mobile"]') ele_mobile.send_keys(paras['mobile']) ele_cardvalue0 = driver.find_element_by_xpath('//*[@id="cardvalue0"]') ele_cardvalue0.send_keys(paras['cardvalue0']) 复制代码
前文有提到过,网页上验证码的源是一条连接而不是一张固定的图片:github
基于这种状况,咱们不能经过连接直接读取当前的验证码。退而求其次,咱们采起的方式是对当前验证码截图。不过这样作有一个缺点,就是每次运行时须要存储一个临时的验证码图片。考虑到脚本的使用环境不会有太多的验证码被缓存,并且每次缓存时保持临时图片的文件名不变则一直只会有一张图片,因此这个策略是能够被接受的。缓存
那怎样对当前验证码截图呢?markdown
selenium
已经为咱们想到了这一点:网络
# 先找到验证码对应的网页元素 ele_piccaptcha = driver.find_element_by_xpath('//*[@id="piccaptcha"]') # 而后直接调用这个元素的screenshot方法,参数是保存的路径便可实现截图 ele_piccaptcha.screenshot('./temp_capchar.jpg') 复制代码
咱们将验证码图片保存为了当前目录下的temp_capchar.jpg
文件。但有时因为元素选择的不许确或者其余的缘由会致使图片偏大,因此在识别验证码以前须要对它进行“瘦身”(前文代码中有体现):dom
# 先读取图片 image = cv2.imread(capchar, 0) # 将图片上下左右各切割一个像素 image = image[1:-1, 1:-1] 复制代码
上述代码是默认封装在recognize_capchar
方法中的,要识别验证码,咱们只须要将验证码图片的路径以及咱们训练好的模型传递给这个方法便可。 须要注意的是,因为初始化神经网络的耗时相对其余代码来讲会长不少,因此最好的作法是在程序一开始就初始化一个模型对象,后面只要须要自动识别验证码,都用这个对象来作。整个过程只须要初始化模型一次,能大大的提升效率,毕竟这是抢钱的时候。ide
# 用已经提早初始化好的模型和标签对象来对temp_capchar.jpg进行自动识别 capchar = recognize_capchar('./temp_capchar.jpg', model, lb) # 将识别结果输入到对应的框中 ele_capchar = driver.find_element_by_xpath('//*[@id="piccode"]') ele_capchar.send_keys(capchar) 复制代码
前面都是静态的网页元素,像这种须要选择的元素应该怎么处理呢?oop
其实也仍是一步步的来,首先获取到这个下拉框对象:
ele_orglevel = driver.find_element_by_xpath('//*[@id="orglevel1"]') 复制代码
而后能够经过这个下拉框对象的text
属性已经预先配置好的location
信息获取到下拉列表的下标:
for org_index, org in enumerate(ele_orglevel.text.split('\n')): if loca in org: ele_org = driver.find_element_by_xpath(xpath + '/option[{}]'.format(str(org_index + 1))) ele_org.click() break 复制代码
这样一级一级的作下来就能够选中预先配置的选项了。我把这些重复的动做作到一个for
循环中,而后将下拉框的选择作成了一个独立的方法,这样代码是否是看起来精简了许多:
def choose_bank(driver, location, top_xpath): locations = location.split(',') for index, loca in enumerate(locations): level = str(index + 1) xpath = top_xpath.replace('1', level) ele_orglevel = driver.find_element_by_xpath(xpath) for org_index, org in enumerate(ele_orglevel.text.split('\n')): if loca in org: ele_org = driver.find_element_by_xpath(xpath + '/option[{}]'.format(str(org_index + 1))) ele_org.click() break xpath = top_xpath.replace('1', str(len(locations) + 1)) try: ele_bottom = driver.find_element_by_xpath(xpath) except: return else: org_index = random.choice(list(range(len(ele_bottom.text.split('\n'))))[1:]) ele_org = driver.find_element_by_xpath(xpath + '/option[{}]'.format(str(org_index + 1))) ele_org.click() 复制代码
而后这样调用就能够了:
choose_bank(driver, paras['location'], '//*[@id="orglevel1"]') 复制代码
因为手机验证码不是程序能直接拿到的东西,因此这个脚本也无能为力,这也是这个脚本只能叫作半自动脚本的缘由。
但这里仍是能简单讲讲业务流程的。
要获取手机验证码,咱们首先得点击“获取验证码”按钮:
btn_sms = driver.find_element_by_xpath('//*[@id="sendValidate"]') btn_sms.click() 复制代码
而后,咱们须要输入手机验证码,而后程序会自动的输入到网页中:
phoneCaptchaNo = input('请输入手机验证码, 按回车键确认(若是还未收到短信,请等到短信以后再输入):\n') ele_phoneCaptchaNo = driver.find_element_by_xpath('//*[@id="phoneCaptchaNo"]') ele_phoneCaptchaNo.send_keys(phoneCaptchaNo) 复制代码
至此,整个表单的信息所有填写完成,如今就差提交了:
ele_infosubmit = driver.find_element_by_xpath('//*[@id="infosubmit"]') ele_infosubmit.click() 复制代码
到这里,整个预定过程就结束了。
咱们的“Python盘记念币系列”也基本结束。
本系列的全部源代码都会放在下面的github仓库里面,有须要能够参考,有问题欢迎指正,谢谢!
https://github.com/TitusWongCN/AutoTokenAppointment
复制代码
后面会有一篇文章对“Python盘记念币系列”作一个总结,同时开始下一个系列,敬请期待!