『python爬虫』selenium实战-comicai绘画ai账密签到(保姆级分布注释)

慈云数据 2024-03-13 技术支持 65 0

目录

    • 实现效果
    • 实现思路
      • 等待指定元素出现
      • 等待指定元素出现并点击(请确保元素可以点击)
      • 无头浏览器节省资源
      • 设置窗口大小
      • 用户名和密码登录填表
      • 登录进去后出现广告弹窗的处理
      • 进行签到(如何处理可变的xpath)
      • 收尾工作关闭服务
      • 实现代码
      • 总结

        实现思路

        import time
        from Selenium import webdriver
        from selenium.webdriver.chrome.options import Options
        from selenium.webdriver.common.by import By
        from selenium.webdriver.support.ui import WebDriverWait
        from selenium.webdriver.support import expected_conditions as EC
        from selenium.common.exceptions import TimeoutException
        import sys
        

        等待指定元素出现

        def wait_for_element(driver, locator, timeout=30):
            """
            #等待元素出现,超时就退出
            :param driver:  浏览器对象
            :param locator: 选择节点(注意这里默认采用 By.XPATH的方式寻找)
            :param timeout: 最长等待时间
            :return:节点或者是None
            """
            try:
                element = WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.XPATH, locator)))
                print("找到元素:", locator,element.text)
                return element
            except TimeoutException:
                print("未找到元素或超时",locator)
                return None
        

        等待指定元素出现并点击(请确保元素可以点击)

        def wait_click_button(driver, locator, timeout=30):
            """
            #等待元素出现并点击元素
            :param driver:  浏览器对象
            :param locator: 选择节点(注意这里默认采用 By.XPATH的方式寻找)
            :param timeout: 最长等待时间
            :return:True 等待并点击节点成功~
            """
            result=wait_for_element(driver, locator, timeout=timeout)
            if result!=None:
                element_to_click = driver.find_element(By.XPATH, locator)
                element_to_click.click()
                return True
            else:
                return False
        

        无头浏览器节省资源

        第一次运行建议你注释掉下面两行代码,观看整个流程,方便你理解,后面为了节约操作消耗的资源,多线程的时候可以用无头浏览器.(简单说就是不生成界面,但是执行浏览器操作)

        chrome_options.add_argument('--headless')  # 启用无头模式
        chrome_options.add_argument('--disable-gpu')  # 禁用 GPU 加速
        
        chrome_options = Options()# 创建 ChromeOptions 对象
        chrome_options.add_argument('--headless')  # 启用无头模式
        chrome_options.add_argument('--disable-gpu')  # 禁用 GPU 加速
        chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3")  # 修改 User-Agent 头部信息为 Chrome 浏览器的 User-Agent
        # 启动 Chrome 浏览器
        driver = webdriver.Chrome(options=chrome_options)
        # 打开登录页面
        driver.get('https://comicai.ai/signin')
        

        设置窗口大小

        这个步骤一般来说不是必要的,主要是因为个别奇葩网页可能会因为大小自适应导致xpath变化.

        # # 获取当前窗口大小
        # width = driver.execute_script("return document.body.clientWidth")
        # height = driver.execute_script("return window.innerHeight")
        # print("当前窗口大小为:{}x{}".format(width, height))
        driver.set_window_size(800,600)#不设置固定大小,可能会导致xpath变化
        

        用户名和密码登录填表

        your_username="xxxxxxxxxxxx@qq.com"
        your_password="xxxxxxxxxxxxx"
        username_input_locator='//*[@id="app"]/div[1]/div[3]/div/div/input[1]'
        password_input_locator='//*[@id="app"]/div[1]/div[3]/div/div/input[2]'
        wait_for_element(driver, username_input_locator) #等待加载 输入框后再输入
        username_input = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[3]/div/div/input[1]')
        password_input = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[3]/div/div/input[2]')
        username_input.send_keys(your_username)#在输入框输入用户名
        password_input.send_keys(your_password)#在输入框输入密码
        login_button_locator= '//*[@id="app"]/div[1]/div[3]/div/div/div[5]/button'
        wait_for_element(driver, login_button_locator) #等待加载 输入框后再输入
        login_button = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[3]/div/div/div[5]/button')
        login_button.click()#点击登录按钮
        

        登录进去后出现广告弹窗的处理

        有些时候我们用xpath能找到元素但是点击不了,就是因为这种弹窗阻挡了,所以要处理好每一步的判断.

        #等待并点击关掉弹窗
        tanchuang_locator='//*[@id="app"]/div[2]/div/div/footer/button[2]/span/span'
        wait_click_button(driver,tanchuang_locator)
        numbers_element_locator='//*[@id="app"]/div[1]/nav/div/div[1]/button/span'
        wait_for_element(driver,numbers_element_locator)#等待宝石数量出现
        numbers_element = driver.find_element(By.XPATH, numbers_element_locator)
        numbers_text_content = numbers_element.text
        print("签到前宝石数量:", numbers_text_content)
        

        进行签到(如何处理可变的xpath)

        • 关键在于怎么拿到这里的领取奖励按钮的xpath,这个是可变化的xpath.

          在XPath中,使用通配符 * 或 contains() 函数可以帮助我们灵活匹配元素,特别是当元素的属性值不是固定的情况下。下面我会分别介绍如何使用通配符 * 和 contains() 函数。

          • 使用通配符 *: 通配符 * 可以匹配任意类型的元素,无论元素的标签名称是什么。例如,如果我们想要匹配某个节点下的所有子节点,可以使用通配符 *。以下是一个示例:

            假设我们要匹配 元素下的所有直接子元素:

            //div/*
            

            这个 XPath 表达式将匹配所有直接位于

            元素下的子元素,无论子元素的标签名称是什么。
            • 使用 contains() 函数: contains() 函数可以在属性值中搜索指定的字符串。它的用法是 contains(attribute, value),其中 attribute 是要搜索的属性,value 是要匹配的值。下面是一个示例:

              假设我们要匹配一个 class 属性包含特定关键词的元素:

              //*[contains(@class, 'keyword')]
              
              领取奖励按钮xpath如下,其中[@id="el-id-3448-9"]里的数字会一直变化,每次都不一样,比如一个变式是:
              //*[@id="el-id-3448-9"]/div/div[1]/div[2]/button
              

              这里我们用了 * 和contain进行匹配!

              get_score_locator = '//*[starts-with(@id, "el-id-") and contains(@id, "-")]/div/div[1]/div[2]/button'
              
              # 等待并点击宝石进入签到界面
              qd_numbers_locator = '//*[@id="app"]/div[1]/nav/div/div[1]/button'
              wait_click_button(driver,qd_numbers_locator)
              # 等待是否已经签到过
              # //*[@id="el-id-3448-9"]/div/div[1]/div[2]/button/span/img  没有签到过的xpath
              ok_get_score_locator = '//*[starts-with(@id, "el-id-") and contains(@id, "-")]/div/div[1]/div[2]/div[2]/img'
              result=wait_click_button(driver, ok_get_score_locator, timeout=5)
              if result==False:
                  print("今日还没有签到过~")
                  # 等待点击获取奖励
                  get_score_locator = '//*[starts-with(@id, "el-id-") and contains(@id, "-")]/div/div[1]/div[2]/button'
                  wait_click_button(driver, get_score_locator)
                  # # 等待点击确认奖励
                  accept_locator = '/html/body/div[8]/div/div/footer/button/span/span'
                  wait_click_button(driver, accept_locator)
                  time.sleep(5)#等待数据加载
                  numbers_element_locator = '//*[@id="app"]/div[1]/nav/div/div[1]/button/span'
                  wait_for_element(driver, numbers_element_locator)  # 等待宝石数量出现
                  numbers_element = driver.find_element(By.XPATH, numbers_element_locator)
                  numbers_text_content = numbers_element.text
                  print("签到后宝石数量:", numbers_text_content)
              else:
                  print("今日已经签到过了~")
                  numbers_element_locator='//*[@id="app"]/div[1]/nav/div/div[1]/button/span'
                  wait_for_element(driver,numbers_element_locator)#等待宝石数量出现
                  numbers_element = driver.find_element(By.XPATH, numbers_element_locator)
                  numbers_text_content = numbers_element.text
                  print("目前宝石数量:", numbers_text_content)
              

              收尾工作关闭服务

              # # 关闭当前窗口但不退出会话(浏览器保留)
              # driver.close()
              # # 关闭浏览器,彻底退出
              driver.quit()
              print("签到完成!")
              

              总结

              大家喜欢的话,给个👍,点个关注!给大家分享更多计算机专业学生的求学之路!

              版权声明:

              发现你走远了@mzh原创作品,转载必须标注原文链接

              Copyright 2023 mzh

              Crated:2023-3-1

              欢迎关注 『python爬虫』 专栏,持续更新中

              欢迎关注 『python爬虫』 专栏,持续更新中

              『未完待续』

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon