weifeng1998

超级鹰

  在这个项目中使用超级鹰来识别验证码。超级鹰的官方接入文档如下。

 1 #!/usr/bin/env python
 2 # coding:utf-8
 3 
 4 import requests
 5 from hashlib import md5
 6 
 7 class Chaojiying_Client(object):
 8     def __init__(self, username, password, soft_id):
 9         self.username = username
10         password =  password.encode(\'utf8\')
11         self.password = md5(password).hexdigest()
12         self.soft_id = soft_id
13         self.base_params = {
14             \'user\': self.username,
15             \'pass2\': self.password,
16             \'softid\': self.soft_id,
17         }
18         self.headers = {
19             \'Connection\': \'Keep-Alive\',
20             \'User-Agent\': \'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)\',
21         }
22     def PostPic(self, im, codetype):
23         """
24         im: 图片字节
25         codetype: 题目类型 参考 http://www.chaojiying.com/price.html
26         """
27         params = {
28             \'codetype\': codetype,
29         }
30         params.update(self.base_params)
31         files = {\'userfile\': (\'ccc.jpg\', im)}
32         r = requests.post(\'http://upload.chaojiying.net/Upload/Processing.php\', data=params, files=files, headers=self.headers)
33         return r.json()
34     def ReportError(self, im_id):
35         """
36         im_id:报错题目的图片ID
37         """
38         params = {
39             \'id\': im_id,
40         }
41         params.update(self.base_params)
42         r = requests.post(\'http://upload.chaojiying.net/Upload/ReportError.php\', data=params, headers=self.headers)
43         return r.json()
44 
45 if __name__ == \'__main__\':
46     chaojiying = Chaojiying_Client(\'超级鹰用户名\', \'超级鹰用户名的密码\', \'软件ID\')           # 用户中心 > 软件ID 生成一个用来接入接口的软件ID
47     im = open(\'验证码.jpg\', \'rb\').read()                                                # 如果是WIN系统,有时本地图片路径可能须要双斜杠//
48     print(chaojiying.PostPic(im, 1902))                                                # 1902是需要验证码的类型,为常见4~6位英文数字。可以在官网查看更多类型。  

 

思路

  1 使用webdriver调用谷歌浏览器,然后请求滴滴打码网站。
  2 通过selenium的xpath定位方法找到输入账号、密码、验证码、登陆的位置,并且传送具体的账号、密码给对应的位置。
  3 对于传送验证码的问题:首先需要重新单独请求验证码,然后将验证码下载到本地,接着使用超级鹰来识别下载到本地的验证码,把识别后的验证码传送到网页中输入验证码的位置。
  4 点击登陆的位置。

 1 from selenium import webdriver
 2 import request
 3 
 4 #打开谷歌浏览器
 5 driver = webdriver.Chrome(r\'D:\Python37\Lib\chromedriver.exe\')
 6 #第一次请求滴滴打码网站
 7 driver.get(\'http://www.ddocr.com/user/login.html\')
8 #传送账号、密码到相应的位置 9 driver.find_element_by_xpath(\'//*[@id="account"]\').send_keys(\'账号\') 10 driver.find_element_by_xpath(\'//*[@id="password"]\').send_keys(\'密码\') 11 12 #第二次重新请求下载到本地的验证码 13 src = driver.find_element_by_xpath(\'//*[@id="verifyImg"]\').get_attribute(\'src\') 14 yanzhengma = requests.get(src) 15 #将验证码下载到本地 16 with open(\'yanzhengma.jpg\',\'wb\') as file: 17 file.write(yanzhengma.content)
18 #使用超级鹰识别下载到本地的验证码 19 #定义Chaojiying_Client类的代码是超级鹰官网自带的 20 from hashlib import md5 21 class Chaojiying_Client(object): 22 def __init__(self, username, password, soft_id): 23 self.username = username 24 self.password = md5(password.encode(\'utf8\')).hexdigest() 25 self.soft_id = soft_id 26 self.base_params = { 27 \'user\': self.username, 28 \'pass2\': self.password, 29 \'softid\': self.soft_id, 30 } 31 self.headers = { 32 \'Connection\': \'Keep-Alive\', 33 \'User-Agent\': \'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)\', 34 } 35 def PostPic(self, im, codetype): 36 """ 37 im: 图片字节 38 codetype: 题目类型 参考 http://www.chaojiying.com/price.html 39 """ 40 params = { 41 \'codetype\': codetype, 42 } 43 params.update(self.base_params) 44 files = {\'userfile\': (\'ccc.jpg\', im)} 45 r = requests.post(\'http://upload.chaojiying.net/Upload/Processing.php\', data=params, files=files, headers=self.headers) 46 return r.json() 47 def ReportError(self, im_id): 48 """ 49 im_id:报错题目的图片ID 50 """ 51 params = { 52 \'id\': im_id, 53 } 54 params.update(self.base_params) 55 r = requests.post(\'http://upload.chaojiying.net/Upload/ReportError.php\', data=params, headers=self.headers) 56 return r.json() 57 chaojiying = Chaojiying_Client(\'账号\', \'密码\', \'软件ID\') 58 im = open(\'yanzhengma.jpg\', \'rb\').read() 59 60 #将超级鹰识别的验证码传入网页中输入验证码的位置。chaojiying.PostPic(im,1004)[\'pic_str\']是超级鹰识别验证码的结果。 61 driver.find_element_by_xpath(\'//*[@id="verity"]\').send_keys(chaojiying.PostPic(im, 1004)[\'pic_str\'])
62 #点击登陆 63 driver.find_element_by_xpath(\'//*[@id="userLogin"]/div[4]/button\').click()

运行后的bug

       运行后发现自动输入验证码时与网页上显示的验证码并不一致。经过思考后,明白了问题出在思路的第三步。因为网页上显示的验证码是我们第一次请求滴滴打码时的验证码,而自动输入的验证码是我们第二次重新请求下载到本地的验证码。这两次请求的验证码并不是同一个,所以就出现了这个bug。即思路的第三步并不可行。

解决——思路的第三步

1 使用selenium截取全屏,然后再截取全屏中特定区域(即验证码的区域)的图片。

例如:①使用selenium截取百度网页全屏

1 driver = webdriver.Chrome()
2 wait = WebDriverWait(driver, 10)
3 driver.get(\'https://www.baidu.com\')
4 time.sleep(3)
5 
6 # 用 get_screenshot_as_file(\'绝对路径\') 方法来截取全屏,并把截取的全屏保存到绝对路径。
7 # 注:保存的图片格式必须为png。
8 driver.get_screenshot_as_file(\'C:\Users\desktop\quanping.png\')

 

②截取全屏中特定区域(验证码)的图片

 1 from PIL import Image
 2 # 对验证码所在位置进行定位,注意定位时电脑的缩放布局必须要设置为100%,不然定位不准确。
 3 img = driver.find_element_by_xpath(\'***\')
 4 time.sleep(2)
 5 
 6 # location属性以字典的形式返回该图片对象(既这张图片)在浏览器中的坐标。假设图片的坐标是(30,30) 即返回{‘x’:30,‘y’:30} 坐标轴是以屏幕左上角为原点,x轴向右递增,y轴向下递增。
 7 location = img.location
 8 # size属性以字典的形式返回该图片对象(即这张图片)的宽度和高度。假设图片的宽度和高度均为30,即返回{‘height’:30,‘width’:30}
 9 size = img.size
10 
11 left = location[\'x\']
12 top = location[\'y\']
13 right = left + size[\'width\']
14 bottom = top + size[\'height\']
15 
16 # pillow模块使用crop((left, up, right, below))方法来裁剪图片
17 obj = Image.open(\'quanping.png\')
18 yanzhengma = obj.crop((left, top, right, bottom))
19 # yanzhengma.show()
20 
21 # 把截取到的验证码图片下载到本地。
22 Image.save(\'yanzhengma.png\')

 

 

 

2 使用超级鹰对下载到本地的验证码进行识别。
3 把超级鹰识别后的验证码传送到网页中输入验证码的位置。

 1 \'\'\'2020-7-2 by 微风\'\'\'
 2 
 3 from selenium import webdriver
 4 import requests
 5 
 6 #打开谷歌浏览器
 7 driver = webdriver.Chrome(r\'D:\Python37\Lib\chromedriver.exe\')
 8 #打开浏览器后发送get请求
 9 driver.get(\'http://www.ddocr.com/user/login.html\')
10 #将浏览器最大化显示
11 driver.maximize_window()
12 
13 driver.find_element_by_xpath(\'//*[@id="account"]\').send_keys(\'账号\')
14 driver.find_element_by_xpath(\'//*[@id="password"]\').send_keys(\'密码\')
15 
16 from PIL import Image
17 driver.get_screenshot_as_file(\'D:\PycharmProjects\爬虫\quanping.png\')
18 obj = Image.open(\'quanping.png\')
19 
20 # 要注意截取验证码时电脑的缩放布局必须要设置为100%,不然定位不准确。
21 location = driver.find_element_by_xpath(\'//*[@id="verifyImg"]\').location
22 size = driver.find_element_by_xpath(\'//*[@id="verifyImg"]\').size
23 
24 left = location[\'x\']
25 top = location[\'y\']
26 right = left + size[\'width\']
27 bottom = top + size[\'height\']
28 yanzhengma = obj.crop((left,top,right,bottom))
29 yanzhengma.save(\'yanzhengma.png\')
30 
31 #使用超级鹰识别下载到本地的验证码
32 #定义Chaojiying_Client类的代码是超级鹰官网自带的
33 from hashlib import md5
34 class Chaojiying_Client(object):
35     def __init__(self, username, password, soft_id):
36         self.username = username
37         self.password = md5(password.encode(\'utf8\')).hexdigest()
38         self.soft_id = soft_id
39         self.base_params = {
40             \'user\': self.username,
41             \'pass2\': self.password,
42             \'softid\': self.soft_id,
43         }
44         self.headers = {
45             \'Connection\': \'Keep-Alive\',
46             \'User-Agent\': \'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)\',
47         }
48     def PostPic(self, im, codetype):
49         """
50         im: 图片字节
51         codetype: 题目类型 参考 http://www.chaojiying.com/price.html
52         """
53         params = {
54             \'codetype\': codetype,
55         }
56         params.update(self.base_params)
57         files = {\'userfile\': (\'ccc.jpg\', im)}
58         r = requests.post(\'http://upload.chaojiying.net/Upload/Processing.php\', data=params, files=files, headers=self.headers)
59         return r.json()
60     def ReportError(self, im_id):
61         """
62         im_id:报错题目的图片ID
63         """
64         params = {
65             \'id\': im_id,
66         }
67         params.update(self.base_params)
68         r = requests.post(\'http://upload.chaojiying.net/Upload/ReportError.php\', data=params, headers=self.headers)
69         return r.json()
70 chaojiying = Chaojiying_Client(\'账号\', \'密码\', \'软件ID\')
71 im = open(\'yanzhengma.png\', \'rb\').read()
72 
73 #将超级鹰识别的验证码传入网页中输入验证码的位置。chaojiying.PostPic(im,1004)[\'pic_str\']是超级鹰识别下载到本地的验证码的结果。
74 driver.find_element_by_xpath(\'//*[@id="verity"]\').send_keys(chaojiying.PostPic(im, 1004)[\'pic_str\'])
75 #点击登陆
76 driver.find_element_by_xpath(\'//*[@id="userLogin"]/div[4]/button\').click()

 

chaojiying.PostPic(im,1004)[\'pic_str\']是超级鹰识别验证码的结果。

分类:

技术点:

相关文章: