Скрипт обнаружил ошибку при разборе имен и адресов из заполненных результатов - PullRequest
0 голосов
/ 04 марта 2020

Я создал скрипт для анализа имен и адресов различных результатов (56 in this case) с веб-сайта. Адреса становятся видимыми, когда щелчок инициируется для каждого результата. Однако, когда я запускаю следующий скрипт, я получаю два результата, но затем я сталкиваюсь с этой element not interactable ошибкой, указывающей на эту строку item.click().

ссылка на веб-сайт

Чтобы заполнить результат, необходимо заполнить поле поиска этим M203DB и нажать кнопку поиска.

Я пробовал с:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys

def get_content(link):
    driver.get(link)
    WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input.inv_addressSuggestion"))).send_keys('M203DB',Keys.RETURN)

    for item in WebDriverWait(driver,20).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "[id^='listItemContainer_']"))):
        item.click()
        name = item.find_element_by_css_selector("span.detailContactVal").text
        address = item.find_element_by_css_selector("span.detailAddr").text
        print(name,address)

if __name__ == '__main__':
    URL = 'https://www.sjp.co.uk/site-services/find-your-adviser?async=1'
    with webdriver.Chrome() as driver:
        get_content(URL)

Ошибка, выдаваемая сценарием:

raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable

Как я могу вычеркнуть имена и адреса из всех результатов?

1 Ответ

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

Эта ошибка указывает на то, что элементы, которые вы пытаетесь щелкнуть, не видны в области просмотра.

Проверьте это Q / A " Как устранить ElementNotInteractableException: Элемент не отображается в веб-драйвере Selenium?"для получения дополнительной информации и решений.

Существует множество проблем с этим параметром c Утилизация (https://www.sjp.co.uk/site-services/find-your-adviser).

  1. Имеет адаптивный макет, который отображает по-разному для мобильных устройств
  2. Имеет кнопку «Загрузить еще» для мобильного просмотра
  3. Имеет сгруппированные разделы, которые необходимо расширить
  4. Имеет несколько просмотров и это приложение отображает дубликаты идентификаторов. Если вы попытаетесь получить длину запроса document.querySelectorAll("[id^='listItemContainer_']").length, вы получите 112 вместо 56, то есть итоговые результаты. Вы должны будете ограничить результаты первым контейнером, используя этот селектор #mCSB_1_container [id^='listItemContainer_'].

Вот рабочий скрипт python, который использует все это. Пожалуйста, прочитайте встроенные комментарии:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import re


def get_content(link):
    driver.get(link)
    WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input.inv_addressSuggestion"))).send_keys('M203DB',Keys.RETURN)

    try:
        # If there is a "Load more" button, click it
        load_more = WebDriverWait(driver,5).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".inv_loadMoreBtn")))
        load_more.click()
    except:
        pass

    # Select from #mCSB_1_container element and not everything to avoid dublicates
    for item in WebDriverWait(driver,20).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#mCSB_1_container [id^='listItemContainer_']"))):
        print("#%s\n" % (item.get_attribute("id")))

        # Get the parent element and its class
        parent = item.find_element_by_xpath('..')
        parent_class = parent.get_attribute("class")

        # If parent element has "inv_childData" then it's grouped and it needs to be expanded
        if re.search(r"inv_childData", parent_class):
            # If the parent expandable element is not expanded (has not the class "inv_childCollapsed")
            if not re.search(r"inv_childCollapsed", parent_class):
                actions = ActionChains(driver)
                # Move to element
                actions.move_to_element(parent).perform()
                # And click it to expand the child items
                parent.click()

        # Use Javascript scrollIntoView() to scroll the view to the item to avoid ElementNotInteractableException
        driver.execute_script("arguments[0].scrollIntoView()", item)

        # Click the item
        item.click()

        name = item.find_element_by_css_selector("span.detailContactVal").text
        address = item.find_element_by_css_selector("span.detailAddr").text

        print("Name: '%s'\nAddress:\n%s\n" % (name, address))

if __name__ == '__main__':
    URL = 'https://www.sjp.co.uk/site-services/find-your-adviser?async=1'

    chrome_options = Options()

    # Make headless
    # chrome_options.add_argument("--headless")

    # Make window size to 1920x1080 to avoid responsive mobile view
    # chrome_options.add_argument("--window-size=1920,1080 ")

    with webdriver.Chrome(options=chrome_options) as driver:
        get_content(URL)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...