Попытка очистить ссылки на карты Google, размещенные в фреймах на динамических веб-страницах, успешна в некоторых из нихPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Попытка очистить ссылки на карты Google, размещенные в фреймах на динамических веб-страницах, успешна в некоторых из них

Сообщение Anonymous »

Я пытаюсь получить информацию о времени и месте на веб-сайте Timable, на котором представлены публичные мероприятия, он использует карту Google для отображения подробных мест, у некоторых мероприятий есть только одно место, и я успешно получил ссылку , но тем, у кого есть несколько ссылок, кажется, что из Google вообще нет ссылки. Как это произошло?
У меня есть написанный код, показанный ниже, и четыре примера страниц событий для тестирования. Цифры обозначают количество мест для каждого мероприятия.

Код: Выделить всё

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException
import time
import pandas as pd
import os
import re

chrome_options = Options()
browser = webdriver.Chrome()

# test examples
# 1 聯和墟社區會堂
url = 'https://timable.com/hk/zh/event/2257473/%E7%84%A1%E6%AF%92-%E6%9C%89%E6%A8%82%E5%9C%A8%E5%8C%97%E5%8D%80-%E5%98%89%E5%B9%B4%E8%8F%AF-2022'
# 3 甲辰年中秋綵燈會 2024
# url = 'https://timable.com/hk/zh/event/66a32ffbea8f6c5f5431d608/%E7%94%B2%E8%BE%B0%E5%B9%B4%E4%B8%AD%E7%A7%8B%E7%B6%B5%E7%87%88%E6%9C%832024'
# 6 避風涼茶館社區巡演
# url = 'https://timable.com/hk/zh/event/66bd5f564d998ae07f8356b1/%E9%81%BF%E9%A2%A8%E6%B6%BC%E8%8C%B6%E9%A4%A8%E7%A4%BE%E5%8D%80%E5%B7%A1%E6%BC%94'
# 1 Skechers Summer Waterpark
# url = 'https://timable.com/hk/zh/event/6684296b5c76c0dac9625910/Skechers%E6%88%B6%E5%A4%96%E6%B0%B4%E4%B8%8A%E6%A8%82%E5%9C%92'
browser.get(url)

time.sleep(5)

# -----------------------------------------------------------------------------------------------------------------------
def sanitize_string(value):
# Define a regex pattern to match illegal characters (e.g., control characters)
# Only keep printable characters (remove non-printable characters)
return re.sub(r'[\x00-\x1f\x7f-\x9f]', '', value)
# -----------------------------------------------------------------------------------------------------------------------
def find_between(s, first, last):
try:
start = s.index(first) + len(first)
end = s.index(last, start)
return s[start:end]
except ValueError:
return ""
# -----------------------------------------------------------------------------------------------------------------------
def extract_event_info(url):
# event = ["", "", "", "", "", ""] # ensure at least an array should be returned

attempts_u = 3
while attempts_u > 0:
try:
browser.get(url)
time.sleep(5)

# Retry to locate parent container to handle Stale Element
attempts_p = 3
while attempts_p >  0:
try:
parent_container = WebDriverWait(browser, 15).until(
EC.visibility_of_element_located((By.XPATH, "//div[@class='chakra-container cha-pmdu9d']"))
)
break  # Break if successful
except StaleElementReferenceException:
attempts_p -= 1
if attempts_p == 0:
print(f"Error(parent_container) for url: {url}: {e}")
return event
time.sleep(2)  # Wait before retrying
except:
attempts_p -= 1
if attempts_p == 0:
print(f"Error(parent_container) for url {url}: {e}")
return event
time.sleep(2)  # Wait before retrying

# fully load the parent container to make sure everything wanted is loaded before extraction
parent_container = WebDriverWait(browser, 15).until(
EC.visibility_of_element_located((By.XPATH, "//div[@class='chakra-container cha-pmdu9d']"))
)

