草庐IT

python+selenium 自动拖拽滑块

壹如年少遲夏歸 2023-10-22 原文

selenium 自动拖拽滑块以顺丰单号查询为例

  • 网址: https://www.sf-express.com/we/ow/chn/sc/waybill/waybill-detail/SFxxxx 后面是订单编号

    • 先看 滑块
    • 这种滑块解决方案很多,本文是参照极验滑动验证码 ;获取滑动验证码完整背景和滑动时展现的背景,二者进行像素点比较,取最左侧不相同的像素点的位置left,即是我们要滑动的位置相对于图像最左侧的位置,届时再减去滑块按钮所在的x轴位置x_pos,就可以得到我们要滑动的长度。
    • 此方案的难点在于如何获取完整的背景图(当然方法也不止一种)
  • 这里我们很容易就找到了缺块的背景图

    • 完整的背景图改如何获取呢,这时候笔者误打误撞发现了一个有意思的链接
    • 这个 * 难道是一个分隔符 抱着试试的态度 访问了一下 * 前面的链接 果然
    • 有了完整图片剩下的不就好弄了
      • 首先,把两张图片保存到本地(当然这里也可以参考极验 使用selenium带的截图功能,因为这里笔者没有找到限定的元素,没法使用js得到完整的背景,只能出此下策了)
      • 使用selenium获取元素 这里要注意 等待 iframe 加载
      • 关于拖动的时候注意 像素点;笔者这里就被坑了;你保存下来的图片大小和实际是有出入的,这里需要自己去计算
  • 最后附上代码(仅供参考)

# Author: Lovy
# File : 04_滑块
# Time : 2022-08-20 16:25

import requests
from selenium import webdriver
from time import sleep
from PIL import Image
from selenium.webdriver import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

headers = {
    'Referer': r'https://t.captcha.qq.com/cap_union_new_show?aid=2037219860&protocol=https&accver=1&showtype=popup&ua=TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV09XNjQpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS85OS4wLjQ4NDQuNTEgU2FmYXJpLzUzNy4zNg%3D%3D&noheader=1&fb=1&aged=0&enableAged=0&enableDarkMode=0&grayscale=1&clientype=2&userLanguage=zh-cn&sess=s0UU0F8r06RUZ9PBVu2eNVsgV_g9hGQrupqfh3xEkQPybQOkMmGtit-awx8nE2_VV1zQAtQHDxcaNsr1zRC1y8j3p9vdCMegNL6x43id3TLhDtZXtbOy8yCBnmpmibs6cSucWri9CjhUpxhw82wPr21EHtsg3QAhSunNBe4T3zeRtWhMDmDG5KEKXgPArssRGIUAHtVvvpznlJcmL3mthvyagLJaoYtsnIQRZbRjm5ATqRv5vGe-Pav3NWPRuAJkBSM8sj0hr-niA*&fwidth=0&sid=6966721938633166848&wxLang=&tcScale=1&uid=&cap_cd=&rnd=414726&prehandleLoadTime=113&createIframeStart=1660995944597&global=0&subsid=2',
    'Host': 't.captcha.qq.com',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
}


class MyDriver():
    def __init__(self):
        self.x_pos = 0
        self.option = webdriver.ChromeOptions()
        self.driver = webdriver.Chrome(options=self.option)
        self.driver.maximize_window()
        self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
            "source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})""",
        })

    def get_url(self, url):
        self.driver.get(url)
        sleep(5)  # 如何显式等待 iframe加载

    def switch_frame(self):
        frame_element = self.driver.find_element('id', 'tcaptcha_iframe')
        WebDriverWait(self.driver, 10, 0.5).until(
            EC.frame_to_be_available_and_switch_to_it(frame_element))

        element_locator = ('id', 'slideBg')
        WebDriverWait(self.driver, 10, 0.5).until(
            EC.visibility_of_element_located(element_locator))

    def get_gap(self, image1, image2):
        left = 60
        for i in range(left, image1.size[0]):
            for j in range(image1.size[1]):
                if not self.is_pixel_equal(image1, image2, i, j):
                    left = i
                    return left
        return left

    def is_pixel_equal(self, image1, image2, x, y):
        pixel1 = image1.load()[x, y]
        pixel2 = image2.load()[x, y]
        threshold = 60
        if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
                pixel1[2] - pixel2[2]) < threshold:
            return True
        else:
            return False

    def img_cv(self):
        img = self.driver.find_element('id', 'slideBg')
        src = img.get_attribute('src')
        img1 = requests.get(url=src, headers=headers)
        with open("temp_img1.png", 'wb') as f:
            f.write(img1.content)
        img2 = requests.get(url=src[:417], headers=headers)
        with open("temp_img2.png", 'wb') as f:
            f.write(img2.content)
        img1_ = Image.open('temp_img1.png')
        img2_ = Image.open('temp_img2.png')
        self.x_pos = self.get_gap(img1_, img2_)

    def move(self, url):
        self.get_url(url)
        self.switch_frame()
        self.img_cv()
        ele_huakuai = self.driver.find_element('id', 'tcaptcha_drag_button')
        ActionChains(self.driver, duration=1000).drag_and_drop_by_offset(ele_huakuai, self.x_pos // 2 - 35, 0).perform()
        sleep(0.5)
        self.driver.find_element('id', 'tcaptcha_drag_button').click()


if __name__ == '__main__':
    url = "https://www.sf-express.com/we/ow/chn/sc/waybill/waybill-detail/SFxxxx" # 单号填自己的
    mydriver = MyDriver()
    mydriver.move(url)

有关python+selenium 自动拖拽滑块的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  4. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  5. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  6. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  7. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  8. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  9. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  10. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

随机推荐