主要实现功能:

- 登陆网页

- 动态等待网页载入

- 验证码下载

非常早就有一个想法,就是自己主动依照脚本运行一个功能。节省大量的人力——个人比較懒。花了几天写了写,本着想完成验证码的识别,从根本上解决这个问题,仅仅是难度太高,识别的准确率又太低。计划再次告一段落。

希望这次经历能够与大家进行分享和交流。

注:代码中的 username与password都是无效的!


Python打开浏览器

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

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


打开网页:(需下载chromedriver

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

  1. from selenium.webdriver.support.ui import Select, WebDriverWait
  2. from selenium import webdriver
  3. from selenium import common
  4. from PIL import Image
  5. import pytesser
  6. import sys
  7. reload(sys)
  8. sys.setdefaultencoding('utf8')
  9. broswer = webdriver.Chrome()
  10. broswer.maximize_window()
  11. username = 'test'
  12. password = 'test'
  13. url = 'http://graduate.buct.edu.cn'
  14. broswer.get(url)

等待网页载入完成

使用的是selenium中的WebDriverWait。上面的代码中已经载入

  1. url = 'http://graduate.buct.edu.cn'
  2. broswer.get(url)
  3. wait = WebDriverWait(webdriver,5) #设置超时时间5s
  4. # 在这里输入表单填写并载入的代码
  5. elm = wait.until(lambda webdriver: broswer.find_element_by_xpath(xpathMenuCheck))

元素定位、字符输入

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

以下的UserRole部分就是和“教师端”选择有关的部分



这里我们看到有一个value = “1”,考虑到下拉框的属性,我们仅仅要想办法把这个value赋值给UserRole就好了。

这里使用的是通过selenium的Select模块来进行选择,定位控件使用 find_element_by_**,能一一相应,非常方便。

  1. select = Select(broswer.find_element_by_id('UserRole'))
  2. select.select_by_value('2')
  3. name = broswer.find_element_by_id('username')
  4. name.send_keys(username)
  5. pswd = broswer.find_element_by_id('password')
  6. pswd.send_keys(password)
  7. btnlg = broswer.find_element_by_id('btnLogin')
  8. btnlg.click()

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


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

对须要已有的报告右键就可以发现和这个活动有关的消息,因如今没有报告,所以仅仅显示了标题。但对于后面的有效报告识别有类似的地方。

对于元素的定位,我优先选择了 xpath。依据測试。能够唯一定位一个元素的位置,非常好用。

  1. //*[@id="dgData00"]/tbody/tr/td[2] (前面是xpath)


爬取信息

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

  1. # 寻找有效报告
  2. flag = 1
  3. count = 2
  4. count_valid = 0
  5. while flag:
  6. try:
  7. category = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(count) + ']/td[1]').text
  8. count += 1
  9. except common.exceptions.NoSuchElementException:
  10. break
  11. # 获取报告信息
  12. flag = 1
  13. for currentLecture in range(2, count):
  14. # 类别
  15. category = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[1]').text
  16. # 名称
  17. name = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[2]').text
  18. # 单位
  19. unitsPublish = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[3]').text
  20. # 開始时间
  21. startTime = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[4]').text
  22. # 截止时间
  23. endTime = broswer.find_element_by_xpath('//*[@id="dgData00"]/tbody/tr[' + str(currentLecture) + ']/td[5]').text

爬取验证码

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

爬取的思路是用selenium截取当前页面(仅显示部分)。并保存到本地——须要翻页并截取特定位置的请研究:broswer.set_window_position(**)相关函数;然后人工进行验证码的定位,通过PIL模块进行截取并保存。

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

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

一部分验证码原图:

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


这个是一位作者实践后的心得:

http://www.cnblogs.com/sweetwxh/p/captcha_recognize.html

看了之后我变得清醒。决定不再继续识别验证码了。但这个经验非常实用,以后就能够拿来爬各种数据了

Python 爬验证码的更多相关文章

  1. Python 爬取 热词并进行分类数据分析-[解释修复+热词引用]

    日期:2020.02.02 博客期:141 星期日 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...

  2. Python 爬取所有51VOA网站的Learn a words文本及mp3音频

    Python 爬取所有51VOA网站的Learn a words文本及mp3音频 #!/usr/bin/env python # -*- coding: utf-8 -*- #Python 爬取所有5 ...

  3. python爬取网站数据

    开学前接了一个任务,内容是从网上爬取特定属性的数据.正好之前学了python,练练手. 编码问题 因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这个机会算是彻底搞清楚了. 问题要从文字的编码讲 ...

  4. python爬取某个网页的图片-如百度贴吧

    python爬取某个网页的图片-如百度贴吧 作者:vpoet mail:vpoet_sir@163.com 注:随意copy,不用告诉我 #coding:utf-8 import urllib imp ...

  5. python爬爬爬之单网页html页面爬取

    python爬爬爬之单网页html页面爬取 作者:vpoet mail:vpoet_sir@163.com 注:随意copy 不用告诉我 #coding:utf-8 import urllib2 Re ...

  6. Python:爬取乌云厂商列表,使用BeautifulSoup解析

    在SSS论坛看到有人写的Python爬取乌云厂商,想练一下手,就照着重新写了一遍 原帖:http://bbs.sssie.com/thread-965-1-1.html #coding:utf- im ...

  7. 使用python爬取MedSci上的期刊信息

    使用python爬取medsci上的期刊信息,通过设定条件,然后获取相应的期刊的的影响因子排名,期刊名称,英文全称和影响因子.主要过程如下: 首先,通过分析网站http://www.medsci.cn ...

  8. python识别验证码——PIL,pytesser,pytesseract的安装

    1.使用Python识别验证码需要安装Python的图像处理模块(PIL.pytesser.pytesseract) (安装过程需要pip,在我的Python中已经安装pip了,pip的安装就不在赘述 ...

  9. Python 爬取美团酒店信息

    事由:近期和朋友聊天,聊到黄山酒店事情,需要了解一下黄山的酒店情况,然后就想着用python 爬一些数据出来,做个参考 主要思路:通过查找,基本思路清晰,目标明确,仅仅爬取美团莫一地区的酒店信息,不过 ...

随机推荐

  1. Android中asset文件夹和raw文件夹区别(转载)

    原文地址:http://www.cnblogs.com/leizhenzi/archive/2011/10/18/2216428.html *res/raw和assets的相同点: 1.两者目录下的文 ...

  2. /proc/meminfo分析(一)

    本文主要分析/proc/meminfo文件的各种输出信息的具体含义. 一.MemTotal MemTotal对应当前系统中可以使用的物理内存. 这个域实际是对应内核中的totalram_pages这个 ...

  3. vim打造开发IDE

    个人的插件和配置 set nocompatible " 去除VI一致性,必须要添加 filetype off " 必须要添加 " advanced keys " ...

  4. 音频特征提取——pyAudioAnalysis工具包

    作者:桂. 时间:2017-05-04  18:31:09 链接:http://www.cnblogs.com/xingshansi/p/6806637.html 前言 语音识别等应用离不开音频特征的 ...

  5. Spring依赖注入构造器注入(通过构造函数注入)

    在src目录下建立applicationContext.xml   (Spring 管理 bean的配置文件) <?xml version="1.0" encoding=&q ...

  6. 通过GUID生成可持久化的PID

    byte[] buffer = Guid.NewGuid().ToByteArray(); ); GUID是微软针对UUID的实现,直接生成会大于long类型的最大长度. 但只要转换一下即可

  7. ISE和Modelsim联合仿真(详细步骤讲解)

    ISE和Modelsim联合仿真(转) 地址:http://www.cnblogs.com/feitian629/archive/2013/07/13/3188192.html 相信很多人会遇到过这个 ...

  8. 并行开发系列 Plinq等

    http://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html

  9. 解决方式-在Mac系统中,Eclipse无法导入含有中文路径的project

    1.改动eclipse.app/Contents/Info.plist.查找 <key>CFBundleExecutable<key> 在其上方加入下面代码 <? xml ...

  10. ETL调度开发(5)——连接数据库运行数据库命令子程序

    ETL调度中读写数据信息,都须要连接数据库,以下的子程序通过传入的数据库连接字符串和数据库命令(或SQL)运行所须要的操作: #!/usr/bin/bash #created by lubinsu # ...