Как сделать так, чтобы все результаты отображались

#python #selenium

Вопрос:

 import sys

from selenium import webdriver
from selenium.webdriver.common.by import By
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 import ActionChains
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import time



def main():
    driver = configuration()
    motcle = sys.argv[1]
    recherche(driver,motcle)

def configuration():
    """
    Permet de faire la configuration nécessaire pour faire le scrapping
    :return: driver
    """

    path = "/usr/lib/chromium-browser/chromedriver"
    driver = webdriver.Chrome(path)
    driver.get("https://www.youtube.com/")
    return driver
def recherche(driver,motcle):
    actionChain = ActionChains(driver)
    search = driver.find_element_by_id("search")
    search.send_keys(motcle)
    search.send_keys(Keys.RETURN)
    driver.implicitly_wait(20)
    content =  driver.find_elements(By.CSS_SELECTOR, 'div#contents ytd-item-section-renderer>div#contents a#thumbnail')
    driver.implicitly_wait(20)
    links = []
    for item in content:
        links = [item.get_attribute('href')]
    print(links)

    time.sleep(5)
if __name__ == '__main__':
    main()
 

Моя программа работает, но не полностью или не так, как ожидалось. Я хочу, чтобы были все ссылки, но появилось только 4. Я пытался использовать WebDriverWait, но он тоже не работает. Я тоже пытался заставить программу подождать, но безуспешно.

Ответ №1:

Проблема здесь в том, что driver.find_elements при определенном driver.implicitly_wait ожидании наличия по крайней мере 1 веб-элемента, соответствующего переданному локатору, а затем это происходит, он немедленно возвращает список веб-элементов, соответствующих этому локатору.
Он не ждет, пока все элементы совпадут с этим локатором.
Точно такая же проблема с ожидаемыми условиями EC.visibility_of_all_elements_located .
Что я могу вам посоветовать здесь, так это использовать ожидаемые условия для представления первого элемента, затем установить режим ожидания, чтобы загрузить все остальные элементы, а затем получить список элементов.
Таким образом, ваш код будет выглядеть следующим образом:

 import sys

from selenium import webdriver
from selenium.webdriver.common.by import By
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 import ActionChains
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import time



def main():
    driver = configuration()
    motcle = sys.argv[1]
    recherche(driver,motcle)

def configuration():
    """
    Permet de faire la configuration nécessaire pour faire le scrapping
    :return: driver
    """

    path = "/usr/lib/chromium-browser/chromedriver"
    driver = webdriver.Chrome(path)
    driver.implicitly_wait(20)
    driver.get("https://www.youtube.com/")
    return driver
def recherche(driver,motcle):
    actionChain = ActionChains(driver)
    search = driver.find_element_by_id("search")
    search.send_keys(motcle)
    search.send_keys(Keys.RETURN)
    wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'div#contents ytd-item-section-renderer>div#contents a#thumbnail')))
    time.sleep(5)
    content =  driver.find_elements(By.CSS_SELECTOR, 'div#contents ytd-item-section-renderer>div#contents a#thumbnail')
    links = []
    for item in content:
        links = [item.get_attribute('href')]
    print(links)

    time.sleep(5)
if __name__ == '__main__':
    main()
 

Кроме того, его driver.implicitly_wait вообще не рекомендуется использовать, и если вы все еще хотите его использовать, нет необходимости определять, нужно ли снова и снова. После определения он определяется для всего сеанса веб-драйвера.

Комментарии:

1. Да, прекрасно, большое спасибо.

2. Если да, пожалуйста, примите ответ. Кстати, это тоже даст вам 2 балла 🙂

Ответ №2:

Если вы повторите его напрямую и добавите explicit wait , он должен привлечь все элементы, которые вы ищете

 wait = WebDriverWait(driver, 20)

links = []

for item in wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR,'div#contents ytd-item-section-renderer>div#contents a#thumbnail'))):
    links.append(item.get_attribute('href'))
 

Вы можете избавиться от implicity_wait звонков

Я проверил это с помощью поискового слова «Python», и оно включило все 25 ссылок href в список

Комментарии:

1. Ты не прав! ожидаемое условие visibility_of_all_elements_located работает точно так же, как find_elements и с implicitly_wait : как только он находит хотя бы 1 элемент, соответствующий переданному локатору, он возвращает список пойманных элементов!

2. @Prophet Ну, для меня это сработало нормально, а его код-нет. Однако вы здесь гений, поэтому я надеюсь, что вы получите очки, которых так жаждете

3. Прости, я не хотел причинять тебе боль. Просто хотел научить вас кое-чему, чего вы, возможно, до сих пор не знаете. Кроме того, я очень далек от того, чтобы быть гением. Я вижу здесь много людей, гораздо более профессиональных и умных, чем я.

4. Кстати, я вообще не получил баллов за этот ответ 🙂