首页/编程/python/文章阅读

akile.io自动签到获取AK币脚本第二版

python 2024-12-23 32 0

前天写了个第一版,当时测试没有问题,第二天查看 crontab 日志也没发现问题,但是一登录账号后发现签到失败。

今天又仔细跑python测试了一下,最后定位到了问题,大概的问题出在js加载上面。

用人话说就是程序跑的太快,没有等待js加载完毕就开始了点击,而点击之后又没有进行判断是否点击成功。

今天完善一下,且这个套路代码理论上可以跑任何的网站自动化。

日志:

akile.io自动签到获取AK币脚本第二版

代码:

[login]
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
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, WebDriverException
import logging
import time
import os
import shutil

配置日志

logging.basicConfig( level=logging.INFO, format=‘%(asctime)s - %(levelname)s - %(message)s’ ) logger = logging.getLogger(name)

class AkileAutoLogin: def init(self, username, password): self.username = username self.password = password self.driver = None self.max_retries = 3 self.retry_delay = 5

def setup_driver(self):
    """设置并配置Chrome浏览器"""
    try:
        options = webdriver.ChromeOptions()
        options.binary_location = '/opt/google/chrome/chrome'

        # 基本配置
        options.add_argument('--no-sandbox')
        options.add_argument('--headless')
        options.add_argument('--enable-javascript') 
        options.add_argument('--start-maximized')
        options.add_argument('--disable-gpu')
        options.add_argument('--disable-dev-shm-usage')

        # 添加 User-Agent 伪装
        user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
        options.add_argument(f'user-agent={user_agent}')

        # 用户配置文件
        chrome_user_dir = os.path.expanduser('~/.config/google-chrome')
        if not os.path.exists(chrome_user_dir):
            os.makedirs(chrome_user_dir)
        options.add_argument(f"--user-data-dir={chrome_user_dir}")

        # ChromeDriver配置
        chromedriver_path = "/www/wwwroot/moren.com/google/chromedriver"
        service = Service(executable_path=chromedriver_path)

        # 重试机制
        for attempt in range(self.max_retries):
            try:
                self.driver = webdriver.Chrome(service=service, options=options)
                self.driver.set_page_load_timeout(30)
                logger.info("浏览器启动成功")
                break
            except WebDriverException as e:
                logger.error(f"第{attempt + 1}次浏览器启动失败: {str(e)}")
                if attempt == self.max_retries - 1:
                    raise
                time.sleep(self.retry_delay)

    except Exception as e:
        logger.error(f"浏览器启动失败: {str(e)}")
        raise


def wait_for_page_load(self, timeout=10):
    """等待页面完全加载"""
    try:
        WebDriverWait(self.driver, timeout).until(
            lambda driver: driver.execute_script("return document.readyState") == "complete"
        )
        logger.info("页面加载完成")
    except TimeoutException:
        logger.error("页面加载超时")
        raise

def wait_and_find_element(self, by, value, timeout=10, condition=EC.presence_of_element_located):
    """统一的元素等待和查找方法"""
    try:
        element = WebDriverWait(self.driver, timeout).until(
            condition((by, value))
        )
        return element
    except Exception as e:
        logger.error(f"等待元素失败 ({by}={value}): {str(e)}")
        raise

