Python爬虫爬验证码实现功能详解


Posted in Python onApril 14, 2016

主要实现功能:

- 登陆网页

- 动态等待网页加载

- 验证码下载

很早就有一个想法,就是自动按照脚本执行一个功能,节省大量的人力——个人比较懒。花了几天写了写,本着想完成验证码的识别,从根本上解决问题,只是难度太高,识别的准确率又太低,计划再次告一段落。
希望这次经历可以与大家进行分享和交流。

Python打开浏览器

相比与自带的urllib2模块,操作比较麻烦,针对于一部分网页还需要对cookie进行保存,很不方便。于是,我这里使用的是Python2.7下的selenium模块进行网页上的操作。

测试网页:http://graduate.buct.edu.cn

打开网页:(需下载chromedriver)

为了支持中文字符输出,我们需要调用sys模块,把默认编码改为 UTF-8

<code class="hljs python">from selenium.webdriver.support.ui import Select, WebDriverWait
from selenium import webdriver
from selenium import common
from PIL import Image
import pytesser
import sys
reload(sys)
sys.setdefaultencoding('utf8')
broswer = webdriver.Chrome()
broswer.maximize_window()
username = 'test'
password = 'test'
url = 'http://graduate.buct.edu.cn'
broswer.get(url)</code>

等待网页加载完毕

使用的是selenium中的WebDriverWait,上面的代码中已经加载

<code class="hljs livecodeserver">url = 'http://graduate.buct.edu.cn'
broswer.get(url)
wait = WebDriverWait(webdriver,5) #设置超时时间5s
# 在这里输入表单填写并加载的代码
elm = wait.until(lambda webdriver: broswer.find_element_by_xpath(xpathMenuCheck))</code>

元素定位、字符输入

接下来我们需要进行登录操作:这里我使用的是Chrome,右键选择需要进行填写内容的部分,选择检查,会自动转跳到 F12下的开发者模式(全程需要这个功能来找到相关的资源)。

Python爬虫爬验证码实现功能详解

vczKprbLJnJkcXVvO9Gh1PHT0LnYtcSyv7fWPGJyIC8+DQo8aW1nIGFsdD0="这里写图片描述" src="https://3water.com/uploadfile/Collfiles/20160414/20160414092144893.png" title="\" />

这里我们看到有一个value = “1”,考虑到下拉框的属性,我们只要想办法把这个value赋值给UserRole就好了。
这里使用的是通过selenium的Select模块来进行选择,定位控件使用 find_element_by_**,能一一对应,很方便。

<code class="hljs sql">select = Select(broswer.find_element_by_id('UserRole'))
select.select_by_value('2')
name = broswer.find_element_by_id('username')
name.send_keys(username)
pswd = broswer.find_element_by_id('password')
pswd.send_keys(password)
btnlg = broswer.find_element_by_id('btnLogin')
btnlg.click()</code>

这是用脚本自动填充完的效果,之后就会转跳到下一页。

Python爬虫爬验证码实现功能详解

这里,我需要的是功能是自动对学术报告进行报名

Python爬虫爬验证码实现功能详解

对需要已有的报告右键即可发现和这个活动有关的消息,因现在没有报告,所以只显示了标题,但对于后面的有效报告识别有相似的地方。

Python爬虫爬验证码实现功能详解

对于元素的定位,我优先选择了 xpath,根据测试,可以唯一定位一个元素的位置,很好用。

<code class="hljs perl">//*[@id="dgData00"]/tbody/tr/td[2] (前面是xpath)</code>

Python爬虫爬验证码实现功能详解

爬取信息

接下来我们要进行的步骤是爬取现有的有效报告:

<code class="hljs axapta"># 寻找有效报告
flag = 1
count = 2
count_valid = 0
while flag:
  try:
    category = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(count) + ']/td[1]').text
    count += 1
  except common.exceptions.NoSuchElementException:
    break
# 获取报告信息
flag = 1
for currentLecture in range(2, count):
  # 类别
  category = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[1]').text
  # 名称
  name = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[2]').text
  # 单位
  unitsPublish = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[3]').text
  # 开始时间
  startTime = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[4]').text
  # 截止时间
  endTime = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[5]').text</code>

爬取验证码

Python爬虫爬验证码实现功能详解

对网页中的验证码进行元素审查后,我们发现了其中的一个一个链接,是 IdentifyingCode.apsx,后面我们就对这个页面进行加载,并批量获取验证码。

Python爬虫爬验证码实现功能详解

爬取的思路是用selenium截取当前页面(仅显示部分),并保存到本地——需要翻页并截取特定位置的请研究:

broswer.set_window_position(**)相关函数;然后人工进行验证码的定位,通过PIL模块进行截取并保存。

最后调用谷歌在Python下的pytesser进行字符识别,但这个网站的验证码有很多的干扰,外加字符旋转,仅仅能识别其中的一部分字符。

