使用selenium模拟登录解决滑块验证问题

目录

1.登录入口

2.点击“账号密码登录”

3.输入账号、密码并点击登录

4.滑块验证过程

5.小结


本次主要是使用selenium模拟登录网页端的TX新闻,本来最开始是模拟请求的,但是某一天突然发现,部分账号需要经过滑块验证才能正常登录,如果还是模拟请求,需要的参数太多了,找的心累。不过好在TX的滑块验证是他们自己开发的,没有极验那么复杂,当然相反的,想要模拟就得自己去一点点探索了,毕竟对极验滑块的破解,网上已经可以找到现成的代码来用了。下面说一下模拟的实现过程和我遇见的问题。

1.登录入口

我是通过来当做登录入口的

部分代码实现:

1

2

3

driver = webdriver.Chrome()

  

driver.get(url)

2.点击“账号密码登录”

selenium可以实现对网页元素的定位,我这里是通过id属性来定位“帐号密码登录”按钮的。这里需要注意的是,有时候可能会因为网络不好等问题导致加载登录入口页会很慢,所以在点击“帐号密码登录”按钮前,需要做一个判断:判断代表“帐号密码登录”的HTML元素是否已经加载完成。

“账号密码登录”按钮的id属性截图:

部分代码实现

1

2

3

4

5

6

element = WebDriverWait(driver, 50.5).until(

  

EC.presence_of_element_located((By.ID"switcher_plogin")))

 <br># from selenium.webdriver.common.by import By

  

element.click()

  

3.输入账号、密码并点击登录

这一步比较简单,直接上代码:

1

2

3

4

5

driver.find_element_by_id('u').send_keys('123456'# 输入用户名

  

driver.find_element_by_id('p').send_keys('ccccc'# 输入密码

  

driver.find_element_by_id('login_button').click() # 点击登录

  

4.滑块验证过程

1)简要说明

因为主要目的就是为了模拟滑块验证,所以在输入用户名和密码的时候直接选择输入“123456”和“ccccc”,这样就必然会跳到滑块验证的页面:

接下来的问题就是如何模拟滑动的过程。这里首先要说一下,经过多次测试发现,TX的滑块验证每次需要拖动的距离是有一定范围的,“缺口”部分的位置基本上都在靠右侧的一面,不像极验的滑块验证,“缺口”部分可能出现在任意的位置,这样在实现“滑动”过程前,就必须判断每次滑动的距离是多少,具体可以看看学习一下大神们都是如何实现极验滑块验证的。所以,对于TX的滑块验证,只要设置一个大概的距离“模拟滑动”即可,失败的时候可以通过增减移动距离进行重试,后面会进一步说明。

2)为什么找不到“蓝色滑块”

前面已经点击了“登录”并跳转到“安全验证”的页面,接着就是去模拟“拖动”截图中的“蓝色滑块”,所以首先要告诉driver,代表“蓝色滑块”的html元素是什么。代表“蓝色滑块”的html元素截图:

通过上面的截图可以知道,id值为"tcaptcha_drag_button"的div标签代表的就是“蓝色滑块”,所以最开始我是直接尝试去拖动它,但是这时候发现报错了,部分截图如下:

报错的原因很明显,在当前得到的所有html元素中,找不到id值为"tcaptcha_drag_button"的div标签。这是为什么?

3)切换frame

为什么出现上面的问题?通过查找相关的资料才知道,在跳转到“安全验证”的页面的时候,“进入”了一个新的frame,可以理解为,在“登录页面”嵌套了一个“验证页面”,而当前的driver加载的html元素全部都是“登录页面”的,想要找到并拖动“蓝色滑块”,就要先切换到“验证页面”,这里通过driver.switch_to方法实现:

1

2

3

iframe = driver.find_element_by_xpath('//iframe'# 找到“嵌套”的iframe

  

driver.switch_to.frame(iframe)     # 切换到iframe

4)模拟拖动

切换到iframe之后,就可以通过driver.find_element_by_id('tcaptcha_drag_button')找到“蓝色滑块”并拖动它了。拖动操作会用到selenium.webdriver的ActionChains类,部分代码如下:

1

2

3

4

5

6

7

8

9

button = driver.find_element_by_id('tcaptcha_drag_button')    # 找到“蓝色滑块”

  

action = ActionChains(driver)            # 实例化一个action对象

  

action.click_and_hold(button).perform()  # perform()用来执行ActionChains中存储的行为

  