# box 2
event_box2 = WebDriverWait(browser, 15).until(
EC.visibility_of_element_located((By.XPATH, "//div[@id='displayLocation']"))
)
if event_box2: print("event_box2 found!")
if event_box2:
# box2_child_box_list = event_box2.find_elements(By.XPATH, ".//div[contains(@class, 'cha-gq6fqh')]")
box2_child_box_list = WebDriverWait(event_box2, 15).until(
EC.presence_of_all_elements_located((By.XPATH, ".//div[contains(@class, 'cha-gq6fqh')]"))
)
if box2_child_box_list: print("box2_child_box_list found!")

# a_tags = event_box2.find_elements(By.XPATH, "//a")
a_tags = event_box2.find_elements(By.XPATH, "//a[contains(@href,'https://maps.google.com/maps?ll=')]")
if a_tags:
print("a tags found!")
location_div_titles = [box2_child_box.find_element(By.XPATH, ".//p[contains(@class, 'chakra-text cha-722v25')]").text for box2_child_box in box2_child_box_list]
print(f"location_div_titles: {location_div_titles}")
for a_tag in a_tags:
link = a_tag.get_attribute("href")
print(f"link: {link}")

# box 1
event_box1 = parent_container.find_element(By.XPATH, ".//div[contains(@class, 'cha-nm882m')]") # get the box covering all the times and locations
child_box_list = event_box1.find_elements(By.XPATH, "./div")
child_box_amt = len(child_box_list)
# print(f"child_box_amt: {child_box_amt}")
box1 = []
for child_box in child_box_list:
child_box_div_list = child_box.find_elements(By.XPATH, "./div")
child_box_div_all = []
child_box_div_time = []
child_box_div_location = []
for child_box_div in child_box_div_list:
element_class = child_box_div.get_attribute("class")
if element_class == 'chakra-stack cha-16yidj1': # time
child_box_div_time.append(child_box_div.text)
elif element_class == 'chakra-stack cha-1igwmid': # location
location_name_text = child_box_div.find_element(By.XPATH, ".//button").text
child_box_div_p2 = child_box_div.find_elements(By.XPATH, ".//p[2]")
if child_box_div_p2:
# detailed_address_text = child_box_div_p2[0].text
detailed_address_text = ', ' + child_box_div_p2[0].text
else: detailed_address_text = ''
location = location_name_text + detailed_address_text

# # if "显示位置"  is available, add the detailed info of locations for reference
# if box2_child_box_list_for_use:
#     for i in range(len(box2_child_box_list_for_use)):
#         if box2_child_box_list_for_use[i][0] == location_name_text:
#             location += ', ' + box2_child_box_list_for_use[i][1] + ', ' + box2_child_box_list_for_use[i][2]

child_box_div_location.append(location)
child_box_div_all.append(child_box_div_time)
child_box_div_all.append(child_box_div_location)
location_num = len(child_box_div_location)
child_box_string = '; '.join(', '.join(map(str, subarray)) for subarray in child_box_div_all)
box1.append(child_box_string)
event_time_location = '~'.join(map(str, box1))
# print(f"event_time_location: {event_time_location}")
# event[3] = location_num
# event[4] = event_time_location

break  # Break if successful

except StaleElementReferenceException:
attempts_u -= 1
if attempts_u == 0:
print(f"Error(getting url) for url: {url}: {e}")
return event
time.sleep(2)  # Wait before retrying
except Exception as e:
attempts_u -= 1
if attempts_u == 0:
print(f"Error(getting url) for url: {url}: {e}")
return event
time.sleep(2)  # Wait before retrying

# return event
return None

# event= extract_event_info(url)
extract_event_info(url)
# print(event)
# output_file = os.path.join('output', f'output_test_1018.xlsx')  # Output file name in the output folder
# columns = ['Title', 'Type', 'Keyword', 'Location Num', 'Time & Location', 'Description']
# events_df = pd.DataFrame(event, columns=columns)
# events_df = pd.DataFrame([event], columns=columns)
# events_df.to_excel(output_file, index=False)
browser.close()
Например, при тестировании первого события получена ссылка в виде:
введите здесь описание изображения
но для второго события ссылка не получена:
/>введите здесь описание изображения

Подробнее здесь: https://stackoverflow.com/questions/791 ... successful
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»