python实现问卷星网站的自动填写

 

由于有一个课程要求进行调查数据的统计,并且小组里选用的是问卷星为平台,问题的形式比较单一,都为单选或多选,因而想到了用python实现一个脚原本代替小组里你们的手动填写。。css

大致上使用的就是python+Selenium+PIL+Tesseracthtml

Selenium 是一种浏览器自动化测试框架,经过它检索html与css代码就能够轻松地找到想要的单选框、复选框、提交键等等,而后即可以自动化地实现点击事件。但在这个过程当中,仍是有不少细节须要注意的。python

例如我使用的firefox浏览器须要下载一个调试驱动插件 -> "geckodriver" 。git

在最后提交数据的时候使用click()函数没有起到跳转页面的做用,最后是使用send_keys(Keys.ENTER),也就是按Enter键才能实现。猜想是资料中说起的click只是触发事件的方式的其中一种。github

PIL (Python Image Library)则是python的一个图形处理库,在一段时间内提交的次数过多时,网站便会要求输入验证码,这时候就要经过Selenium截取屏幕图片而后经过PIL进行进一步的截取和优化图片的效果。由于验证码当中可能会有干扰线、拉伸变形,这时候就要经过处理才能更好地判断出当中的数据。web

Tesseract 是一款由HP实验室开发由Google维护的开源的光学字符识别引擎,PIL处理事后的图片即是经过tesseract来与从github上已有的训练数据进行匹配。算法

 

 1 # coding: utf-8
 2 
 3 from selenium import  webdriver
 4 from selenium.webdriver.common.by import By
 5 from selenium.webdriver.common.keys import Keys
 6 from selenium.webdriver.support.ui import Select
 7 from selenium.webdriver.common.action_chains import ActionChains
 8 from selenium.common.exceptions import NoAlertPresentException
 9 from PIL import Image,ImageEnhance
10 import random,os,time,pytesseract
11 
12 bs = webdriver.Firefox(executable_path="geckodriver")
13 bs.set_window_size(600,400)
14 
15 def func():
16     bs.get('https://www.wjx.cn/m/17854971.aspx/')
17     bs.find_elements_by_class_name("ui-radio")[0].click()
18     bs.find_elements_by_class_name("ui-checkbox")[1].click()
19     bs.find_elements_by_class_name("ui-radio")[2].click()
20     bs.find_elements_by_class_name("ui-checkbox")[4].click()
21     bs.find_elements_by_class_name("ui-checkbox")[5].click()
22     bs.find_elements_by_class_name("ui-checkbox")[8].click()
23     bs.find_elements_by_class_name("ui-checkbox")[11].click()
24     bs.find_elements_by_class_name("ui-radio")[6].click()
25     bs.find_elements_by_class_name("ui-checkbox")[random.randint(14, 17)].click()
26     try:
27         bs.find_element_by_id("yucinput").click()
28         time.sleep(2)
29         bs.get_screenshot_as_file('D://python_project//wholepage.png')
30         im = Image.open("D://python_project//wholepage.png")
31         box = (160, 180, 409, 308)
32         region = im.crop(box)
33         region.save("D://python_project//testwholepage.png")
34         im = Image.open("D://python_project//testwholepage.png")
35         im = im.convert("L")
36         threshold = 55
37         pixdata = im.load()
38         w, h = im.size
39         for y in range(h):
40             for x in range(w):
41                 if pixdata[x, y] < threshold: pixdata[x, y] = 0 else: pixdata[x, y] = 255 for y in range(1, h - 1): for x in range(1, w - 1): count = 0 if pixdata[x, y - 1] > 245:
42                     count = count + 1
43                 if pixdata[x, y + 1] > 245:
44                     count = count + 1
45                 if pixdata[x - 1, y] > 245:
46                     count = count + 1
47                 if pixdata[x + 1, y] > 245:
48                     count = count + 1
49                 if count > 2:
50                     pixdata[x, y] = 255
51 
52         im.save("D://python_project//newMethod.png")
53         img = Image.open("D://python_project//newMethod.png")
54         code = pytesseract.image_to_string(img, "eng")
55         newCode = ''
56         for c in code:
57             if(c.isalnum()):
58                 newCode += c
59         print(newCode)
60         bs.find_element_by_id("yucinput").send_keys(newCode)
61     except Exception:
62         print("other_func()")
63     finally:
64         bs.find_element_by_id("ctlNext").send_keys(Keys.ENTER)
65 
66 def func2():
67     bs.get('https://www.wjx.cn/m/17854971.aspx/')
68     bs.find_elements_by_class_name("ui-radio")[random.randint(0, 1)].click()
69     bs.find_elements_by_class_name("ui-checkbox")[random.randint(0, 2)].click()
70     bs.find_elements_by_class_name("ui-radio")[random.randint(2, 4)].click()
71     bs.find_elements_by_class_name("ui-checkbox")[random.randint(3, 6)].click()
72     bs.find_elements_by_class_name("ui-checkbox")[random.randint(7, 10)].click()
73     bs.find_elements_by_class_name("ui-checkbox")[random.randint(11, 13)].click()
74     bs.find_elements_by_class_name("ui-radio")[random.randint(5, 7)].click()
75     bs.find_elements_by_class_name("ui-checkbox")[random.randint(14, 17)].click()
76     bs.find_element_by_id("ctlNext").send_keys(Keys.ENTER)
77 
78 ''' def check(css):
79 
80     s = bs.find_elements_by_css_selector(css_selector=css).
81     if(len(s) == 0):
82         func2()
83     elif len(s) == 1:
84         func() '''
85 
86 while True:
87     try:
88         '''check("#yucinput")'''
89         func()
90     except Exception:
91         t = bs.switch_to_alert()
92         print(t.text)
93         t.accept()
94     time.sleep(2)

 

两天赶出来的代码。。很是混乱,最后仍是能够跑起来。不过tesseract的准确率有点感人,大概是十个里面对上四个就不错了。可是自动化处理起来的效率毕竟仍是高于人工输入的。最主要的缘由我想仍是在验证码图片方面处理得不够好,里面图片处理首先是转成灰度图而后二值化而后对干扰线进行处理。而数据的输入能够采起random.randint(x,y) 就可让数据平均显示。浏览器

 

这是处理前框架

这是处理后dom

 

这已是比较理想的状况 干扰线并无太多与字体重叠在一块儿

 

还有一处地方就是我是把py文件放在tesseract的安装目录下才可以运行起来,可是我已经添加了tesseract环境变量。这里仍是搞不懂的,还有具体图像优化的算法 仍是要再学习的。还有问卷星网站是必定时间内太多提交才会要求输入验证码(固然,其实这个也能够设置为每次提交都要输入验证码),因此就要使用异常的作区别对待,异常的使用不太熟,也是恰好运行起来了。。还要学习学习。无论这样使用异常处理是否正确,不过也很是有用地帮助我理解异常这一律念了。

 

经过这两天的调试,最明显体会到的就是python做为一门脚本语言,真的很是神奇与方便。大量的现存库能够帮助人们在短期里作出同样东西来。

 

 

参考资料:

Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登陆

 http://www.51testing.com/html/64/272264-200302.htmls

 

Selenium.click 不等于手动单击

http://www.51testing.com/html/64/272264-200302.html

相关文章
相关标签/搜索