action.reset_actions()

  

action.move_by_offset(1800).perform()  # 移动滑块

  

5)构造移动轨迹

为了使拖动过程模拟的更“真实”,可以构造一个滑动轨迹,我这里也是参考了别人的代码看这里,简单实现了一下,实际上TX新闻的滑块验证对这方面好像要求不是很严格:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

def get_track(distance):

  

track = []

  

current = 0

  

mid = distance * 3 / 4

  

= 0.2

  

= 0

  

while current < distance:

  

if current < mid:

  

= 2

  

else:

  

= -3

  

v0 = v

  

= v0 + * t

  

move = v0 * + 1 / 2 * * * t

  

current += move

  

track.append(round(move))

  

return track

  

6)如何确定已经“验证成功”了

接下来的问题就是,我如何告诉程序,已经“验证成功”了呢?经过测试发现,当拖动滑块完成拼图“验证成功”后,网页又从“安全验证”的页面又跳回了“登录页面”,滑动前截图:

滑动验证成功的截图:

成功后跳转回“登录”页面:

通过上面的截图我们可以知道,在“验证通过”之前,在“安全验证”页面我们一直可以看到“拖动下方滑块完成拼图”的文字提示,也就是说,如果验证没有通过,那么在当前的所有html元素中,我们是可以找到文本为“拖动下方滑块完成拼图”的标签的:

通过截图可以知道,该标签的class为"tcaptcha-title",通过driver.find_element_by_class_name('tcaptcha-title').text来判断验证是否成功。

7)重试

前面说了,我们可以通过提前设置一个“可能的”值当初始距离来移动滑块,如果移动的距离“过长”,就减小该值当做下次移动的距离,所以可以加一个while循环。以上过程实现的完整代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

# encoding=utf8

  

  

  

from time import sleep

  

from selenium import webdriver

  

from selenium.webdriver import ActionChains

  

from selenium.webdriver.common.by import By

  

from selenium.webdriver.support import expected_conditions as EC

  

from selenium.webdriver.support.wait import WebDriverWait

  

  

  

url = 'https://xui.ptlogin2.qq.com/cgi-bin/xlogin?&low_login=0&appid=636014201&target=self&border_radius=1&maskOpacity=40&s_url=http%3A//www.qq.com/qq2012/loginSuccess.htm'

  

  

  

def get_track(distance):

  

track = []

  

current = 0

  

mid = distance * 3 / 4

  

= 0.2

  

= 0

  

while current < distance:

  

if current < mid:

  

= 2

  

else:

  

= -3

  

v0 = v

  

= v0 + * t

  

move = v0 * + 1 / 2 * * * t

  

current += move

  

track.append(round(move))

  

return track

  

  

  

def main():

  

driver = webdriver.Chrome()

  

driver.set_window_position(90010)

  

driver.get(url)

  

# 检测id为"switcher_plogin"的元素是否加在DOM树中,如果出现了才能正常向下执行

  

element = WebDriverWait(driver, 50.5).until(

  

EC.presence_of_element_located((By.ID"switcher_plogin"))

  

)

  

element.click()

  

  

  

sleep(1)

  

# 输入用户名和密码

  

driver.find_element_by_id('u').clear()

  

driver.find_element_by_id('u').send_keys('123456')

  

driver.find_element_by_id('p').clear()

  

driver.find_element_by_id('p').send_keys('ccccc')

  

sleep(1)

  

# 点击登录

  

driver.find_element_by_id('login_button').click()

  

  

  

sleep(5)

  

  

  

# 切换iframe

  

try:

  

iframe = driver.find_element_by_xpath('//iframe')

  

except Exception as e:

  

print 'get iframe failed: ', e

  

