【网站密码管理不用愁】进阶篇 • 如何利用cookie绕开登录验证码强上网站


————————————————————————————————

一、项目回顾

在上一篇文章中《【网站密码管理不用愁】基础篇 • 利用selenium构建网站密码管理和自动登录神器》

我分享了如何通过python+selenium来构建网站密码管理和自动登录神器。

用来解决我们在平时工作生活中遇到的各种网站太多、账号密码难管理的问题。
在这里插入图片描述
我们只需要打开运行窗口,输入我们设定的关键词,就能一键启动网站并自动输入账号和密码,实在方便得不要不要的。
在这里插入图片描述
以后麻麻再也不用担心我记不住账号、找不到密码啦!

同时,也有小伙伴在评论区留言道
在这里插入图片描述
对吼!

现在我们有很多网站登录不仅是要输入账号密码,还要输入验证码。

而且还是多种款式的验证码各不相同。
在这里插入图片描述

——

二、问题分析

作为稀里糊涂自学python三个月,编程知识渊博(qian bo)的我,看到这个问题自然是一脸懵逼。

所以恣意地在网上搜索,发现这个小儿科的问题早已被各路网友大神分分钟钟解决掉过。

大神们的骚操作极多,什么验证码识别训练模型、图像识别计算滑块验证码的距离等等。
在这里插入图片描述
溜了溜了,反正我是学不来。
在这里插入图片描述
从我们个人的实际需求出发,我们是希望建立一种能够快速登录网站的方式,从而方便我们的工作生活,解决时间,提高效率。

我们的核心目的是实现网站的快速登录,而非正面硬刚验证码环节,所以我们可以采用绕过验证码的方式登录网站。
在这里插入图片描述
所以经过我细致探索,发现利用selenium本身具有的add_cookie方法就能够成功解决需要验证码才能登录的问题。

那么首先让我们来搞清楚通过cookie免密免验证码登录的原理是什么。

简单来说,cookie就是网站存储在我们浏览器上的一小段数据,里面有我们个人用户的信息。

如果我们首次登录网站后,浏览器记住了我们登录后的信息(也就是cookie),当下一次请求时会把该 cookie 发送给网站,之后网站服务器发现客户端发送过来的 cookie 后,会检查是哪个客户端发送过来的请求,然后对比服务器上的记录,最后得到了之前的状态信息。

这也是我们在登录网站时候勾选【下次自动登录】后,以后不用输入账号和密码自动登录网站的原因。

再通俗点讲,cookie记住了我们登录网站后的状态,我们下次登录网站的时候浏览器会把这些cookie发送给网站,从而直接进入到登录后的状态,也就不需要输入账号密码,更不用什么验证码之类的呢。

——

三、利用cookie绕过验证码环节

百度在输入账号和密码之后,会出现图形验证码,要求拖动滑块使图片角度为正,因为每次需要拖动的距离不一样,所以不能像以前那样控制鼠标事件一拖到底(以前百度的验证码是直接拖到底那种)。
在这里插入图片描述
本次我们以实战登录百度为例,看看如何通过cookie绕过百度的图形滑块验证码,从而强上百度。
在这里插入图片描述

【01】获取cookie

首先我们明确下获取cookie的流程

  1. 通过python+selenium进行到自动输入账号密码后的流程(为了练习)
  2. 手动滑动图形验证码并实现成功登录
  3. 利用get_cookie()方法获取我们登录后的cookie

简单三步走,完美!

我们先来编写第一步的代码,再来练习一下如何定位目标元素、如何控制键盘事件。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver= webdriver.Chrome()
driver.get('https://www.baidu.com/')

driver.maximize_window()     # 浏览器最大化

driver.find_element_by_css_selector('#u1 .lb').click()  # 点击登录
time.sleep(2)          # 需要加载一段时间,否则找不到页面元素
driver.find_element_by_css_selector('#TANGRAM__PSP_10__footerULoginBtn').click()                # 切换到使用账号密码登录
time.sleep(1)          # 等页面加载一段时间

driver.find_element_by_id('TANGRAM__PSP_10__userName').send_keys('******')    # 输入自己的账号
driver.find_element_by_id('TANGRAM__PSP_10__password').send_keys('******')    # 输入自己的密码
driver.find_element_by_id('TANGRAM__PSP_10__password').send_keys(Keys.ENTER)    # 回车确定登录

time.sleep(20)   # 等待较长时间,确保成功登录(因为需要获得登录后的cookie)

cookies = driver.get_cookies()  # 获取cookie
print(cookie)                   # 打印cookie

其中对部分代码进行重点说明

  • 我们导入了time库,在适当位置进行强制等待,确保页面元素都加载出来,尤其在最后我们进行手动拖动滑块进行验证的环节,一定要留出充足的时间等待进入登录成功后的页面再获取其cookie

然后第二步我们运行程序,selenium帮我们自动登录网站并输入账号密码,进入到验证码环节,这时候我们手动拖动验证码进行登录。

最后就让我们静静等待程序获取cookie。

最后的cookie是这样子的在这里插入图片描述
这一大团密密麻麻的是什么玩意?

