#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. Кстати, я вообще не получил баллов за этот ответ 🙂