def login(self):
    """执行登录操作"""
    try:
        # 访问登录页面
        self.driver.get("https://akile.io/login")
        logger.info("成功访问登录页面")
        time.sleep(1)
        # 等待页面加载完成
        self.wait_for_page_load()
        time.sleep(1)
        # 调用qiandao方法,检查是否已登录并尝试签到
        # if self.qiandao():  # 如果签到成功,则提前返回
        #     logger.info("已成功执行签到,跳过登录")
        #     return True

        # 打印当前页面 HTML 源代码
        # logger.info("当前页面 HTML 源代码:")
        # logger.info(self.driver.page_source)

        # 等待页面表单加载完成
        try:
            self.wait_and_find_element(By.CLASS_NAME, "arco-form")
        except Exception as e:
            logger.error(f"等待表单加载失败: {str(e)}")
            return False

        # 查找并填写邮箱
        try:
            email_input = self.wait_and_find_element(
                By.CSS_SELECTOR,
                "input[type='text'][placeholder='Enter your email']"
            )
            email_input.clear()
            email_input.send_keys(self.username)
            logger.info("已输入邮箱")
            time.sleep(1)
        except Exception as e:
            logger.error(f"查找或填写邮箱失败: {str(e)}")
            return False

        # 查找并填写密码
        try:
            password_input = self.wait_and_find_element(
                By.CSS_SELECTOR,
                "input[type='password'][placeholder='Enter your password']"
            )
            password_input.clear()
            password_input.send_keys(self.password)
            logger.info("已输入密码")
            time.sleep(1)
        except Exception as e:
            logger.error(f"查找或填写密码失败: {str(e)}")
            return False

        # 点击登录按钮
        try:
            login_button = self.wait_and_find_element(
                By.CSS_SELECTOR,
                "button[type='submit']",
                condition=EC.element_to_be_clickable
            )
            time.sleep(1)
            # 等待页面加载完成
            self.wait_for_page_load()
            time.sleep(1)
            # self.driver.execute_script("arguments[0].click();", login_button)
            login_button.click()  # 点击按钮
            time.sleep(5)
            # 等待页面加载完成
            # logger.info(self.driver.page_source)
            # self.wait_for_page_load()
            if self.driver.current_url != "https://akile.io/login":
                # logger.info(self.driver.current_url)
                logger.info("登录成功,已跳转到首页!")
                # logger.info("登录成功")
                time.sleep(5)
                logger.info("进入签到模块...")
                self.qiandao()
                return True
            else:
                logger.error("登录失败,URL未改变")
                return False

            time.sleep(1)
        except Exception as e:
            logger.error(f"点击登录按钮失败: {str(e)}")
            return False


        return True

    except TimeoutException:
        logger.error("页面加载或元素等待超时")
        return False
    except Exception as e:
        logger.error(f"登录过程出错: {str(e)}")
        return False

def close(self):
    """关闭浏览器并删除所有缓存数据,包括cookies"""
    try:
        if self.driver:
            # 删除所有Cookies
            # self.driver.delete_all_cookies()
            # logger.info("已删除所有Cookies")
            # 关闭浏览器
            self.driver.quit()
            logger.info("浏览器已关闭")
    except Exception as e:
        logger.error(f"关闭浏览器时出错: {str(e)}")

    # Chrome清除所有数据
    chrome_user_data_path = os.path.expanduser("~/.config/google-chrome")
    # 检查路径是否存在
    if os.path.exists(chrome_user_data_path):
        # 删除整个目录及其内容
        shutil.rmtree(chrome_user_data_path)
        print(f"已删除 Chrome 用户数据目录: {chrome_user_data_path}")
    else:
        print(f"未找到 Chrome 用户数据目录: {chrome_user_data_path}")



