Как получить javascript сгенерированный html, который я вижу, нажав «проверить элемент» в браузере? - PullRequest
1 голос
/ 09 марта 2020

Я пытаюсь получить часы доступных временных интервалов с этой веб-страницы (поля под календарем):

https://magicescape.it/le-stanze/lo-studio-di-harry-houdini/

I ' Мы прочитали другие связанные вопросы и написали этот код

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import presence_of_element_located
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoup

url = 'https://magicescape.it/le-stanze/lo-studio-di-harry-houdini/'
wait_time = 10
options = Options()
options.headless = True

driver = webdriver.Firefox(options=options)
driver.get(url)
driver.switch_to.frame(0)

wait = WebDriverWait(driver, wait_time)
first_result = wait.until(presence_of_element_located((By.ID, "sb_main")))

soup = BeautifulSoup(driver.page_source, 'html.parser')
print(soup)

driver.quit()

После переключения на iframe, содержащий временные интервалы, я получаю это после печати soup

<script id="time_slots_view" type="text/html"><div class="slots-view{{#ifCond (getThemeOption 'timeline_modern_display') '==' 'as_table'}} as-table{{/ifCond}}">
    <div class="timeline-wrapper">
        <div class="tab-pd">
            <div class="container-caption">
                {{_t 'available_services_on_this_day'}}
            </div>

            {{#if error_message}}
                <div class="alert alert-danger alert-dismissible" role="alert">
                    {{error_message}}
                </div>
            {{/if}}

            {{>emptyTimePart is_empty=is_empty is_loaded=is_loaded}}

            <div id="sb_time_slots_container"></div>
            {{> bookingTimeLegendPart legend="only_available" time_diff=0}}
        </div>
    </div>
</div></script>
<script id="time_slot_view" type="text/html"><div class="slot">
    <a class="sb-cell free {{#ifPluginActive 'slots_count'}}{{#if available_slots}}has-available-slot{{/if}}{{/ifPluginActive}}" href="#{{bookingStepUrl time=time date=date}}">
        {{formatDateTime datetime 'time' time_diff}}

        {{#ifCond (getThemeOption 'timeline_show_end_time') '==' 1}}
            -<span class="end-time">
                &nbsp;{{formatDateTime end_datetime 'time' time_diff}}
            </span>
        {{/ifCond}}

        {{#ifPluginActive 'slots_count'}}
            {{#if available_slots}}
                <span class="slot--available-slot">
                    {{available_slots}}
                    {{#ifConfigParam 'slots_count_show_total' '==' true}} / {{total_slots}} {{/ifConfigParam}}
                </span>
            {{/if}}
        {{/ifPluginActive}}
    </a>
</div></script>

при щелчке правой кнопкой мыши> осмотреть элемент на веб-странице Я получаю это

<div class="slots-view">
  <div class="timeline-wrapper">
    <div class="tab-pd">
      <div class="container-caption">
        Orari d'inizio disponibili
      </div>
      <div id="sb_time_slots_container">
        <div class="slot">
          <a class="sb-cell free " href="#book/location/4/service/6/count/1/provider/6/date/2020-03-09/time/23:00:00/">
            23:00
          </a>
        </div>
      </div>
      <div class="time-legend">
        <div class="available">
          <div class="circle">
          </div>
          - Disponibile
        </div>
      </div>
    </div>
  </div>
</div>

Как я могу получить час доступных слотов (23:00 в этом примере), используя селен?

1 Ответ

1 голос
/ 12 марта 2020

Чтобы получить желаемый ответ, вам необходимо:

  1. Правильно определить iframe, на который вы хотите переключиться (и переключиться на него). Вы пытались переключиться на frame[0], но вам нужно frame[1]. Следующий код удаляет зависимость от индексов и использует xpath.
  2. Получите элементы, содержащие время. Опять же это использует xpath, чтобы идентифицировать все дочерние элементы div элемента с id=sb_time_slots_container.
  3. Затем мы перебираем эти дочерние элементы div и получаем свойство text, которое вкладывается в <a> из этих div.

Для обоих шагов 1 и 2 следует также использовать wait.until, чтобы можно было загружать контент.

...
driver.get(url)
wait = WebDriverWait(driver, wait_time)

# Wait until the iframe exists then switch to it
iframe_element = wait.until(presence_of_element_located((By.XPATH, '//*[@id="prenota"]//iframe')))
driver.switch_to.frame(iframe_element)

# Wait until the times exist then get an array of them
wait.until(presence_of_element_located((By.XPATH, '//*[@id="sb_time_slots_container"]/div')))
all_time_elems = driver.find_elements_by_xpath('//*[@id="sb_time_slots_container"]/div')

# Iterate over each element and print the time out
for elem in all_time_elems:
    print(elem.find_element_by_tag_name("a").text)

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