目标

  • 使用selenium实现自动登录
    img
  • 整理一下思路
    拿到账号密码输入框的id –> 填写账号 –> 填写密码 –> 出现滑块 –> 滑过滑块 –> 点击登录

过程

  • 拿到输入框id的过程就不再介绍了,需要注意的点就是’iframe’这个元素,例:
1
2
3
4
5
6
7
8
9
<iframe src="" frameborder="0" id="iframe_id">
<html>
...
<input type="text" id="user_name">
<input type="text" id="password">
<button id="login">登录</button>
...
</html>
</iframe>

在iframe标签中的数据是无法直接拿到,需要进行一次切换才能得到数据

1
2
3
4
5
6
7
8
# 切换到iframe中
driver.switch_to_frame("iframe_id")
# 清除账号框
driver.find_element_by_id("user_name").clear()
# 填写账号
driver.find_element_by_id("user_name").send_keys(username)
# 填写密码
driver.find_element_by_id("TPL_username_1").clear().send_keys(password)
  • 在填写密码的时候出现了滑块验证,先不要着急做滑块,暂时睡一会time.sleep(5),然后手动去拉滑块,惊喜来了
  • 可能是某宝的技术比较高端,不管你怎么拉都是会失败的,简直神奇,查了一下原因是因为使用了某种js方式检测到了当前页面是使用selenium打开的,所以认定为爬虫,不可能放你过去的

解决方法

  • 需要修改chromedriver文件中的内容

把’cdc_asdjflasutopfhvcZLmcfl’修改为相同字符数量的任意字符即可,要在root模式下执行,不然文件会毁损,记得备份。
详情参考:stackoverflow-selenium-with-chromedriver

  • 问题解决,开始自动滑块操作,正常可以去拿滑块的id进行操作,但是我想使用一个奇怪的方式
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
# 滑块验证
from selenium.webdriver.common.action_chains import ActionChains

# 滑块验证,假设拿不到滑块的id
def the_slider_validation(driver):
builder = ActionChains(driver)
# 拿到登录的button
l = driver.find_element_by_id("login")
# 清除之前的action
builder.reset_actions()
# 计算滑块移动的轨迹, 300为移动距离
track = move_mouse(300)
# 移动到登录button上35像素位置(就是滑块所在位置),根据登录button进行定位滑块
builder.move_to_element_with_offset(l, 0, -35)
# 点击左键,不释放
builder.click_and_hold()
time.sleep(0.2)
# 开始生成移动轨迹
for i in track:
builder.move_by_offset(xoffset=i, yoffset=0)
builder.reset_actions()
time.sleep(0.1)
# 释放左键,执行for中的操作
builder.release().perform()

# 鼠标移动
def move_mouse(distance):
remaining_dist = distance
moves = []
a = 0
# 加速度,速度越来越快...
while remaining_dist > 0:
span = random.randint(15, 20)
a += span
moves.append(a)
remaining_dist -= span
if sum(moves[:-1]) > 300:
print(sum(moves))
break
return moves
  • 验证通过,点击登录,或者是失败进行重试
1
driver.find_element_by_id("login").click()