def qiandao(self):
    time.sleep(3)
    logger.info("检测到用户已登录,跳转到控制台页面")
    self.driver.get("https://akile.io/console")
     # 打印当前页面 HTML 源代码
    # logger.info("当前页面 HTML 源代码:")
    # logger.info(self.driver.page_source)
    # logger.info("跳转后的页面HTML:")
    # logger.info(self.driver.page_source) 
    # 使用CSS选择器来定位"每日签到"按钮
    # 等待页面加载完成
    self.wait_for_page_load()
    if self.driver.current_url != "https://akile.io/console":
        logger.errpr("控制台进入失败,URL未变")
        return False
    else:
        time.sleep(2)
        # logger.info(self.driver.current_url)
        logger.info("控制台进入成功,URL已变")

        try:
            # logger.info("当前页面 HTML:")
            self.wait_for_page_load()  # 等待控制
            time.sleep(1)
            # logger.info(self.driver.page_source)
            # sign_in_button = WebDriverWait(self.driver, 10).until(
            #     EC.element_to_be_clickable(
            #         (By.XPATH, "//div[contains(@class, 'arco-statistic-value')]//button")
            #     )
            # )
            try:
                self.wait_for_page_load()
                # sign_in_button = WebDriverWait(self.driver, 10).until(
                #     EC.element_to_be_clickable(
                #         (By.XPATH, "//div[contains(@class, 'arco-statistic-value')]//button")
                #     )
                # )
                # logger.info("找到"每日签到"按钮,正在点击")
                # sign_in_button.click()  # 点击按钮
                # self.driver.execute_script("arguments[0].click();", sign_in_button)
                # 等待特定的异步加载的元素出现
                # sign_in_button = WebDriverWait(self.driver, 10).until(
                #     EC.presence_of_element_located((By.XPATH, "//div[contains(@class, 'arco-statistic-value')]//button"))
                # )
                # 然后再点击
                # sign_in_button.click()
                # self.driver.execute_script("arguments[0].click();", sign_in_button)
                time.sleep(5)
                sign_in_button = WebDriverWait(self.driver, 10).until(
                    EC.presence_of_element_located((By.XPATH, "//button[contains(@class, 'arco-btn') and text()='每日签到']"))
                )
                sign_in_button.click()
                time.sleep(1)
                logger.info("已经点击签到!")
                time.sleep(5)
                # self.driver.execute_script("arguments[0].click();", sign_in_button)
                # # 获取按钮的坐标
                # button_location = sign_in_button.location
                # x = button_location['x']
                # y = button_location['y']

                # # 获取按钮的大小,以确保点击在按钮区域内
                # button_size = sign_in_button.size
                # width = button_size['width']
                # height = button_size['height']

                # # 计算按钮中心点的坐标
                # center_x = x + (width / 2)
                # center_y = y + (height / 2)

                # # 使用ActionChains模拟点击
                # actions = ActionChains(self.driver)
                # actions.move_by_offset(center_x, center_y).click().perform()

                # # 重置ActionChains的鼠标位置
                # actions.reset_actions()
                # # logger.info(sign_in_button)

                # if sign_in_button:
                #     logger.info(f"找到的按钮文本: {sign_in_button.text}")
            except Exception as e:
                logger.error(f"查找按钮失败: {str(e)}")
            # logger.info("找到"每日签到"按钮,正在点击")
            # sign_in_button.click()  # 点击按钮
            # logger.info("找到"每日签到"按钮,正在点击")
            # sign_in_button.click()  # 点击按钮
            # 等待页面加载完成

            # logger.info(self.driver.page_source)

        except TimeoutException:
            logger.error("等待"每日签到"按钮超时或未能找到按钮")
            return True



    # sign_in_button = self.wait_and_find_element(
    #     By.CSS_SELECTOR,
    #     "button.arco-btn[style*='position: absolute; right: 20px; bottom: 20px;']"
    # )
    # 等待并检查按钮是否可点击
    # try:
    #     # 使用 WebDriverWait 来等待元素可点击
    #     WebDriverWait(self.driver, 10).until(
    #         EC.element_to_be_clickable(sign_in_button)
    #     )
    #     logger.info("按钮可点击")
    #     sign_in_button.click()  # 如果可点击,点击按钮
    # except TimeoutException:
    #     logger.error("按钮不可点击或超时")

    # sign_in_button.click()
    # self.driver.execute_script("arguments[0].click();", sign_in_button)
    # 点击按钮
    # try:
    #     sign_in_button.click()
    # except Exception as e:
    #     logger.error(f"点击Logout按钮时出错: {str(e)}")
    #     # 如果直接点击失败,可以尝试使用JavaScript执行点击
    #     self.driver.execute_script("arguments[0].click();", sign_in_button)
    # logger.info("已点击"每日签到"按钮")


    # 若没退出先退出.
    # Logout = self.wait_and_find_element(
    #     (By.CSS_SELECTOR, "span:contains('Logout')")
    # )
    # try:
    #     Logout.click()
    # except Exception as e:
    #     logger.error(f"点击退出按钮失败: {str(e)}")
    #     # 如果直接点击失败,可以尝试使用JavaScript执行点击
    #     self.driver.execute_script("arguments[0].click();", Logout)
    #     logger.info("退出按钮已点击")

def process_account(account): “”“处理单个账号”“” username = account[“username”] password = account[“password”] logger.info(f”开始处理账号:{username}“)

# 初始化自动登录类
auto_login = AkileAutoLogin(username,password)

try:
    auto_login.setup_driver()
    if auto_login.login():
        logger.info("自动登录签到流程完成!")
    else:
        logger.error("登录失败")
except Exception as e:
    logger.error(f"发生错误: {str(e)}")
finally:
    auto_login.close()

def main(): accounts = [ {“username”: “xsdsee@gmail.com”, “password”: “Lm643965..”}, {“username”: “aaxbb@qq.com”, “password”: “Lm643965..”}, {“username”: “xsdsee@foxmail.com”, “password”: “123@@@”}, {“username”: “feelym@88.com”, “password”: “123@@@”}, {“username”: “feelym@126.com”, “password”: “FDtG]UXHJe#PT03F”}, ]

for account in accounts:
    process_account(account)
    time.sleep(20)  # 设置一个小的间隔,避免过快登录多个账号

if name == “main”: main()

[/login]

正文结束

记一次akile.io平台的自动登录签到程序python3版本ufw防火墙阻止别人扫描并使用自己vps

评论区

还没有评论,来坐沙发吧。