Selenium模拟腾讯新闻登录及滑块验证破解详解
本文详解如何使用Selenium模拟登录腾讯新闻网页版。针对部分账号触发的滑块验证,文章深入分析了TX滑块与极验的区别,重点讲解了Frame切换、蓝色滑块定位、移动轨迹构造及验证成功判断逻辑,并提供完整的Python重试代码实现。
Selenium模拟腾讯新闻登录背景
本次主要介绍利用Selenium模拟登录腾讯新闻网页端的过程。起初尝试直接模拟HTTP请求,但发现部分账号登录时会触发滑块验证,导致所需参数复杂且难以获取。幸运的是,腾讯的滑块验证机制相对独立,虽无极验那样成熟的破解方案可用,但通过逐步探索仍可找到模拟方法。下文将详细阐述模拟实现的具体步骤及遇到的问题。
登录入口与按钮定位
1. 确定登录入口
通过点击特定链接作为登录入口进入页面。
相关代码实现如下:
driver = webdriver.Chrome()
driver.get(url)
2. 点击“账号密码登录”按钮
Selenium支持对网页元素进行精确定位,此处通过ID属性定位“账号密码登录”按钮。需注意,受网络状况影响,登录入口页面加载可能较慢,因此在点击按钮前,必须添加等待逻辑,判断代表“账号密码登录”的HTML元素是否已完全加载。
“账号密码登录”按钮的ID属性截图如下:

部分代码实现:
element = WebDriverWait(driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID, "switcher_plogin"))
) # from selenium.webdriver.common.by import By
element.click()
账号密码输入与提交
3. 输入账号、密码并点击登录
此步骤操作相对简单,直接参考以下代码:
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”,从而强制跳转至滑块验证页面。

接下来的核心问题是模拟滑动过程。经多次测试发现,腾讯滑块的拖动距离存在一定范围,“缺口”通常位于右侧,这与极验滑块缺口位置随机不同。因此,在实现滑动前需判断每次的具体拖动距离。对于腾讯滑块,只需设置一个预估距离进行“模拟滑动”,若失败则通过增减移动距离重试,后续将详细说明。
2)为何无法直接找到“蓝色滑块”
点击“登录”并跳转至“安全验证”页面后,需模拟拖动截图中的“蓝色滑块”。首先需明确代表“蓝色滑块”的HTML元素,其ID属性截图如下:

由截图可知,ID为“tcaptcha_drag_button”的div标签代表“蓝色滑块”。起初尝试直接拖动该元素,但报错,部分截图如下:

报错原因显而易见:在当前获取的HTML元素集合中,找不到ID为“tcaptcha_drag_button”的div标签。这是为何?
3)切换Frame框架
出现上述问题的原因在于,跳转至“安全验证”页面时,系统嵌入了一个新的frame。可以理解为“登录页面”中嵌套了“验证页面”,而当前driver加载的HTML元素仅属于“登录页面”。要找到并拖动“蓝色滑块”,必须先切换到“验证页面”,这通过driver.switch_to方法实现:
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类,部分代码如下:
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(180, 0).perform() # 移动滑块
5)构造移动轨迹
为使拖动过程更“真实”,可构造滑动轨迹。此处参考了他人代码并进行了简单实现,实际上腾讯新闻的滑块验证对此要求并不严格:
def get_track(distance):
track = []
current = 0
mid = distance * 3 / 4
t = 0.2
v = 0
while current < distance:
if current < mid:
a = 2
else:
a = -3
v0 = v
v = v0 + a * t
move = v0 * t + 1 / 2 * a * t * 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循环。以上过程的完整代码如下:
# 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
t = 0.2
v = 0
while current < distance:
if current < mid:
a = 2
else:
a = -3
v0 = v
v = v0 + a * t
move = v0 * t + 1 / 2 * a * t * t
current += move
track.append(round(move))
return track
def main():
driver = webdriver.Chrome()
driver.set_window_position(900, 10)
driver.get(url)
# 检测id为"switcher_plogin"的元素是否加在DOM树中,如果出现了才能正常向下执行
element = WebDriverWait(driver, 5, 0.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, 5, 0.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 i 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. 小结
上述代码仍有进一步“优化”空间。例如,若尝试三次滑动后仍未“验证成功”,应主动跳回“登录”页面,重新输入账号密码登录,进入下一轮验证,而非无休止地进行“滑块验证”。此外,以上仅对“滑块验证”部分进行了分析和模拟,实际情况中,通过“滑块验证”后,仍可能出现账号或密码错误,此时是否应重新输入账号密码进入新一轮验证过程?
因此,以上代码仍有待继续完善,也欢迎读者对本文不足之处提出指正。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









