Python Selenium browser.find_element_by_class_name有时返回错误?

2024-09-27 07:29:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python新手,正在经历“自动化无聊的东西”——阿尔·斯维加特

我写了一个脚本,在“https://gabrielecirulli.github.io/2048”玩“2048”瓷砖游戏。在几次移动之后,平铺游戏将“最大输出”,并弹出一个“游戏结束!”,我还不知道如何读取它-因此,我实现了逻辑,在每4次移动后读取分数,确定分数是否停止增加,如果是,游戏结束

我发现我读分数的语句返回了一个错误有时。我不明白为什么它要么有效,要么无效。为什么它有时会返回错误

我把它放在一个try/except块中,所以如果我得到一个错误,我就把它加起来。有时是一些,有时是大约一半的时间

如果有任何帮助或建议,我将不胜感激

谢谢

output...
Evolutions: 40   oldScore1308    newScore: 1736
Evolutions: 41   oldScore1736    newScore: 1736
GAME OVER!
Good Game.

Final Score:
Evolutions: 41   OldScore1736    NewScore: 1736   Errors:23
Pausing before program closes.  Hit enter to continue.

代码:

#! python


import webbrowser
from selenium import webdriver
from selenium.webdriver.common.keys import Keys  # import Keys to send special keys
from selenium.common.exceptions import NoSuchElementException
import time


def opensite():
    # open browser
    global browser  # stop chrome window from closing by itself.
    browser = webdriver.Chrome()
    browser.get("https://gabrielecirulli.github.io/2048")

    return browser


def botKeys():
    # function to send arrow keys to browser :up, right, down, left.
    w = 0.025  # time to wait between plays
    try:
        element = browser.find_element_by_tag_name("body")

        gameOn = True
        counter = 0
        oldScore = 0
        error = 0

        while gameOn == True:

            counter += 1

            # Send keys to move pieces
            time.sleep(w)
            element.send_keys(Keys.UP)

            time.sleep(w)
            element.send_keys(Keys.RIGHT)

            time.sleep(w)
            element.send_keys(Keys.DOWN)

            time.sleep(w)
            element.send_keys(Keys.LEFT)

            # check the score.  Keep track of it to determine if GAME OVER!
            try:
                newScore = browser.find_element_by_class_name(
                    "score-container"
                )  # get the object with the score.
                newScore = int(
                    newScore.text
                )  # read the text of the object, which is the score in a string.  Convert it to an integer.

                print(
                    f"Evolutions: {counter}   oldScore{oldScore}    newScore: {newScore}"
                )
                if oldScore != newScore:
                    oldScore = newScore
                else:  # old and new are the same, game over
                    print(f"GAME OVER!\nGood Game.")
                    print(f"\nFinal Score:")
                    print(
                        f"Evolutions: {counter}   OldScore{oldScore}    NewScore: {newScore}   Errors:{error}"
                    )
                    gameOn = False

            except ValueError:
                error += 1  # count value errors, but that's all.

    except NoSuchElementException:
        print("Could not find element")

    input("Pausing before program closes.  Hit enter to continue.")


def main():

    # TODO  open the site
    driver = opensite()
    # TODO  send keystrokes
    botKeys()
    driver.close()


if __name__ == "__main__":
    main()

Tags: thetofromimportbrowsersend游戏time
2条回答

看起来不错!以下是我的解决方案:

'''
2048
2048 is a simple game where you combine tiles by sliding them up, down, 
left, or right with the arrow keys. You can actually get a fairly high score 
by repeatedly sliding in an up, right, down, and left pattern over and over 
again. Write a program that will open the game at https://gabrielecirulli 
.github.io/2048/ and keep sending up, right, down, and left keystrokes to 
automatically play the game.
'''

from selenium import webdriver
import random
import time
import os
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import ElementNotInteractableException

os.makedirs('2048', exist_ok=True)
bestScoreCurrent, check, attempts = 0, False, 0
driver = webdriver.Firefox()
# driver.maximize_window()
driver.get('https://gabrielecirulli.github.io/2048/')


def saveScreenshot(screenshot, filename, best, timeLoc):
    filename = f'2048\{best}_{filename}_{timeLoc}.png'
    with open(filename, 'wb') as elemFile:
        elemFile.write(screenshot)


