Парсинг веб-страниц Python в SAP Business Objects CMC: получение списка расписаний

Парсинг веб-страниц Python в SAP Business Objects CMC: получение списка расписаний

14 января 2024 г.

Недавно передо мной встала задача: организовать все расписания SAP Business Objects в файл Excel. Ручной процесс был утомительным: копирование имени и деталей каждого расписания и вставка их в Excel. С сотнями расписаний это означало бесконечное копирование.

Я порылся в Интернете в поисках решений и обнаружил, что основным решением является Query Builder. Однако экспорт результатов Power Builder из Интернета в файл Excel по-прежнему является сложной задачей.

Я также попробовал API SAP Business Objects, он мог получить все расписания, но количество повторяющихся расписаний не такое, как в SAP BO CMC.

Итак, я обратился к Python, и он работает! Если вы столкнулись с той же проблемой, мой код может оказаться тем решением, которое вы ищете.

Яимпортирую библиотеки

import pandas as pd
from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.webdriver.common.by import By
import time

Здесь импортируются необходимые библиотеки. pandas для манипулирования данными, selenium для очистки веб-страниц, BeautifulSoup для анализа HTML и time для добавления пауз между операциями .

Настройка сведений о соединении SAP BO

bo_cmc = 'http://localhost:port/BOE/CMC'
bo_user_name = 'username'
bo_password = 'password'

Он определяет URL-адрес центральной консоли управления SAP BusinessObjects (CMC) и учетные данные для входа.

Функция получения супа (HTML-содержимое)

def get_soup(driver, xpath):
    element = driver.find_element(By.XPATH, xpath)
    soup = BeautifulSoup(element.get_attribute("innerHTML"), 'lxml')
    soup.prettify()
    return soup

Эта функция использует Selenium для поиска HTML-элемента с помощью XPath, извлекает его внутренний HTML-код, а затем создает объект BeautifulSoup для анализа.

Функции для преобразования HTML в список и DataFrame

def bo_instances_html_to_list(soup):
    n = int(len(soup.select('tr td div')) / 16)
    values = [[] * n for _ in range(n)]
    for i in range(n):
        for j in range(16):
            values[i].append(soup.select('tr td div')[i * 16 + j].text)
    return values

def bo_values_to_df(values):
    df = pd.DataFrame(values)
    df.columns = ['', 'title', 'type', 'status', 'location', 'owner', 'completion_time', 'next_run_time',
                  'submission_time',
                  'start_time', 'duration', 'recurrence', 'expiry', 'server', 'error', 'title2']
    return df

def bo_instance_to_df(soup):
    values = bo_instances_html_to_list(soup)
    df = bo_values_to_df(values)
    return df

Эти функции преобразуют HTML-содержимое экземпляров SAP BO в список, а затем в DataFrame Pandas.

Функция автоматизации Selenium

def bo_selenium_to_df():
    options = webdriver.ChromeOptions()
    prefs = {'profile.default_content_settings.popups': 0}
    options.add_experimental_option('prefs', prefs)
    options.add_experimental_option("detach", True)
    driver = webdriver.Chrome(options=options)
    driver.get(bo_cmc)
    driver.switch_to.frame("servletBridgeIframe")
    time.sleep(3)

    username_input = driver.find_element(By.XPATH, '//*[@id="_id2:logon:USERNAME"]')
    password_input = driver.find_element(By.XPATH, '//*[@id="_id2:logon:PASSWORD"]')

    time.sleep(1)
    username_input.send_keys(bo_user_name)
    time.sleep(1)
    password_input.send_keys(bo_password)
    time.sleep(1)

    login_button = driver.find_element(By.XPATH, '//*[@id="_id2:logon:logonButton"]')
    time.sleep(1)
    login_button.click()

    time.sleep(5)
    html_text = driver.execute_script("return document.documentElement.outerHTML")
    contentFrame = driver.find_element(By.XPATH, '//*[@id="contentFrame"]')
    driver.switch_to.frame(contentFrame)
    time.sleep(2)

    innerContent = driver.find_element(By.XPATH, '//*[@id="innerContent"]')
    driver.switch_to.frame(innerContent)
    time.sleep(2)

    instance_manager_href = driver.find_element(By.XPATH, '//*[@id="manageList"]/li[1]/a[2]')
    instance_manager_href.click()
    time.sleep(1)

    # instancemanager
    ## switch to innerContent iframe
    html_page = driver.execute_script("return document.documentElement.outerHTML")
    contentFrame = driver.find_element(By.XPATH, '//*[@id="contentFrame"]')
    driver.switch_to.frame(contentFrame)
    time.sleep(1)

    innerContent = driver.find_element(By.XPATH, '//*[@id="innerContent"]')
    driver.switch_to.frame(innerContent)
    time.sleep(1)

    frames = []

    soup = get_soup(driver, xpath='//*[@id="UniversalRepositoryExplorer_detailView_mainTableBody"]')
    n = int(len(soup.select('tr td div')) / 16)
    df_start = bo_instance_to_df(soup=soup)
    frames.append(df_start)

    # In SAP BusinessObjects (SAP BO), schedules default to displaying 50 schedules per page.
    while n == 50:
        next_page_button = driver.find_element(By.XPATH, '//*[@id="UniversalRepositoryExplorer_goForwardButton"]')
        next_page_button.click()
        time.sleep(2)
        soup = get_soup(driver, xpath='//*[@id="UniversalRepositoryExplorer_detailView_mainTableBody"]')
        df = bo_instance_to_df(soup=soup)
        frames.append(df)
        n = int(len(soup.select('tr td div')) / 16)

    df = pd.concat(frames, axis=0)
    driver.close()
    drop_column = ['', 'completion_time', 'start_time', 'duration', 'server', 'error', 'title2']

    for column in drop_column:
        df = df.drop(column, axis=1)

    df['index'] = range(1, len(df) + 1)
    df = df[['index', 'title', 'type', 'status', 'location', 'owner', 'next_run_time',
             'submission_time', 'recurrence', 'expiry']]
    return df

Эта функция использует Selenium для автоматизации процесса входа в SAP BO, перехода к диспетчеру расписания, извлечения деталей расписания и, наконец, преобразования их в DataFrame Pandas.

Выполнение функции Selenium

df = bo_selenium_to_df()

Эта строка вызывает функцию Selenium и сохраняет полученный DataFrame в переменной df.


Спасибо, что нашли время, чтобы вместе со мной изучить информацию, связанную с данными. Я ценю ваше участие. Если эта информация окажется для вас полезной, я приглашаю вас подписаться на меня или связаться со мной на LinkedIn. Приятного изучения!👋

:::информация Также появляется здесь.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE