(项目)使用selenium的截屏功能实现自动登陆滴滴打码网

超级鹰

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

 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']是超级鹰识别验证码的结果。
posted @ 2020-07-02 20:09  菜鸟峰  阅读(274)  评论(0编辑  收藏  举报