ghy_20001004 2024-07-31 00:03 采纳率: 100%
浏览 17
已结题

selenium滑块验证

京东滑块验证码过不了
用selenium写的代码测试京东滑块验证,每次滑块都对不准,或对准了也无法模拟登录

from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import ddddocr
from PIL import Image
import requests
import base64
from io import BytesIO
from selenium.webdriver.common.action_chains import ActionChains
import random

chrome_options = Options()
# chrome_options.add_argument("--headless")
# chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)


wd = webdriver.Chrome(options=chrome_options)
wd.get('https://passport.jd.com/new/login.aspx?ReturnUrl=http%3A%2F%2Fsearch.jd.com%2FSearch%3Fkeyword%3D%25E6%25B8%25B8%25E6%2588%258F%25E4%25B8%25BB%25E6%259C%25BA%26enc%3Dutf-8%26spm%3Da.0.0%26pvid%3D5e08dc4a947348c9a76ee2d28f407fde&czLogin=1')
print(wd.title)
wd.maximize_window()
wd.find_element(By.ID, 'loginname').send_keys('17871951280')
wd.find_element(By.ID, 'nloginpwd').send_keys('your_password')
wd.find_element(By.XPATH,'//*[@id="formlogin"]/div[5]').click()
time.sleep(5)
#动作链设计

while wd.title == '京东-欢迎登录':
    bg_url = wd.find_element(By.XPATH, '//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[1]/img').get_attribute('src').split(',')[1]
    target_url = wd.find_element(By.XPATH, '//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[2]/img').get_attribute('src').split(',')[1]
    bg_url_bs = base64.b64decode(bg_url)
    target_url_bs = base64.b64decode(target_url)

    # 存储二进制数据
    bg = Image.open(BytesIO(bg_url_bs))
    target = Image.open(BytesIO(target_url_bs))
    bg.save('bg.png')
    target.save('target.png')

    # 滑块位置计算
    det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
    with open('bg.png', 'rb') as f:
        bg = f.read()
    with open('target.png', 'rb') as f:
        target = f.read()

    res = det.slide_match(target, bg, simple_target=True)
    print(res)

    # 模拟拖动,乘以窗口缩放比例
    ActionChains(wd).click_and_hold(wd.find_element(By.XPATH, '//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[2]/img')).perform()
    ActionChains(wd).move_by_offset((res['target'][0])/200*33, 0).perform()
    ActionChains(wd).move_by_offset((res['target'][0])/200*33, 0).perform()
    ActionChains(wd).move_by_offset((res['target'][0])/200*33, 0).perform()
    ActionChains(wd).move_by_offset((res['target'][0])/200*33, 0).perform()
    ActionChains(wd).release().perform()
    time.sleep(10)




  • 写回答

3条回答 默认 最新

  • 代码伐木匠 2024-07-31 11:54
    关注

    京东滑块验证码是用来防止自动化脚本的,使用传统的图像处理技术来解决可能会遇到各种挑战。你提供的脚本尝试使用图像处理和模拟操作来绕过验证码,但是可能会遇到以下问题:

    1. 滑块位置计算不准确:滑块验证码的实际滑动距离可能与计算出的距离有差异,特别是在使用不同的浏览器或分辨率时。

    2. 拖动操作不稳定:模拟拖动的操作需要精确控制,而且不同的浏览器可能对模拟操作的支持有所不同。

    3. 验证码防护机制:京东可能会使用动态的验证码机制、鼠标轨迹检测等,增加了绕过验证码的难度。

    提高脚本准确性的建议

    1. 优化滑块计算:确保滑块计算的精度高,考虑使用更先进的图像处理算法。如果 ddddocr 的结果不准确,可能需要对其进行调试或尝试其他库。

    2. 调整拖动模拟:确保模拟拖动的过程与实际操作一致。可以尝试增加拖动的精度,并适当加入随机性。

    3. 使用浏览器开发者工具:在浏览器开发者工具中观察验证码的实现细节,可能会帮助你更好地理解如何模拟操作。

    示例改进

    下面是一个经过优化的滑块验证码自动化脚本示例:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.action_chains import ActionChains
    from PIL import Image
    import requests
    import base64
    from io import BytesIO
    import time
    import ddddocr
    
    chrome_options = Options()
    # chrome_options.add_argument("--headless")  # 如果不需要浏览器界面,可以取消注释
    # chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    
    service = Service('path/to/chromedriver')  # 替换为你自己的ChromeDriver路径
    driver = webdriver.Chrome(service=service, options=chrome_options)
    
    driver.get('https://passport.jd.com/new/login.aspx?ReturnUrl=http%3A%2F%2Fsearch.jd.com%2FSearch%3Fkeyword%3D%25E6%25B8%25B8%25E6%2588%258F%25E4%25B8%25BB%25E6%259C%25BA%26enc%3Dutf-8%26spm%3Da.0.0%26pvid%3D5e08dc4a947348c9a76ee2d28f407fde&czLogin=1')
    
    # 等待页面加载
    time.sleep(3)
    
    # 输入用户名和密码
    driver.find_element(By.ID, 'loginname').send_keys('your_username')  # 替换为你的用户名
    driver.find_element(By.ID, 'nloginpwd').send_keys('your_password')  # 替换为你的密码
    driver.find_element(By.XPATH, '//*[@id="formlogin"]/div[5]').click()
    
    # 等待滑块验证码出现
    time.sleep(5)
    
    while True:
        try:
            # 获取背景图和目标图的base64数据
            bg_url = driver.find_element(By.XPATH, '//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[1]/img').get_attribute('src').split(',')[1]
            target_url = driver.find_element(By.XPATH, '//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[2]/img').get_attribute('src').split(',')[1]
            
            # 解码图片
            bg_img = Image.open(BytesIO(base64.b64decode(bg_url)))
            target_img = Image.open(BytesIO(base64.b64decode(target_url)))
    
            # 保存图片
            bg_img.save('bg.png')
            target_img.save('target.png')
    
            # 识别滑块位置
            ocr = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
            with open('bg.png', 'rb') as f:
                bg_data = f.read()
            with open('target.png', 'rb') as f:
                target_data = f.read()
            
            result = ocr.slide_match(target_data, bg_data, simple_target=True)
            print(result)
    
            if 'target' in result:
                target_x = result['target'][0] / 200 * 33
                action = ActionChains(driver)
                slider = driver.find_element(By.XPATH, '//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[2]/img')
                action.click_and_hold(slider).move_by_offset(target_x, 0).release().perform()
                break
            else:
                print("无法识别滑块位置,重新获取验证码")
                time.sleep(5)
        except Exception as e:
            print("发生错误:", e)
            time.sleep(5)
    
    driver.quit()
    

    说明

    1. **ddddocr**:用于滑块识别的OCR工具,如果这个工具效果不好,可以考虑替换为其他工具。
    2. 滑块位置:确保计算出的滑块位置准确。可以增加一些随机性来模拟人类的操作。
    3. 浏览器兼容性:确保WebDriver和浏览器版本匹配,避免由于版本不匹配导致的问题。

    请根据实际情况调整脚本,特别是元素的定位和滑块计算部分。如果脚本仍然无法工作,可以尝试使用更高级的图像识别技术或寻求专业的服务。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 8月10日
  • 已采纳回答 8月2日
  • 创建了问题 7月31日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?