Есть ли способ найти эту кнопку (если она есть) и нажать на нее? - PullRequest
1 голос
/ 19 марта 2020

Я пытаюсь последовательно нажимать на некоторые кнопки онлайн-игры. Может быть полезно взглянуть на игру . Вот часть основного html, относящаяся к кнопкам:

<div class="grid x5" id="grid">
    <div style="opacity: 1;"><span class="box" style="z-index:92"></span>1</div> #⬅Each of this lines are a button.
    <div style="opacity: 1;"><span class="box" style="z-index:92"></span>2</div>
    <div style="opacity: 1;"><span class="box" style="z-index:92"></span>3</div>
    <div style="opacity: 1;"><span class="box" style="z-index:92"></span>4</div>
</div>

Лучшее, что у меня получилось:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import presence_of_element_located

browser = webdriver.Firefox()
browser.get('http://zzzscore.com/1to50/en/')

wave_info = [[25, "//div[contains(@style, 'opacity')]"], [50, "//div[contains(@style, 'opacity')]"]]


n = 1
for wave in wave_info:
    grid_elements = browser.find_elements_by_xpath(wave[1])
    while n <= wave[0]:
        for item in grid_elements:
            if int(item.text) == n:
                item.click()
                n += 1

Приведенный выше код работает хорошо, но после нажатия на 27 кнопках (а иногда и на 28 кнопках) отображается следующая трассировка:

Traceback (most recent call last):
  File "C:\Users\Parsa\Desktop\python\2.py", line 18, in <module>
    if int(item.text) == n:
ValueError: invalid literal for int() with base 10: ''

Существует соответствующий вопрос , но я не очень хорошо его понял. Ваш быстрый ответ в этом отношении будет высоко оценен.

Ответы [ 2 ]

1 голос
/ 20 марта 2020

Есть более элегантный способ сделать это:

x = range(1, 51)
for number in x:
    element = browser.find_element_by_xpath('//div[text()= "' + str(number) + '"]')
    element.click()
0 голосов
/ 19 марта 2020

Ошибка

Ошибка, которую вы получаете, выдается на финальной стадии игры, когда коробки / кнопки начинают исчезать. Как только поле исчезнет, ​​вызов item.text вернет None, который не может быть преобразован в int.

Решение

import time
from selenium.common.exceptions import StaleElementReferenceException

wave_info = [[25, "//div[contains(@style, 'opacity')]"], [50, "//div[contains(@class, 'second')]"]]
time.sleep(2)
n = 1
for wave in wave_info:
    time.sleep(.1)
    grid_elements = browser.find_elements_by_xpath(wave[1])
    while n <= wave[0]:
        for item in grid_elements:
            try:
                if int(item.text) == n:
                    item.click()
                    n += 1
            except ValueError:
                continue
            except StaleElementReferenceException:
                break

Объяснение

Время импортировано и time.sleep(2) вызывается для полной загрузки времени страницы, прежде чем мы начнем с ним взаимодействовать. time.sleep(.1) в начале l oop позволяет элементам сетки полностью загружаться между первой и второй волной (переход между первыми 25 и последними 25 элементами). Все элементы, которые мы должны щелкнуть в игре, имеют один и тот же стиль, и это используется в приведенном выше решении. Все элементы найдены и сохранены в одну строку grid_elements = browser.find_elements_by_xpath(wave[1]). Затем элементы проходят по петле и щелкаются, когда их значение совпадает с номером, который мы ищем. Это сводит к минимуму количество кликов, которые мы фактически должны сделать, до 50 по сравнению с кликом по каждому элементу и в надежде, что вы нажали правильный. Это сравнение выполняется в попытке, за исключением случая, когда выдается ValueError, что означает, что item.text вернул None. Другое, кроме завершающего внутреннего для l oop после того, как 50-й элемент был нажат. Поскольку страница изменяется и элементы перестают существовать после нажатия на 50-й элемент, при попытке щелкнуть один из этих элементов выдается StaleElementReferenceException. Когда выдается ошибка, мы знаем, что игра окончена, потому что страница изменилась, что означает, что мы можем разбить внутреннюю часть на l oop. Два внешних цикла автоматически завершатся, потому что n будет равен 51, а весь массив wave_info будет закольцован. Если выдается какая-либо ошибка, код не будет остановлен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...