Использование селена для поиска индексированного элемента внутри div - PullRequest
2 голосов
/ 22 апреля 2019

Я очищаю интерфейс веб-страницы и испытываю трудности с получением текста HMTL для div внутри div.

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

Вот пример одной из страниц, которые я пытаюсь очистить:

https://www.bandsintown.com/e/1013664851-los-grandes-de-la-banda-at-aura-nightclub?came_from=257&utm_medium=web&utm_source=home&utm_campaign=event

<div class="eventInfoContainer-54d5deb3">
    <div class="lineupContainer-570750d2"> 
    <div class="eventInfoContainer-9e539994">
        <img src="assets.bandsintown.com/images.clock.svg">
        <div>Sunday, April 21st, 2019</div> <!––***––> 
        <div class="eventInfoContainer-50768f6d">5:00PM</div><!––***––> 
     </div> 
<div class="eventInfoContainer-1a68a0e1">
    <img src="assets.bandsintown.com/images.clock.svg">
    <div class="eventInfoContainer-2d9f07df">
        <div>Aura Nightclub</div> <!––***––> 
        <div>283 1st St., San Jose, CA 95113</div> <!––***––> 
</div>

Я пометил элементы, которые хочу извлечь, звездочками - дату, время, место и адрес.Вот мой код:

base_url = 'https://www.bandsintown.com/?came_from=257&page='
events = []
eventContainerBucket = []
for i in range(1, 2):
    driver.get(base_url + str(i))

# get events links
event_list = driver.find_elements_by_css_selector('div[class^=eventList-] a[class^=event-]')
# collect href attribute of events in even_list
events.extend(list(event.get_attribute("href") for event in event_list))



# iterate through all events and open them.
for event in events:
    driver.get(event)
    uniqueEventContainer = driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')[0]

    print "Event information: "+ uniqueEventContainer.text

Это печатает:

Event information: Sunday, April 21st, 2019
3:00 PM
San Francisco Brewing Co.
3150 Polk St, Sf, CA 94109
View All The Fourth Son Tour Dates

Моя проблема в том, что я не могу получить доступ к вложенным элементам div EventInfoContainer по отдельности.Например, div 'date' - это позиция [1], так как это второй элемент (после img) в его родительском div "eventInfoContainer-9e539994".Родительский div "eventInfoContainer-9e539994" находится в положении [1], если он также является вторым элементом в его родительском div "eventInfoContainer-54d5deb3" (после "lineupContainer).

По этой логике я не долженбыть в состоянии получить доступ к тексту даты по этому коду: (получая доступ к 1-му элементу позиции, с его родителем, являющимся 1-м элементом позиции, внутри контейнера (0-й элемент позиции)?

for event in events:
    driver.get(event)
    uniqueEventContainer = driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')[0][1][1]

Я получаю следующееошибка:

TypeError: 'WebElement' object does not support indexing

Любая помощь приветствуется! Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 22 апреля 2019

Когда вы индексируете в список webElements (то, что возвращает find_elements_by_css_selector('div[class^=eventInfoContainer-]')), вы получаете webElement, вы не можете дальше индексировать в этом.Вы можете разделить текст элемента webElement для создания списка для дальнейшей индексации.

Если на страницах имеется регулярная структура, вы можете загрузить html для div в BeautifulSoup.Пример URL:

from selenium import webdriver
from bs4 import BeautifulSoup as bs

d = webdriver.Chrome()
d.get('https://www.bandsintown.com/e/1013664851-los-grandes-de-la-banda-at-aura-nightclub?came_from=257&utm_medium=web&utm_source=home&utm_campaign=event')
soup = bs(d.find_element_by_css_selector('[class^=eventInfoContainer-]').get_attribute('outerHTML'), 'lxml')
date = soup.select_one('img + div').text
time = soup.select_one('img + div + div').text
venue = soup.select_one('[class^=eventInfoContainer-]:nth-of-type(3) div > div').text
address = soup.select_one('[class^=eventInfoContainer-]:nth-of-type(3) div + div').text

print(date, time, venue, address)

Если разрывы строк были согласованы:

containers = d.find_elements_by_css_selector('div[class^=eventInfoContainer-]')
array = containers[0].text.split('\n')
date = array[3]
time = array[4]
venue = array[5]
address = array[6]
print(date, time, venue, address)

С индексом и разделением:

from selenium import webdriver
from bs4 import BeautifulSoup as bs

d = webdriver.Chrome()
d.get('https://www.bandsintown.com/e/1013664851-los-grandes-de-la-banda-at-aura-nightclub?came_from=257&utm_medium=web&utm_source=home&utm_campaign=event')
containers = d.find_elements_by_css_selector('div[class^=eventInfoContainer-]')
date_time = containers[1].text.split('\n')
i_date = date_time[0]
i_time = date_time[1]
venue_address = containers[3].text.split('\n')
venue = venue_address[0]
address = venue_address[1]
print(i_date, i_time, venue, address)
1 голос
/ 22 апреля 2019

Как показывает ошибка, webelements не имеет индексации.То, что вы путаете с списком.

Здесь

driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')

Этот код возвращает список веб-элементов.Вот почему вы можете получить доступ к webelement, используя индекс списка.Но этот элемент не имеет индексации к другому элементу.Вы не получаете список списков.

Вот почему driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')[0] работает.Но driver.find_elements_by_css_selector('div[class^=eventInfoContainer-][0][1]') нет.


Редактировать: (Ответ на вопрос в комментарии)


Это не код слена.

Код, отправленный в ответе QHarr , использует BeautifulSoup.Это пакет python для разбора документов HTML и XML.
BeautifulSoup имеет метод .select(), который использует селектор CSS для проанализированного документа и возвращает все соответствующие элементы.
Существует также метод, называемый select_one(), который находит только первый тег, соответствующий селектору.

В коде

time = soup.select_one('img + div + div').text 
venue = soup.select_one('[class^=eventInfoContainer-]:nth-of-type(3) div > div').tex

Он получает первый элемент, найденный данным селектором CSS, и возвращает текст внутри тега.Первая строка находит тэг img, затем находит ближайший тэг div, а затем снова находит тэг dev-уровня предыдущего тега div.Во второй строке он находит третий родственный тег с классом, начинающимся с eventInfoContainer-, а затем находит дочернего элемента div и находит его дочернего элемента div.

Извлекает селекторы CSS

Это может быть сделано напрямую с помощью selenium:

date = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='clock.svg'] + div")
time = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'] + div + div")
venue = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='pin.svg'] + div > div")
address = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='pin.svg'] + div > div:nth-of-type(2)")

Я использовал разные селекторы CSS, но он по-прежнему выбирает те же элементы.
Я не уверен насчетBeautifulSoup но в ответе QHarr селектор даты вернет другое значение вместо предполагаемого значения для селена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...