我们仔细看一下,其实就是有多个字典组成的列表,每个字典中又有多个键值对。

【02】优化cookie

首先我们要搞明白为什么要对获取到的cookie,因为上面我们得到那一串cookie的列表是无法直接通过add_cookie()方法添加进去的。

会出现两个问题:

  1. add_cookie()方法中只能传入字典,所以我们需要先将cookie列表中的每一个字典单独提出来。
  2. 计算将单个字典提出来传入到方法add_cookies()中,在运行程序的时候会报错: selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid ‘expiry’ 。最简单有效的方法就是直接将“expiry”这对键值对删除掉。

既然明确了以上两个问题,那么我就知道该如何对获取的cookie进行优化

  1. 用for循环将单个的字典从列表中提取出来
  2. 同时检查字典中是否存在键名为“expiry”的键值对,如果有就删除掉
  3. 打印构造的字符串,方便等会直接复制粘贴
for i in cookies:
    if 'expiry' in i:               # 判断"expiry"是否在字典中
        del i['expiry']           # 如果就删除该键值对
    print('driver.add_cookie('+str(i)+')')     #打印构造的字符串,方便等会直接复制粘贴

其中注意因为 i 是一个一个的字典,所以需要强制转换为字符串类型。

最终我们就获取了一条条已经传入到add_cookie()方法里的字符串了。(为了防止信息泄露,我部分进行了马赛克处理)
在这里插入图片描述

【03】添加cookie

因为我们在上一步已经做好了cookie优化工作,所以我们直接对其进行复制粘贴到代码中即可。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver= webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '1454_21122_30211_20697_30347_30327_30283_28701'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': True, 'name': 'BDUSS', 'path': '/', 'secure': False, 'value': ''})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': ''})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'F'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'delPer', 'path': '/', 'secure': False, 'value': '0'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': ''})
driver.add_cookie({'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'BDORZ', 'path': '/', 'secure': False, 'value': 'B490B5EBF6F3CD402E515D22BCDA1598'})
driver.add_cookie({'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': ''})

driver.refresh()  #刷新页面

driver.maximize_window()

(为了防止信息泄露,我对部分关键信息代码进行了删除)

我们最后看下程序运行的结果
在这里插入图片描述
注意看右上角,你会发现直接由未登录状态“唰”地一下跳到了已登录账号的状态,中间没有输入账号、密码以及烦人的验证码过程。

是不是感觉超棒!

——

四、复盘总结

在最后列出完整的代码

一个是获取并优化cookie的代码

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver= webdriver.Chrome()
driver.get('https://www.baidu.com/')

driver.maximize_window()     # 浏览器最大化

driver.find_element_by_css_selector('#u1 .lb').click()  # 点击登录
time.sleep(2)          # 需要加载一段时间,否则找不到页面元素
driver.find_element_by_css_selector('#TANGRAM__PSP_10__footerULoginBtn').click()                # 切换到使用账号密码登录
time.sleep(1)          # 等页面加载一段时间

driver.find_element_by_id('TANGRAM__PSP_10__userName').send_keys('******')    # 输入自己的账号
driver.find_element_by_id('TANGRAM__PSP_10__password').send_keys('******')    # 输入自己的密码
driver.find_element_by_id('TANGRAM__PSP_10__password').send_keys(Keys.ENTER)    # 回车确定登录

time.sleep(20)   # 等待较长时间,确保成功登录(因为需要获得登录后的cookie)

cookies = driver.get_cookies()  # 获取cookie
print(cookie)                   # 打印cookie
print('\n')

for i in cookies:
    if 'expiry' in i:               # 判断"expiry"是否在字典中
        del i['expiry']           # 如果就删除该键值对
    print('driver.add_cookie('+str(i)+')')     #打印构造的字符串,方便等会直接复制粘贴

另一个是添加cookie登录网站的代码

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver= webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '1454_21122_30211_20697_30347_30327_30283_28701'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': True, 'name': 'BDUSS', 'path': '/', 'secure': False, 'value': ''})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': ''})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'F'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'delPer', 'path': '/', 'secure': False, 'value': '0'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': ''})
driver.add_cookie({'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'})
driver.add_cookie({'domain': 'baidu.com', 'httpOnly': False, 'name': 'BDORZ', 'path': '/', 'secure': False, 'value': 'B490B5EBF6F3CD402E515D22BCDA1598'})
driver.add_cookie({'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': ''})

driver.refresh()  #刷新页面

driver.maximize_window()

整个代码中需要注意的要点有:

  1. 需要手动进入登录后的界面,并确保程序获取的是登录后状态的cookie,所以时间一定要足够充足,我设定的是time.sleep(20)
  2. 通过get_cookie()获取的是多个字典的列表,我们需要用for循环单独提出来
  3. 如果字典中有“expiry”的键值对,需要删除否则会造成程序报错
  4. 为了方便直接复制粘贴,我们在打印的时候直接构造完整的字符串,其中每个字典需要强制转换为字符串类型

在这里插入图片描述

发布了35 篇原创文章 · 获赞 35 · 访问量 2765

猜你喜欢

转载自blog.csdn.net/nilvya/article/details/103674999