爬虫日常-selenium登录12306,绕过验证

news/2024/7/19 12:01:56 标签: 爬虫, python, selenium

文章目录

  • 前言
  • 代码设计

前言

hello兄弟们,这里是无聊的网友。愉快的周末过去了,欢迎回到学习频道。书接上文,我们说到了再用selenium登录12306时遇到了滑块验证的问题。当前的网站几乎每家都会在登录模块添加一个认证,来规避各种爬虫,而我们则不断的去想办法绕过这些验证模块。目前一些简单的验证如图片拼接,汉字识别的都可以借助如图鉴,超级鹰提供的功能解决。而主流的流行应用的验证绕过则需要非常复杂的步骤。我们就有点自知之明,先能够做到简单的绕过就好。
在这里插入图片描述就拿12306为例,目前还只是最简单的滑块验证,还好不是类似哔哩哔哩的极验类的滑块验证,所以我们趁着它简单先拿它开刀​

在这里插入图片描述我们可以看到在输入账号密码后,页面就会跳出滑块认证,依旧是先分析再动手

按照正常思路,先点击到滑块认证,然后鼠标点击滑块,拖动到最边上。我们首先右键检查滑块认真,看看验证模块有没有存在iframe中

在这里插入图片描述检查完发现div并没有被包裹在iframe中,就存在页面源码中,我们就可以直接通过find_element定位到此处并进行点击动作

代码设计

先放上上一期的代码

python">from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By


# 定义登录方法
def login(user, pwd):
    login_choice = web.find_element(By.XPATH, '//*[@id="toolbar_Div"]/div[2]/div[2]/ul/li[1]')
    # 点击账号密码登录方式
    login_choice.click()
    web.find_element(By.XPATH, '//*[@id="J-userName"]').send_keys(user)  # 向账号框传入账号信息
    web.find_element(By.XPATH, '//*[@id="J-password"]').send_keys(pwd)  # 向密码框传入密码
    # 定位到登录按钮并点击
    web.find_element(By.XPATH, '//*[@id="J-login"]').click()


if __name__ == '__main__':
    opt = Options()
    opt.add_experimental_option('excludeSwitches', ['enable-automation'])  # 去除浏览器顶部显示受自动化程序控制
    opt.add_experimental_option('detach', True)  # 规避程序运行完自动退出浏览器
    web = Chrome(options=opt)
    web.get('https://kyfw.12306.cn/otn/resources/login.html')
    user = ''  # 此处输入账号
    pwd = ''   # 此处输入密码
    login(user, pwd)

按照设计思路,我们应当在登录方法处添加模拟点击滑块的代码
到了这一步,学完基础的同学就应该想到要借助ActionChains,ActionChains模拟鼠标操作的常用方法。使用click()方法可以进行鼠标的单击操作,此外还提供了有关双击、右击、悬停、鼠标拖动等功能的方法,这里不一一阐述了。

设计代码如下

python">    span = web.find_element(By.XPATH, '//*[@id="nc_2_n1z"]')  # 首先定位到滑块
    action = ActionChains(web)
    action.click_and_hold(span).move_by_offset(300, 0).perform() # click_and_hold代表点击并保持点击动作。move_by_offset(x, y),其中x代表水平移动距离,y代表垂直移动距离
    

在这里插入图片描述在这里插入图片描述可以看到整个滑块的水平长度为340​而需要移动的小滑块为38.4的宽度。所以大致需要移动的距离为340-38.4。如果move_by_offset的x参数过大可以导致程序报错超出滑框宽度,在循环中若移动的参数过小可能到达不了最右侧或者超时认证。因此此处我直接一次性滑动300.
编写完运行检测效果
在这里插入图片描述可以看到第一次的运行失败,报错信息为滑块验证element没有定位到。那么为什么会出现这样的错误呢。是因为我们的速度太快了
在这里插入图片描述
因为我们的点击请求过快,导致页面的滑块验证模块还没有跳转出来就直接进行点击请求了,解决的方法也很简单,可以直接使用time.sleep进行强制睡眠。但我们不建议这样使用,最好是采用显示等待的方法对其处理。

我们都知道显式等待也称为智能等待,针对指定元素定位指定等待时间,在指定时间范围内进行元素查找,找到元素则直接返回,如果在超时还没有找到元素,则抛出异常,显示等待是 selenium 当中比较灵活的一种等待方式,他的实现原理其实是通过 while 循环不停的尝试需要进行的操作。那么知道了原理后就直接上手用它。

在定位到滑块验证并点击前设置显示等待。需要下面两个包配合使用

python">from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
     # 此处还去掉了点击滑块验证的操作
    # 设置显示等待直到滑块的span标签被定位到
    WebDriverWait(web, 0.5, 0.05).until(EC.presence_of_element_located((By.ID, 'nc_1_n1z')))
    span = web.find_element(By.ID, 'nc_1_n1z')  # 首先定位到滑块

WebDriverWait()中的参数主要为等待时间和刷新时间,经过我的测试0.5为我的程序最少的需要的等待时间,再少程序就要报错,同样0.05为最少刷新时间
这个是和个人电脑与网速有关的,报错的同学可以尝试修改
编写后在再次测试
在这里插入图片描述
ok,最后运行成功。成功绕过12396的滑块认证。老规矩运行成功放源码

python">from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


# 定义登录方法
def login(user, pwd):
    login_choice = web.find_element(By.XPATH, '//*[@id="toolbar_Div"]/div[2]/div[2]/ul/li[1]')
    # 点击账号密码登录方式
    login_choice.click()

    username = web.find_element(By.XPATH, '//*[@id="J-userName"]')  # 向账号框传入账号信息
    passwd = web.find_element(By.XPATH, '//*[@id="J-password"]')  # 向密码框传入密码
    username.click()
    username.send_keys(user)
    passwd.click()
    passwd.send_keys(pwd)
    # 定位到登录按钮并点击
    web.find_element(By.XPATH, '//*[@id="J-login"]').click()
    # 设置显示等待直到滑块的span标签被定位到
    WebDriverWait(web, 0.5, 0.05).until(EC.presence_of_element_located((By.ID, 'nc_1_n1z')))
    span = web.find_element(By.ID, 'nc_1_n1z')
    action = ActionChains(web)
    action.click_and_hold(span).move_by_offset(300, 0).perform() # click_and_hold代表点击并保持点击动作。move_by_offset(x, y),其中x代表水平移动距离,y代表垂直移动距离


if __name__ == '__main__':
    opt = Options()
    opt.add_experimental_option('excludeSwitches', ['enable-automation'])  # 去除浏览器顶部显示受自动化程序控制
    opt.add_experimental_option('detach', True)  # 规避程序运行完自动退出浏览器
    web = Chrome(options=opt)
    web.get('https://kyfw.12306.cn/otn/resources/login.html')
    # 解除浏览器特征识别selenium
    script = 'Object.defineProperty(navigator,"webdriver", {get: () => false,});'
    web.execute_script(script)
    user = ''  # 此处输入账号
    pwd = ''   # 此处输入密码
    login(user, pwd)

今天先告一段落,明天在和大家接着研究如何在登录后选购票。麻烦点个赞哦兄弟们。
在这里插入图片描述


http://www.niftyadmin.cn/n/233644.html

相关文章

详解自动化测试之 Selenium 与 Junit

文章目录1. 什么是自动化2. 自动化测试的分类3. selenium(web 自动化测试工具)4. 一个简单的自动化例子5. selenium 常用方法5.1 查找页面元素 findElement ()5.2 元素的定位 By 类5.3 xpath 路径语言6. 常见的元素操作6.1 输入文本 sendKeys6.2 点击 cl…

【C++】哈希的应用——bitset(STL)位图

哈希的应用——bitset(STL)位图 文章目录哈希的应用——bitset(STL)位图一、bitset的介绍1.位图的引入2.位图的概念3.位图的应用二、bitset的使用1.bitset的构造方式2.bitset成员函数的使用3.bitset运算符的使用三、bitset位图的模拟实现1.位图的基本框架2.成员函数2.1.构造函数…

Netty内存管理--ChunkPage

写在前面 必要性 网络通信中,接收端通常需要多层解码,最终在应用层解码后才能得到业务层可处理的message。Netty需要缓存接收到的网络数据和待发送的网络数据,缓存发送/解码完成后就可以释放。其中对缓存的获取和释放频次高; 通…

新品首发丨计讯物联智慧灯杆TG473-A6-5“滴水不进”,严苛环境下稳定运行无压力

近年来,智慧灯杆产业快速发展,已广泛应用于智慧城市、智慧交通、智慧园区、智慧停车等细分场景,提质增效、节本降耗的作用突显。值得注意的是,不同的场景有着不同的环境条件,如高低温、潮湿、沙尘等,对智慧…

MSI: 基于多元同步索引的SSVEP频率识别算法

MSI: 基于多元同步索引的SSVEP频率识别算法1.算法背景2.算法原理3.Python代码实现1.算法背景 脑机接口(Brain-Computer Interface, BCI)因其在神经工程与神经科学中的广泛应用价值而备受研究者们的关注。BCI系统可以在人类或动物被试与外部设备之间提供…

【排序算法 下】带你手撕常见排序 (冒泡,快排,归并排序) (动图详解)

欢迎来到 Claffic 的博客 💞💞💞 “只要有花可开,就不允许生命与黯淡为伍。” 前言: 承接上篇,继续带大家手撕常见排序算法,这次讲剩余的两类:交换排序和归并排序。 注:…

智能网卡-提升网络性能的新选择

一、智能网口介绍 智能网卡(Smart NIC)是一种专用于网络数据处理的高性能网卡,采用了定制芯片、高速网络接口和强大的软件支持,可以为数据中心和企业网络提供更快、更安全、更可靠的网络连接和数据传输服务。 智能网卡的出现受到…

linux环境查看cpu是否开启睿频

linux环境下如何查看cpu开启睿频 方法一 [root@~rootbird]# cat /sys/devices/system/cpu/cpufreq/boost 1 表示开启 [root@~rootbird]# cat /sys/devices/system/cpu/cpufreq/boost 0 表示未开启 方法二 cpupower 查看,cpupower 工具旨在提供给定计算机上支持的所有 CPU 电…