Selenium очищает те же заголовки, субтитры и ссылки с веб-страницы The Sun Football

Я столкнулся с проблемой при очистке заголовков новостей, субтитров и ссылок с веб-сайта The Sun Football с помощью Selenium. Несмотря на, казалось бы, правильную реализацию XPath для выбора нужных элементов (div[@class = "teaser__copy-container"] для контейнеров, span[@class = "teaser__headline teaser__kicker t-p-color"] для заголовков и h3[@class = "teaser__subdeck"] для субтитров), я последовательно извлекаю одни и те же данные для всех новостей.

Фрагмент кода

from selenium import webdriver
from selenium.webdriver.firefox.service import Service # Using Firefox service

import pandas as pd

# Website URL for news scraping
website = "https://www.thesun.co.uk/sport/football/"

# Path to the GeckoDriver executable
path = "/Users/dada/AutomationProjects/drivers/geckodriver.exe"

# Configure Firefox service with GeckoDriver path
service = Service(executable_path=path)

# Initialise Firefox WebDriver using the service
driver = webdriver.Firefox(service=service)

# Open the desired website
driver.get(website)

containers = driver.find_elements(by = "xpath", value='//div[@class = "teaser__copy-container"]')

titles = []
subtitles = []
links = []

for container in containers:
    title = container.find_element(by = "xpath", value='//div[@class = "teaser__copy-container"]/a/span[@class = "teaser__headline teaser__kicker t-p-color"]').get_attribute("data-original-text")
    subtitle = container.find_element(by = "xpath", value='//div[@class = "teaser__copy-container"]/a/h3[@class = "teaser__subdeck"]').get_attribute("data-original-text")
    link = container.find_element(by = "xpath", value='//div[@class = "teaser__copy-container"]/a').get_attribute("href")
    titles.append(title)
    subtitles.append(subtitle)
    links.append(link)

dict = {'Titles' : titles, 'Subtitles' : subtitles, 'Links' : links}

headlines_df = pd.DataFrame(dict)
print(headlines_df)

Проверенные XPath: я дважды проверил XPath с помощью инструментов разработчика браузера, чтобы убедиться, что они точно нацелены на нужные элементы. Проблема сохраняется. Я по-прежнему извлекаю те же заголовки, субтитры и ссылки, несмотря на этап устранения неполадок.

Версия селена: 4.19.0 | Версия Python: 3.9.19 | Окружающая среда: блокнот Jupyter.

Я буду признателен за любую информацию или предложения, которые помогут мне определить основную причину этой проблемы и успешно скопировать отдельные заголовки, субтитры и ссылки с веб-сайта The Sun Football.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да... есть одна "странная" вещь, которую приходится делать с XPath при поиске по существующему элементу. Вместо

link = container.find_element(By.XPATH, '//div[@class = "teaser__copy-container"]/a')

вам нужно добавить '.' к началу XPath, например.

link = container.find_element(By.XPATH, './/div[@class = "teaser__copy-container"]/a')
                                         ^ period added here

Это применимо только к XPath и только тогда, когда вы используете .find_element() из элемента. Например, driver.find_element() работает нормально, но element.find_element() требует '.'. Это должно решить ваши проблемы.


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

from selenium import webdriver
from selenium.webdriver.common.by import By

import pandas as pd

# Website URL for news scraping
website = "https://www.thesun.co.uk/sport/football/"

# Initialise Firefox WebDriver using the service
driver = webdriver.Firefox()
driver.maximize_window()

# Open the desired website
driver.get(website)

containers = driver.find_elements(By.XPATH, '//div[@class = "teaser__copy-container"][./a]')

titles = []
subtitles = []
links = []
for container in containers:
    title = container.find_element(By.CSS_SELECTOR, 'a > span').get_attribute("data-original-text")
    subtitle = container.find_element(By.CSS_SELECTOR, 'a > h3').get_attribute("data-original-text")
    link = container.find_element(By.CSS_SELECTOR, 'a').get_attribute("href")
    titles.append(title)
    subtitles.append(subtitle)
    links.append(link)

dict = {'Titles' : titles, 'Subtitles' : subtitles, 'Links' : links}

headlines_df = pd.DataFrame(dict)
print(headlines_df)

Это выводит

           Titles                                          Subtitles                                              Links
0      OF HIS ILK   Gundogan's glam wife enters row with Barca st...  https://www.thesun.co.uk/sport/27404398/ilkay-...
1       NICE TUCH   Bayern president hails Tuchel for 'tactical m...  https://www.thesun.co.uk/sport/27402309/bayern...
...

Дополнительный отзыв

  1. Начиная с Selenium 4.6 вам больше не нужно загружать, настраивать и поддерживать собственные драйверы. Был добавлен Selenium Manager, который автоматически загрузит и установит для вас драйверы, соответствующие установленному вами браузеру. Итак, ваш первоначальный код можно упростить до

    from selenium import webdriver
    
    website = "https://www.thesun.co.uk/sport/football/"
    driver = webdriver.Firefox()
    driver.get(website)
    
  2. Предпочтительный способ написать .find_element() звонок:

    from selenium.webdriver.common.by import By
    
    driver.find_element(By.XPATH, '//div[@class = "teaser__copy-container"]/a')
    

    Ваш способ будет работать, но он подвержен опечаткам, и ваша IDE не узнает об опечатках, пока вы не запустите сценарий и он не завершится неудачно. Использование By.XPATH и т. д. позволяет избежать опечаток в типе локатора, а ваша IDE поможет вам автоматически заполнить его. Если есть опечатки, IDE пометит их как ошибки перед запуском, что сэкономит ваше время.


Поскольку вы запросили XPath, элементы containers уже найдены с помощью XPath. Приведенный ниже код должен позаботиться обо всем остальном.

title = container.find_element(By.XPATH, './a/span').get_attribute("data-original-text")
subtitle = container.find_element(By.XPATH, './a/h3').get_attribute("data-original-text")
link = container.find_element(By.XPATH, './a').get_attribute("href")

После добавления точки "." Я получил сообщение об ошибке: NoSuchElementException: Сообщение: Невозможно найти элемент: .//div[@class = "teaser__copy-container"]/a/span[@class = "tease‌​r__headline teaser__kicker t-p-color"]; Документацию по этой ошибке можно найти по адресу: selenium.dev/documentation/webdriver/troubleshooting/…. Когда снимаю, проблема сохраняется - извлекаются одни и те же заголовки, субтитры и ссылки.

Darry Mich 18.04.2024 16:40

@DarryMich Оказывается, ваши локаторы были неверными. Я обновил и упростил их. Я также опубликовал полный код с обновлениями и изменениями на основе моих дополнительных отзывов. Код работает, и я также опубликовал фрагмент вывода.

JeffC 18.04.2024 17:34

Вы заметите, насколько проще синтаксис селекторов CSS и насколько проще их использовать в случае element.find_element() и т. д. Это лишь одна из многих причин, по которым селекторам CSS следует отдавать предпочтение перед XPath. XPaths имеет свое место, но он предназначен для: 1. поиска элементов по содержащемуся в них тексту и 2. выполнения сложного обхода DOM.

JeffC 18.04.2024 17:36

Спасибо, JeffC, за ценные советы по решению проблемы, с которой я столкнулся. Предоставленный вами код работает, и синтаксис селектора CSS намного проще и проще. Я искренне ценю время и усилия, которые вы вложили в мою помощь! Но если вы не возражаете, мне интересно узнать правильные локаторы XPATH.

Darry Mich 19.04.2024 00:29

Сделанный. Добавил их в конец вопроса.

JeffC 19.04.2024 00:37

Другие вопросы по теме