Код Python работает локально, но не на сервере (бот Discord с селеном) - PullRequest
0 голосов
/ 04 ноября 2019

Мой код принимает пользовательский ввод и использует его для поиска элемента на веб-странице. он очищает HTML-код веб-страницы, чтобы получить элементы, появившиеся в результате:

driver = webdriver.Chrome()
driver.get(urlItem)
#this last line is the one that's not working on heroku
item_list = driver.find_elements_by_class_name('price-history-link')

это HTML-код:

<ul class="no-padding small-block-grid-3 large-block-grid-5 text-center word-wrap-break-word">
<li>
<a href="/item/7399/"><img src="/assets/imgs/items/7399.gif" alt="A Grey Faerie Doll" title="A Grey Faerie Doll" class="item-result-image"></a><br><a href="/item/7399/">A Grey Faerie Doll</a>
<br><span class="text-small"><a href="/item/7399/price-history/" class="price-history-link" title="October 31, 2019">2,400,000 NP</a></span>
</li>
</ul>

Когда я запускаю код локальнобот работает отлично. Когда я запускаю точно такой же код с моего хостинг-сайта (heroku), он не возвращает никаких элементов. Я подумал, что это может быть проблема с загрузкой, поэтому я добавил:

WebDriverWait(driver, 10).until(ec.visibility_of_element_located((By.CLASS_NAME, "price-history-link")))

, когда этот код на месте, он возвращает исключение (только при запуске на хостинг-сайте, он отлично работает при запуске намой компьютер)

повысить TimeoutException (message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Сообщение:

да, исключение заканчивается там, на самом деле это не такПокажите мне сообщение.

Я действительно не понимаю, почему это не сработает на heroku ... любая помощь очень ценится!

Редактировать: Добавить в ловушку для NoSuchElementException, но он не поймалчто-нибудь

1 Ответ

0 голосов
/ 04 ноября 2019

Вы видели это правильно. WebDriverWait() в сочетании с expected_conditions() всегда будет возвращать TimeoutException при сбое.

Подробное обсуждение можно найти в Случайных тестах Selenium E2e Fail из-затайм-ауты на DevOps Azure, но работают локально и с удаленным Selenium (BrowserStack Automate)


Этот сценарий использования

Поскольку вы используете Стратегия локатора CLASS_NAME as price-history-link возможно, это CLASS_NAME связано также с некоторыми скрытыми элементами. Следовательно, когда вы используете find_elements_by_class_name(), элементы идентифицируются, когда visibility_of_element_located() приводит к TimeoutException.


Решение

Для имитации find_elements_by_class_name() вместе с WebDriverWait() ив сочетании с expected_conditions() вам нужно вызвать WebDriverWait для visibility_of_all_elements_located(), и вы можете использовать любое из следующих решений:

  • Использование CSS_SELECTOR:

    item_list = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "a.price-history-link[href$='/price-history/'][title*='20']")))
    
  • Использование XPATH:

    item_list = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//a[@class='price-history-link' and contains(@href, '/price-history/')][contains(., 'NP')]")))
    
  • Примечание : необходимо добавить следующие операции импорта:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
...