Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Selenium-browser.find_element_by_class_name-有时返回错误?_Python_Selenium_Web Scraping - Fatal编程技术网

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

Python Selenium-browser.find_element_by_class_name-有时返回错误?,python,selenium,web-scraping,Python,Selenium,Web Scraping,我是Python新手,正在经历“自动化无聊的东西”——阿尔·斯维加特 我写了一个脚本,在“”玩“2048”平铺游戏。在几次移动之后,平铺游戏将“最大输出”,并弹出一个“游戏结束!”,我还不知道如何读取它-因此,我实现了逻辑,在每4次移动后读取分数,确定分数是否停止增加,如果是,游戏结束 我发现我读分数的语句有时会返回错误。我不明白为什么它要么有效,要么无效。为什么它有时会返回错误 我把它放在一个try/except块中,所以如果我得到一个错误,我就把它加起来。有时是一些,有时是大约一半的时间 如

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

我写了一个脚本,在“”玩“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.
代码:

如果显示错误

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 = driver.find_element_by_class_name("game-over")  # 
但是,当没有类
游戏结束时,它会引发错误,因此我会使用
查找元素
(单词
查找元素
的末尾有
s
)来获取空列表,而不是生成错误

顺便说一句:我改了一些名字,因为




也许下一步是使用(或类似的)强化学习(
机器学习
人工智能

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

'''
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)

当出现错误时,您应该显示HTML,以查看HTML中的实际内容-可能它确实没有此元素。或者您应该在移动后睡眠(甚至几毫秒),浏览器将有时间创建此元素。顺便说一句:您应该将
驱动程序
发送到
僵尸键(驱动程序)
然后您就不需要
全局浏览器了
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()
'''
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)