Я пытаюсь почистить веб-страницу, в которой используются объекты JS.
Я использую Selenium в среде Python;Я использую селен, чтобы загрузить то, что я хочу, то есть текст «ПРОСМОТРЕТЬ ВЫБОР ТВ ПАКЕТА», который запускает модальный контейнер.
![enter image description here](https://i.stack.imgur.com/ra5K6.jpg)
В этом контейнере, есть заголовки пакетов, с каналами под ними.Я пытаюсь перебрать каждый заголовок и захватить названия каналов в каждом.
Это веб-страница
Вот мой код, который поможет вам перейти к контейнеру, который я пытаюсь очистить:
from selenium import webdriver
import pandas as pd
url = "https://www.rogers.com/consumer/tv#/packages"
#create a new Chrome session
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get(url)
#change the province to Ontario
province_button = driver.find_element_by_class_name("dropdown-toggle")
province_button.click() #clicks dropdown
province_button = driver.find_element_by_link_text("Ontario")
province_button.click() #clicks dropdown
#visit TV portal page, re-init url again
driver.get(url)
#####BEGIN SCRAPING PACKAGE INFO#####
#open Select Package window
package_button = driver.find_element_by_class_name("Package-details")
package_button.click() #clicks dropdown
package_data = driver.find_elements_by_class_name("Package-channels")
package_data
var возвращает все мои заголовки и названия каналов;но не указание того, какие строки были заголовками, а какие - каналами.Я знаю, что мог бы написать какое-то сложное регулярное выражение, чтобы добиться цели, но я надеюсь на динамический подход.Любой совет приветствуется.Спасибо!
****** РЕДАКТИРОВАНИЕ *******
В комментариях ниже приведен код, который переводит WebElements в переменную вместо вывода в консоль:
select_package_data = []
headingsCount = len(driver.find_elements_by_xpath("//div[@class='modal-
content']//*[contains(@class,'Package-channels--heading ng-binding')]"))
for index in range(headingsCount):
head = driver.find_element_by_xpath("//div[@class='modal-content']//*
[contains(@class,'Package-channels--heading ng-binding')]
[index]".replace('index',str(index+1)))
select_package_data.append(head.text)
channelsPerheading = driver.find_elements_by_xpath("(//div[@class='modal-
content']//ul[@ng-if='vm.channels'])[index]/li[not
(contains(@class,'Package-channels--heading ng-
binding'))]".replace('index',str(index+1)))
temp_list=[]
for channel in channelsPerheading:
temp_list.append(channel.text.encode('utf-8'))
select_package_data.insert((index+1), temp_list[:])`
********* РЕДАКТИРОВАНИЕ V2 ЗА КОММЕНТАРИИ: *********
Окончательный код требует добавления скобок в методе xpath;Я полагаю, что это связано с [index]
, добавленным в конец фактического xpath при назначении его переменной:
#get the count of headings in the modal contaier
headingsCount = len(driver.find_elements_by_xpath("//div[@class='modal-
content']//*[contains(@class,'Package-channels--heading ng-binding')]"))
#use this count as an iterator
for index in range(headingsCount):
#get the first heading - we use replace method bc xpath is not zero-indexed
head = driver.find_element_by_xpath("(//div[@class='modal-content']//*
[contains(@class,'Package-channels--heading ng-binding')])
[index]".replace('index',str(index+1)))
header_placeholder = head.text
##takes heading element as text to use for dataframe row index label
#goes to //ul tag in accordance with current index, finds all BUT the
#headings
channelsPerheading = driver.find_elements_by_xpath("(//div[@class='modal-
content']//ul[@ng-if='vm.channels'])[index]/li[not
(contains(@class,'Package-channels--heading ng-
binding'))]".replace('index',str(index+1)))
temp_list=[]
for channel in channelsPerheading: #append the channels as text to a temp
list
temp_list.append(channel.text.encode('utf-8'))