def tryRetryButton():
    gameScreenshot = driver.find_element_by_css_selector(
        '.game-container').screenshot_as_png
    try:
        driver.find_element_by_css_selector('.retry-button').click()
        return True, gameScreenshot
    except ElementNotInteractableException:
        return False, gameScreenshot


def botLogic():
    for key in [Keys.UP, Keys.RIGHT, Keys.DOWN, Keys.LEFT]:
        bestScorePossible = int(driver.find_element_by_css_selector(
            ".best-container").text)
        time.sleep((random.randint(5, 10) / 20))
        userElem = driver.find_element_by_xpath('/html/body')
        userElem.send_keys(key)
    return bestScorePossible


while True:

    bestScorePossible = botLogic()
    bestScoreScreenshot = driver.find_element_by_css_selector(
        '.best-container').screenshot_as_png
    check, gameScreenshot = tryRetryButton()

    if check and bestScorePossible > bestScoreCurrent:
        attempts += 1
        print(
            f'New best score {bestScorePossible}! Total attempts {attempts}')
        bestScoreCurrent = bestScorePossible
        timeLoc = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
        saveScreenshot(bestScoreScreenshot, 'bestScore', bestScoreCurrent, timeLoc)
        saveScreenshot(gameScreenshot, 'bestGameWindow', bestScoreCurrent, timeLoc)

如果显示错误

except ValueError as ex:
    error += 1
    print(ex)

然后你就知道问题出在哪里了

invalid literal for int() with base 10: '3060\n+20'

问题是,有时它会显示结果3060,并将点添加到结果+20

当您在\n上拆分它并获取第一个元素时,它会正常工作

newScore = int(
    newScore.text.split('\n')[0]
)

要识别Game Over您需要

game_over = driver.find_element_by_class_name("game-over")  # 

但是,当没有类game-over时,它会产生错误,因此我将使用find_elements(在单词find_elements的末尾使用s)来获取空列表,而不是生成错误

顺便说一句:我改变了一些名字,因为PEP 8 Style Guide for Python Code


from selenium import webdriver
from selenium.webdriver.common.keys import Keys  # import Keys to send special keys
from selenium.common.exceptions import NoSuchElementException
import time


def opensite():
    driver = webdriver.Chrome()
    driver.get("https://gabrielecirulli.github.io/2048")
    return driver


def bot_keys(driver):
    '''Function to send arrow keys to browser :up, right, down, left.'''

    wait = 0.025  # time to wait between plays

    try:
        element = driver.find_element_by_tag_name("body")

        game_on = True
        counter = 0
        old_score = 0
        new_score = 0
        error = 0

        while game_on:

            counter += 1

            # Send keys to move pieces
            time.sleep(wait)
            element.send_keys(Keys.UP)

            time.sleep(wait)
            element.send_keys(Keys.RIGHT)

            time.sleep(wait)
            element.send_keys(Keys.DOWN)

            time.sleep(wait)
            element.send_keys(Keys.LEFT)

            # check the score.  Keep track of it to determine if GAME OVER!
            try:

                new_score = driver.find_element_by_class_name("score-container")  # get the object with the score.

                new_score = int(new_score.text.split('\n')[0])  # read the text of the object, which is the score in a string.  Convert it to an integer.

                print(f"Evolutions: {counter:5} | Old Score: {old_score:5} | New Score: {new_score:5}")

                old_score = new_score

                game_over = driver.find_elements_by_class_name("game-over")  # get the object with the score.
                #print('game_over:', len(game_over))

                if game_over:
                    print("\nGAME OVER!\n")
                    print("Final Score:")
                    print(f"Evolutions: {counter:5} | New Score: {new_score:5} | Errors: {error}")
                    game_on = False

            except ValueError as ex:
                print('ex:', ex)
                error += 1  # count value errors, but that's all.

    except NoSuchElementException:
        print("Could not find element")

    input("\nPausing before program closes.  Hit enter to continue.")


def main():
    driver = opensite()
    bot_keys(driver)
    driver.close()


if __name__ == "__main__":
    main()

也许下一步是使用Gym(或类似的东西)来使用Reinforcement LearningMachine LearningArtificial Intelligence

相关问题 更多 >

    热门问题