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中的对象拷贝示例 python引用传递
Jan 23 Python
跟老齐学Python之字典,你还记得吗?
Sep 20 Python
python中快速进行多个字符替换的方法小结
Dec 15 Python
Python闭包之返回函数的函数用法示例
Jan 27 Python
python微信公众号开发简单流程
Mar 23 Python
python 实现12bit灰度图像映射到8bit显示的方法
Jul 08 Python
pandas DataFrame的修改方法(值、列、索引)
Aug 02 Python
浅谈python图片处理Image和skimage的区别
Aug 04 Python
Django 拆分model和view的实现方法
Aug 16 Python
tensorflow如何批量读取图片
Aug 29 Python
解决Django响应JsonResponse返回json格式数据报错问题
Aug 09 Python
使用python生成大量数据写入es数据库并查询操作(2)
Sep 23 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中通过ADODB库实现调用Access数据库之修正版本
2006/12/31 PHP
国外比较好的几个的Php开源建站平台小结
2010/04/22 PHP
PHP中usort在值相同时改变原始位置问题的解决方法
2011/11/27 PHP
PHP strip_tags()去除HTML、XML以及PHP的标签介绍
2014/02/18 PHP
Windows平台PHP+IECapt实现网页批量截图并创建缩略图功能详解
2019/08/02 PHP
javascript qq右下角滑出窗口 sheyMsg
2010/03/21 Javascript
一个报数游戏js版(约瑟夫环问题)
2010/08/05 Javascript
js通过googleAIP翻译PHP系统的语言配置的实现代码
2011/10/17 Javascript
javascript中的document.open()方法使用介绍
2013/10/09 Javascript
JS判断、校验MAC地址的2个实例
2014/05/05 Javascript
javascript使用 concat 方法对数组进行合并的方法
2016/09/08 Javascript
vue.js element-ui validate中代码不执行问题解决方法
2017/12/18 Javascript
JS操作字符串转数字的常见方法示例
2019/10/29 Javascript
[04:44]DOTA2西游记战队视频彩蛋流出 师徒开黑巧遇林书豪
2016/08/03 DOTA
python3使用urllib示例取googletranslate(谷歌翻译)
2014/01/23 Python
python中类的一些方法分析
2014/09/25 Python
python logging类库使用例子
2014/11/22 Python
Python脚本实现代码行数统计代码分享
2015/03/10 Python
在Django的模型和公用函数中使用惰性翻译对象
2015/07/27 Python
python队列通信:rabbitMQ的使用(实例讲解)
2017/12/22 Python
python中map的基本用法示例
2018/09/10 Python
对python多线程SSH登录并发脚本详解
2019/02/14 Python
pandas分区间,算频率的实例
2019/07/04 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
如何解决安装python3.6.1失败
2020/07/01 Python
Django haystack实现全文搜索代码示例
2020/11/28 Python
python中append函数用法讲解
2020/12/11 Python
迪奥官网:Dior.com
2018/12/04 全球购物
德国、奥地利和瑞士最大的旅行和度假门户网站:HolidayCheck
2019/11/14 全球购物
求职信怎么写
2014/05/23 职场文书
大学国际贸易专业自荐信
2014/06/05 职场文书
2014年最新学校运动会广播稿
2014/09/17 职场文书
2014年招商引资工作总结
2014/11/22 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
通知函格式范文
2015/04/27 职场文书
web前端之css水平居中代码解析
2021/05/20 HTML / CSS