<code class="hljs livecodeserver"># 获取验证码并验证(仅仅一幅)
authCodeURL = broswer.find_element_by_xpath('//*[@id="Table2"]/tbody/tr[2]/td/p/img').get_attribute('src') # 获取验证码地址
broswer.get(authCodeURL)
broswer.save_screenshot('text.png')
rangle = (0, 0, 64, 28)
i = Image.open('text.png')
frame4 = i.crop(rangle)
frame4.save('authcode.png')
qq = Image.open('authcode.png')
text = pytesser.image_to_string(qq).strip()</code>
<code class="hljs axapta"># 批量获取验证码
authCodeURL = broswer.find_element_by_xpath('//*[@id="Table2"]/tbody/tr[2]/td/p/img').get_attribute('src') # 获取验证码地址
# 获取学习样本
for count in range(10):
  broswer.get(authCodeURL)
  broswer.save_screenshot('text.png')
  rangle = (1, 1, 62, 27)
  i = Image.open('text.png')
  frame4 = i.crop(rangle)
  frame4.save('authcode' + str(count) + '.png')
  print 'count:' + str(count)
  broswer.refresh()
broswer.quit()</code>

爬取下来的验证码

Python爬虫爬验证码实现功能详解

一部分验证码原图:Python爬虫爬验证码实现功能详解Python爬虫爬验证码实现功能详解Python爬虫爬验证码实现功能详解Python爬虫爬验证码实现功能详解

从上面的验证码看出,字符是带旋转的,而且因为旋转造成的重叠对于后续的识别也有很大的影响。我曾尝试过使用神经网络进行训练,但因没有进行特征向量的提取,准确率低得离谱。

关于Python爬虫爬验证码实现功能详解就给大家介绍到这里,希望对大家有所帮助!

Python 相关文章推荐
python 实现归并排序算法
Jun 05 Python
Tornado服务器中绑定域名、虚拟主机的方法
Aug 22 Python
简化Python的Django框架代码的一些示例
Apr 20 Python
Python设计模式中单例模式的实现及在Tornado中的应用
Mar 02 Python
Python模拟脉冲星伪信号频率实例代码
Jan 03 Python
替换python字典中的key值方法
Jul 06 Python
python将list转为matrix的方法
Dec 12 Python
Python脚本修改阿里云的访问控制列表的方法
Mar 08 Python
通过 Django Pagination 实现简单分页功能
Nov 11 Python
Python关于反射的实例代码分享
Feb 20 Python
解决windows下python3使用multiprocessing.Pool出现的问题
Apr 08 Python
python 元组的使用方法
Jun 09 Python
Python实现简单登录验证
Apr 13 #Python
Python数组定义方法
Apr 13 #Python
Python基于select实现的socket服务器
Apr 13 #Python
Python简单实现子网掩码转换的方法
Apr 13 #Python
Python多进程分块读取超大文件的方法
Apr 13 #Python
Python字符串拼接、截取及替换方法总结分析
Apr 13 #Python
Python字符串格式化输出方法分析
Apr 13 #Python
You might like
第六节 访问属性和方法 [6]
2006/10/09 PHP
PHP延迟静态绑定示例分享
2014/06/22 PHP
tp5.1 框架数据库常见操作详解【添加、删除、更新、查询】
2020/05/26 PHP
Script的加载方法小结
2011/01/12 Javascript
javascript删除option选项的多种方法总结
2013/11/22 Javascript
jquery选择器大全 全面详解jquery选择器
2014/03/06 Javascript
director.js实现前端路由使用实例
2015/02/03 Javascript
AngularJS内置指令
2015/02/04 Javascript
javascript包装对象实例分析
2015/03/27 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
最佳的JavaScript错误处理实践
2016/07/16 Javascript
原生js获取iframe中dom元素--父子页面相互获取对方dom元素的方法
2016/08/05 Javascript
bootstrapfileinput实现文件自动上传
2016/11/08 Javascript
BootStrap中关于Select下拉框选择触发事件及扩展
2016/11/22 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
2017/01/11 Javascript
node.js中EJS 模板快速入门教程
2017/05/08 Javascript
JS禁止浏览器右键查看元素或按F12审查元素自动关闭页面示例代码
2017/09/07 Javascript
nginx配置React静态页面的方法教程
2017/11/03 Javascript
Vue 动态组件与 v-once 指令的实现
2019/02/12 Javascript
vue 重塑数组之修改数组指定index的值操作
2020/08/09 Javascript
JS遍历树层级关系实现原理解析
2020/08/31 Javascript
element-ui中dialog弹窗关闭按钮失效的解决
2020/09/22 Javascript
python运行其他程序的实现方法
2017/07/14 Python
python利用多种方式来统计词频(单词个数)
2019/05/27 Python
基于Python3.6中的OpenCV实现图片色彩空间的转换
2020/02/03 Python
pytorch实现从本地加载 .pth 格式模型
2020/02/14 Python
Python 实现日志同时输出到屏幕和文件
2020/02/19 Python
浅谈spring boot 集成 log4j 解决与logback冲突的问题
2020/02/20 Python
python3代码中实现加法重载的实例
2020/12/03 Python
新加坡网上化妆品店:Best Buy World
2018/05/18 全球购物
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
高中生毕业自我鉴定
2013/10/10 职场文书
招聘单位介绍信
2014/01/14 职场文书
志愿者爱心公益活动策划方案
2014/09/15 职场文书
2016大学优秀学生干部事迹材料
2016/03/01 职场文书
英镑符号 £
2022/02/17 杂记