sleep(2# 等待资源加载

  

driver.switch_to.frame(iframe)

  

  

  

# 等待图片加载出来

  

WebDriverWait(driver, 50.5).until(

  

EC.presence_of_element_located((By.ID"tcaptcha_drag_button"))

  

)

  

try:

  

button = driver.find_element_by_id('tcaptcha_drag_button')

  

except Exception as e:

  

print 'get button failed: ', e

  

  

  

sleep(1)

  

# 开始拖动 perform()用来执行ActionChains中存储的行为

  

flag = 0

  

distance = 195

  

offset = 5

  

times = 0

  

while 1:

  

action = ActionChains(driver)

  

action.click_and_hold(button).perform()

  

action.reset_actions() # 清除之前的action

  

print distance

  

track = get_track(distance)

  

for in track:

  

action.move_by_offset(xoffset=i, yoffset=0).perform()

  

action.reset_actions()

  

sleep(0.5)

  

action.release().perform()

  

sleep(5)

  

  

  

# 判断某元素是否被加载到DOM树里,并不代表该元素一定可见

  

try:

  

alert = driver.find_element_by_class_name('tcaptcha-title').text

  

except Exception as e:

  

print 'get alert error: %s' % e

  

alert = ''

  

if alert:

  

print u'滑块位移需要调整: %s' % alert

  

distance -= offset

  

times += 1

  

sleep(5)

  

else:

  

print '滑块验证通过'

  

flag = 1

  

driver.switch_to.parent_frame()    # 验证成功后跳回最外层页面

  

break

  

  

  

sleep(2)

  

driver.quit()

  

print "finish~~"

  

return flag

  

  

  

if __name__ == '__main__':

  

main()

  

5.小结

其实上面的代码还可以进一步“优化”。例如,当尝试三次滑动后如果仍然没有“验证成功”,就应该主动跳回“登录”页面,重新输入账号密码登录,进入下一次验证过程,而不是无休止的进行“滑块验证”。除此之外,以上只是对“滑块验证”部分进行了分析和模拟,实际情况是,通过了“滑块验证”后,有可能账号或密码错误了,这时候是不是应该重新输入账号密码进入新一轮验证过程呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/40826.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【个人笔记】对linux中一切皆文件的理解与ls命令

目录 Linux中一切皆文件ls命令常用参数常用命令lscpu lspci Linux中一切皆文件 理解参考&#xff1a;为什么说&#xff1a;Linux中一切皆文件&#xff1f; ls命令 ls&#xff08;英文全拼&#xff1a; list directory contents&#xff09;命令用于显示指定工作目录下之内容…

javascript 导出表格的excel

一个php网站的表格,需要增加导出excel的功能, 因对web开发不甚了解,开始想着用php导出, 搜索一番发现比较复杂,而且我的表格里已经有数据了, 如果导出又要去库中获取一次,不是负担加倍, 可否把现有表格数据,直接导出来? 答案是肯定的,用js在前端导出 开源js组件…

Camtasia Studio 2023保存为mp4格式的视频的详细教程,Camtasia的视频导出功能

很多用户刚接触Camtasia Studio&#xff0c;不熟悉如何保存mp4格式的视频。在今天的文章中小编为大家带来了Camtasia Studio 2023保存为mp4格式的视频的详细教程介绍。 1、 打开Camtasia Studio。 Camtasia Studio- 2023 win&#xff1a; https://souurl.cn/1JFEsn Camtasia …

【C++学习记录】(二)--一个C++工程文件里有哪些东西?

写在前面 首先&#xff0c;我有一个完整的C工程文件&#xff0c;文件分别是包含Debug、include、Service和src。 1.了解文件结构: 首先&#xff0c;查看每个文件夹中的内容以了解文件的组织结构。Debug文件夹通常包含与调试相关的文件&#xff0c;include文件夹可能包含头文件…

数据库复习

select 查询 字段别名用 as (可以为中文) 例如 select distinct 关键字 去重复值 例如select distinct deptno from test where 条件过滤 and or 和 not运算符 and同时成立 or有一个成立就可以了 优先级and>or>not不符合&#xff08;!&#xff09; in 匹配多个值 selec…

个人号的微信API接口,微信机器人二次开发

前段时间应公司需求&#xff0c;要开发一套自定义的微信机器人&#xff0c;具体需求是可以自己批量添加好友、批量打标签等进行好友管理&#xff0c;社群管理需要自动聊天&#xff0c;自动回复&#xff0c;发朋友圈&#xff0c;转发语音&#xff0c;以及定时群发等&#xff0c;…

Redis简介(1)

⭐ 作者简介&#xff1a;码上言 ⭐ 代表教程&#xff1a;Spring Boot vue-element 开发个人博客项目实战教程 ⭐专栏内容&#xff1a;个人博客系统 ⭐我的文档网站&#xff1a;http://xyhwh-nav.cn/ 文章目录 Redis简介1、NoSQL1.1、什么是NoSQL&#xff1f;1.2、NoSQL 特点…

Python实现HBA混合蝙蝠智能算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝙蝠算法是2010年杨教授基于群体智能提出的启发式搜索算法&#xff0c;是一种搜索全局最优解的有效方法…

python实现接口压力测试

python实现接口压力测试 直接上代码&#xff1a; # -*- coding: utf-8 -*-import json import requests import logginglogging.basicConfig(levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s) logger logging.getLogger(__name__)restime …

ES系列--文档处理

一、文档冲突 当我们使用 index API 更新文档 &#xff0c;可以一次性读取原始文档&#xff0c;做我们的修改&#xff0c;然后重 新索引 整个文档 。 最近的索引请求将获胜&#xff1a;无论最后哪一个文档被索引&#xff0c;都将被唯一存 储在 Elasticsearch 中。如果其他人同时…

15 大模型训练 内存优化

先看GPU结构&#xff0c;我们常说显存的时候&#xff0c;说的一般就是Global memory 训练的过程中&#xff0c;我们为了反向传播过程&#xff0c;必须将中间的结果&#xff08;激活值&#xff09;存储下来。 在训练的过程中&#xff0c;那些会消耗内存呢&#xff1f; model we…

Centos 8 / TencentOS Server 3.1 安装 docker-ce

目录 前言安装 docker-ce设置Docker Hub 镜像缓存参考 前言 TencentOS Server 3.1(与 CentOS 8用户态完全兼容&#xff0c;配套基于社区5.4 LTS 内核深度优化的 tkernel4版本) 安装 docker-ce 先卸载老版本&#xff0c;没有老版本的跳过 yum remove docker \docker-client \d…

行为型模式 - 命令模式

概述 日常生活中&#xff0c;我们出去吃饭都会遇到下面的场景。 定义&#xff1a; 将一个请求封装为一个对象&#xff0c;使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通&#xff0c;这样方便将命令对象进行存储、传递、调用、增加与管理。 结构 …

MyBatis PostgreSQL实现数组类型的操作

我的GitHub&#xff1a;Powerveil GitHub 我的Gitee&#xff1a;Powercs12 (powercs12) - Gitee.com 皮卡丘每天学Java 最近在学习数据库PostgreSQL&#xff0c;遇到如何实现对数组类型的数据操作&#xff0c;试着自己尝试学习实现。 话不多说&#xff0c;直接撸代码。 建表…

云计算之OpenStack核心

云计算之OpenStack核心 一、OpenStack架构1.1 OpenStack概念架构1.2 OpenStack逻辑架构1.3 拓扑部署1.4 使用OpenStack CLI1.4.1 OpenStack 服务都有自己的 CLI 二、OpenStack核心服务2.1 认证服务Keystone2.1.1 基本功能2.1.2 基本概念2.1.3 举例说明&#xff1a;admin用户查看…

【从零开始学习CSS | 第三篇】选择器优先级

目录 前言&#xff1a; 常见选择器的优先级&#xff08;从高到低&#xff09; 选择器的权重&#xff1a; 总结&#xff1a; 前言&#xff1a; 在前几篇文章中我们介绍了大量的选择器&#xff0c;那么大量的选择器在使用的时候&#xff0c;一定是有一个优先级顺序的&#xff…

Haystack:建立端到端的NLP应用程序的工具箱

Haystack是一个端到端的自然语言处理&#xff08;NLP&#xff09;框架&#xff0c;可以使用语言模型、Transformer模型、向量搜索等功能来构建NLP应用程序。无论您想进行问题回答、答案生成、语义文档搜索&#xff0c;还是构建能够进行复杂决策和查询解决的工具&#xff0c;都可…

MongoDB源码安装

文章目录 MongoDB源码安装&#xff1a;注&#xff1a;下载&#xff1a;解压&#xff1a;创建数据目录&#xff1a;创建软链接&#xff1a;创建变量脚本&#xff1a;执行脚本&#xff1a;启动mongodb:检查&#xff1a;连接mongodb&#xff1a; MongoDB源码安装&#xff1a; 注&…

ceph安装部署

Ceph 简介 存储基础 单机存储设备 单机存储的问题 分布式存储的类型 分布式存储&#xff08;软件定义的存储 SDS&#xff09; Ceph 架构 Ceph 核心组件 ​编辑 Pool中数据保存方式支持两种类型 OSD 存储后端 Ceph 数据的存储过程 Ceph 集群部署 基于 ceph-deploy …

Microsoft Outlook如何定时发送邮件

点击New Emai 选择Options→Delay Delivery→Do not deliver before→Close