Как получить данные из IFRAME с помощью Python и Selenium

Я пытаюсь получить значение с этой страницы: https://www.bbva.com.co/personas/productos/inversion/fondos/pais.html

Я образ, я показываю вам, что мне нужно получить.

Проверенная страница

Первое, что я вижу, это то, что это значение находится внутри Iframe с классом = «iframe_base».

Я попробовал следующий код для извлечения значения, но он не сработал должным образом, потому что я ничего не получил.

Я использую селен и веб-драйвер Microsoft Edge.

Что я делаю не так? и Как я могу получить то, что мне нужно?

Спасибо.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
import time

# Configura el controlador de Edge
edge_options = Options()
# edge_options.add_argument("--headless") 
service = Service("C:/Users/PERSONAL/Downloads/msedgedriver.exe")  
driver = webdriver.Edge(service=service, options=edge_options)

# Abre la página web
driver.get("https://www.bbva.com.co/personas/productos/inversion/fondos/pais.html")  # Reemplaza con la URL real

# Espera hasta que el iframe esté presente
time.sleep(5)  # Espera 5 segundos, ajusta según sea necesario

print("Seleccionamos el IFRAME")
iframe1 = driver.find_element(By.XPATH, "//*[@id = 'content-iframe_copy']")

print("Cambiamos el foco el IFRAME")
driver.switch_to.frame(iframe1)

print("Obtener HTML del IFRAME")
html = driver.page_source
print(html)

print("Obtener el dato")
dato = driver.find_elements(By.TAG_NAME, "g")
print(dato)

driver.quit()

🤔 А знаете ли вы, что...
Python имеет богатую стандартную библиотеку, включая модули для работы с текстом, файлами и сетями.


64
3

Ответы:

ты можешь использовать это

from bs4 import BeautifulSoup as BS

soup = BS(driver.page_source, features = "html.parser")
step1 = soup.find("div", class_ = "caja-liquidativo-rentabilidad")
step2 = step1.find("p", class_ = "liquidativo-rentabilidad)"

У меня нет доступа к Edge, но это работает с Chrome и, я думаю, будет работать и с Edge.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service
from selenium.webdriver.chrome.options import Options
import time

DRIVER_PATH = "/usr/bin/chromedriver"

options = Options()

service = Service(executable_path=DRIVER_PATH)

driver = webdriver.Chrome(service=service, options=options)

driver.get("https://www.bbva.com.co/personas/productos/inversion/fondos/pais.html")

iframe = driver.find_element(By.CSS_SELECTOR, "#content-iframe_copy")

driver.switch_to.frame(iframe)

time.sleep(5)

price = driver.execute_script(
    """
    var shadowHost = document.querySelector('fichaco-page');
    var shadowRoot = shadowHost.shadowRoot;
    return shadowRoot.querySelector('.liquidativo-rentabilidad').textContent;
"""
)

print(price)

driver.quit()

Хитрость здесь в том, что да, есть <iframe> (и вы были правы, переключившись на него!), но страница, включенная в <iframe>, имеет теневой DOM. Поэтому вам нужно проникнуть в теневой DOM, чтобы получить доступ к содержимому внутри.


Решено

вы можете использовать не селеновый раствор:

import requests
import json

headers = {
    'accept': 'application/json, text/plain, */*; q=0.01',
    'content-type': 'application/json',
}


def get_tsec() -> str:
    url = "https://www.bbva.es/ASO/TechArchitecture/grantingTickets/V02"
    payload = json.dumps({
        "authentication": {
            "consumerID": "30000032",
            "userID": "IMMH032",
            "authenticationType": "04",
            "authenticationData": [
                {
                    "authenticationData": [
                        "WAMH032P"
                    ],
                    "idAuthenticationData": "password"
                }
            ]
        }
    })
    response = requests.request("POST", url, headers=headers, data=payload)
    return response.headers['tsec']


def get_value(pair_name: str, tsec: str) -> float:
    url = f"https://www.bbva.es/ASO/management-entity-funds/v1/management-entities-funds/{pair_name}"
    headers['tsec'] = tsec
    response = requests.get(url, headers=headers)
    for x in response.json()['data']['netAssetValues']:
        if x['netAssetValueType']['id'] == 'LAST_DATE':
            return x['netAssetValueAmount']['amount']


print(get_value('CCAPAISCB', get_tsec()))

ВЫХОД:

21128.849089