Я столкнулся с проблемой при очистке заголовков новостей, субтитров и ссылок с веб-сайта 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 подходит для начинающих программистов благодаря своей простоте и читаемости кода.
Да... есть одна "странная" вещь, которую приходится делать с 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...
...
Дополнительный отзыв
Начиная с Selenium 4.6 вам больше не нужно загружать, настраивать и поддерживать собственные драйверы. Был добавлен Selenium Manager, который автоматически загрузит и установит для вас драйверы, соответствующие установленному вами браузеру. Итак, ваш первоначальный код можно упростить до
from selenium import webdriver
website = "https://www.thesun.co.uk/sport/football/"
driver = webdriver.Firefox()
driver.get(website)
Предпочтительный способ написать .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")