Я пытаюсь сканировать Product Hunt с помощью Selenium
В частности, я пытаюсь получить ссылку на источник для всех значков продуктов.
HTML:

Мой код для сканирования следующий:
driver = webdriver.Chrome("<Your driver's path>")
driver.get("https://www.producthunt.com/topics/seo-tools?order=most-upvoted")
time.sleep(4)
icons = driver.find_elements_by_css_selector("div.styles_thumbnail__d2DAK.styles_thumbnail__XBHZ_ img")
print(len(icons))
print(icons)
driver.close()
Проблема в том, что селен получает только 3 первых изображения, а не все доступные продукты.
Я попытался увеличить время сна, а также реализовал путь driver.wait вместе с EC.presence_of_all_elements_located, чтобы убедиться, что все значки загружаются правильно.






Поскольку другие значки отображаются при прокрутке внизу страницы, вы можете сделать это следующим образом.
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 import webdriver
driver = webdriver.Chrome()
driver.get("https://www.producthunt.com/topics/seo-tools?order=most-upvoted")
expected_number_of_icons = 20
icons = []
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
icons = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, "//div[contains(@data-test, 'post-item')]//div[@class='styles_thumbnail__d2DAK styles_thumbnail__XBHZ_']//img | //div[contains(@class, 'styles_link')]//span[@class='lazyload-wrapper']/img")))
icons = list(set(icons))
if len(icons) > expected_number_of_icons:
break
icons = icons[:expected_number_of_icons]
driver.close()
где вы решите остановиться, когда достигнете нужного количества значков. Очевидно, например, если вы достигли 210 значков и хотите только 200 значков, вы можете отказаться от последних 10 элементов списка.
Да потому что он найдет дубликаты. Я отредактировал ответ, чтобы удалить дубликаты. Попробуйте с этим, и если он пропустит некоторую проверку, есть ли у них другой путь, и добавьте другие пути к исходному с условием или
Хм, все еще он получает случайные изображения. Мне довольно странно, что это происходит только для изображений
Что вы имеете в виду под случайными изображениями? Разве он не возвращает только значки? Возвращает ли он другие изображения на странице?
Нет, я имею в виду, что он пропускает некоторые изображения. хочу первые 20
Осмотрите страницу и с помощью Control + F или Command + F поместите xpath в строку поиска и проверьте, находит ли путь все первые 20 элементов. Если он пропускает какой-либо значок, добавьте путь к пропущенным значкам в мой xpath или попробуйте найти однозначный xpath для всех значков.
попробуйте использовать visibility_of_all_elements_located вместо presence_of_all_elements_locatedи скажите, сработает ли это
Нет, чувак, он все еще возвращает случайные изображения. Странно то, что я могу сканировать элементы div, содержащие изображения, но не сами изображения.
М-да, я попробовал еще раз, и он пропускает какое-то изображение. Это действительно странно, так как xpath хорошо сканирует значки. Я также пытался сначала прокрутить, а затем получить бит изображений безрезультатно:/
Чтобы распечатать значение атрибута src, вы можете использовать одну из следующих стратегий локатора:
Использование css_selector:
print([my_elem.get_attribute("src") for my_elem in driver.find_elements_by_css_selector("span.lazyload-wrapper > img")])
Использование xpath:
print([my_elem.get_attribute("src") for my_elem in driver.find_elements_by_xpath("//span[@class='lazyload-wrapper']/img")])
В идеале вы должны вызвать WebDriverWait для visibility_of_all_elements_located(), и вы можете использовать одну из следующих стратегий локатора:
Использование CSS_SELECTOR:
driver.get('https://www.producthunt.com/topics/seo-tools?order=most-upvoted')
print([my_elem.get_attribute("src") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "span.lazyload-wrapper > img")))])
Использование XPATH в одной строке:
driver.get('https://www.producthunt.com/topics/seo-tools?order=most-upvoted')
print([my_elem.get_attribute("src") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//span[@class='lazyload-wrapper']/img")))])
Примечание. Вы должны добавить следующие импорты:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Тем не менее он возвращает только первые четыре значка, и я хочу получить все первые значки. Если я сканирую div, я получаю все 20, но не в случае с иконками.
@ z3y50n z3y50n Неважно :) Кажется, вы получили принятый ответ
Кажется, он получает больше значков, но пропускает некоторые, и я хочу просканировать, скажем, первые 20.