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中操作列表之List.append()方法的使用
May 20 Python
Python合并字典键值并去除重复元素的实例
Dec 18 Python
疯狂上涨的Python 开发者应从2.x还是3.x着手?
Nov 16 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
Jan 05 Python
10分钟教你用Python实现微信自动回复功能
Nov 28 Python
在pycharm中使用git版本管理以及同步github的方法
Jan 16 Python
django框架实现模板中获取request 的各种信息示例
Jul 01 Python
使用Python将字符串转换为格式化的日期时间字符串
Sep 01 Python
python实现连连看游戏
Feb 14 Python
TensorFlow实现批量归一化操作的示例
Apr 22 Python
Django与数据库交互的实现
Jun 03 Python
python基础之函数的定义和调用
Oct 24 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
php向js函数传参的几种方法
2014/08/10 PHP
js如何判断不同系统的浏览器类型
2013/10/28 Javascript
Jqgrid表格随窗口大小改变而改变的简单实例
2013/12/28 Javascript
jquery操作复选框checkbox的方法汇总
2015/02/05 Javascript
JS实现状态栏跑马灯文字效果代码
2015/10/24 Javascript
详解javascript遍历方式
2015/11/11 Javascript
JavaScript的设计模式经典之代理模式
2016/02/24 Javascript
jQuery实现的网格线绘制方法
2016/06/20 Javascript
js严格模式总结(分享)
2016/08/22 Javascript
js 判断各种数据类型的简单方法(推荐)
2016/08/29 Javascript
JS只能输入正整数的简单实例
2016/10/07 Javascript
微信小程序 http请求详细介绍
2016/10/09 Javascript
详解vue数据渲染出现闪烁问题
2017/06/29 Javascript
Vue项目webpack打包部署到服务器的实例详解
2017/07/17 Javascript
vue.extend实现alert模态框弹窗组件
2018/04/28 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
JS 设计模式之:工厂模式定义与实现方法浅析
2020/05/06 Javascript
uni-app使用countdown插件实现倒计时
2020/11/01 Javascript
uniapp开发小程序实现滑动页面控制元素的显示和隐藏效果
2020/12/10 Javascript
[53:29]完美世界DOTA2联赛循环赛 DM vs Matador BO2第二场 11.04
2020/11/05 DOTA
总结网络IO模型与select模型的Python实例讲解
2016/06/27 Python
numpy数组拼接简单示例
2017/12/15 Python
python读文件保存到字典,修改字典并写入新文件的实例
2018/04/23 Python
python3实现表白神器
2019/04/09 Python
opencv 实现特定颜色线条提取与定位操作
2020/06/02 Python
Python如何读取、写入JSON数据
2020/07/28 Python
HTML5 实现一个访问本地文件的实例
2012/12/13 HTML / CSS
整理HTML5的一些新特性与Canvas的常用属性
2016/01/29 HTML / CSS
设计师家具购买和委托在线市场:Viyet
2016/11/16 全球购物
阿联酋彩妆品牌:OUD MILANO
2019/10/06 全球购物
EMPHASIS艾斐诗官网:周生生旗下原创精品珠宝品牌
2020/12/17 全球购物
在C语言中实现抽象数据类型什么方法最好
2014/06/26 面试题
入党综合考察材料
2014/06/02 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
2015年个人思想总结
2015/03/09 职场文书
学校隐患排查制度
2015/08/05 职场文书