Невозможно найти элемент после выбора параметра из раскрывающегося списка с использованием Python, Selenium и ActionChains

Для кого-то это будет легко, и это превратилось в длинный пост из-за того, что я думаю, что это простой вопрос.

Я очищаю сайт поставщика и пишу в csv, чтобы мне не приходилось вручную пролистывать страницы и страницы продуктов. Чтобы получить список продуктов, я запускаю поиск без переменных и получаю лот. Однако, если я попытаюсь ограничить свой поиск товарами в наличии, используя раскрывающийся список, мой код вылетает.

Поскольку это сторонний сайт, я не могу изменить html. Вот кусок html с сайта (переформатирован, так как скопировано очень некрасиво):

<tbody id="adv_search_box">
    <tr>
        <td class="data-name">Search in category:</td>
        <td class="data-input" colspan="2">
        <select name="posted_data[categoryid]" class="adv-search-select">
            <option value="">&nbsp;</option>
            <option value="257">Hot New Arrivals</option>
            <option value="252">In-Stock</option>

...

        <button class="button main-button" type="submit" title="Search">
            <span class="button-right"><span class="button-left">Search</span></span>
        </button>
        </td>
    </tr>
</tbody>

Когда я использую следующее, чтобы нажать кнопку поиска, я получаю все, что есть у поставщика, независимо от статуса. Так что это работает просто отлично:

searchButton = driver.find_element_by_xpath('//*[@id="adv_search_box"]/tr[8]/td[2]/button/span/span')
actions = ActionChains(driver)
actions.move_to_element(searchButton)
actions.click(searchButton)
actions.perform()

Затем я добавляю код для выбора опции «В наличии» перед кодом нажатия кнопки:

#Select in-stock on search page
InStockSelection = driver.find_element_by_xpath('//*[@id="adv_search_box"]/tr[1]/td[2]/select/option[3]')
actions = ActionChains(driver)
actions.move_to_element(InStockSelection)
actions.click(InStockSelection)
actions.perform()

#Click button
searchButton = driver.find_element_by_xpath('//*[@id="adv_search_box"]/tr[8]/td[2]/button/span/span')
actions = ActionChains(driver)
actions.move_to_element(searchButton)
actions.click(searchButton)
actions.perform()

Я получаю следующую ошибку:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="adv_search_box"]/tr[8]/td[2]/button/span/span"}

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

Спасибо всем за вашу помощь.

Редактировать 1: Мне кажется, что простое решение xpath не сработает. Я думаю, что в псевдо-кодировании программа сосредоточена на раскрывающейся таблице и не может видеть остальную часть html. Если бы я мог переориентироваться на страницу в целом, это должно было бы сработать.

Решение. Программирование для меня похоже на волшебство. Часто вам нужно следить за тем, на что вы не смотрите. В данном случае не было ничего плохого в коде для выбора кнопки. Проблема заключалась в том, что код для выбора раскрывающегося списка работал неправильно, а щелчок в конце менял фокус страницы.

Решение состояло в том, чтобы изменить способ расположения опции и избежать цепочки действий.

driver.find_element_by_xpath("//select[@name='posted_data[categoryid]']/option[text()='In-Stock']").click()

Помощь была найдена в этой статье: Selenium - Python - значение параметра раскрывающегося меню < /а>.

Спасибо, MikeJRamsey56, за то, что убедили меня отказаться от цепочки действий, и спасибо dejavu_cmd_delt за то, что нашли время ответить.


person NickV    schedule 11.11.2016    source источник


Ответы (1)


я бы предложил использовать ниже xpath, так как он свободен от проблем с индексацией, предполагая, что во всех tr есть только одна кнопка.

searchButton = driver.find_element_by_xpath('//*[@id="adv_search_box"]//button[@title="Search"]//span[@class="button-left"])
person Falloutcoder    schedule 11.11.2016
comment
Нет, не сработало. Даже когда я добавил недостающую закрывающую одинарную кавычку. ;-) - person NickV; 12.11.2016