
求救各位python大神,找不到他的API,我用selenium爬取公開資訊訊觀測站,
使用webdriver按下【詳細資料】按鈕可以成功開的了視窗,
但讀不到新跳出來的視窗
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
# 啟動 WebDriver
driver = webdriver.Chrome()
try:
    # 打開目標網頁
    driver.get("https://mopsov.twse.com.tw/mops/web/ajax_t114sb07?parameters=0eb65210d5bdc34ea16e295ccdbad1094cba7de165dfcdf4e7902f9ef62c42f5e1d5d55f2907af83df59ae82756caca37dd8deda6d21048dd6757f91f6feed9efade4567702b1a82869a09fd73fc40584805cee69a5101ddc3bffc42dba6838e87d6b6c0db4e0cc4b38b25e81f8e9e6aaeb537f477d135aaa7cfe6b60d70cfc4")
    # 記錄原始視窗
    original_window = driver.current_window_handle
    # 等待並點擊按鈕
    button = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, '//*[@id="t114sb07_fm"]/p[2]/table[2]/tbody/tr[4]/td[9]/input'))
    )
    driver.execute_script("arguments[0].click();", button)
    # 由於第二頁是動態生成的 (URL 為 about:blank),所以等待特定元素出現
    WebDriverWait(driver, 30).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "#table01"))
    )
    # 透過 CSS Selector 找到第二頁的表格 (JS Path: document.querySelector("#table01"))
    table_element = driver.find_element(By.CSS_SELECTOR, "#table01")
    table_html = table_element.get_attribute("outerHTML")
    # 使用 BeautifulSoup 解析表格 HTML
    soup = BeautifulSoup(table_html, "html.parser")
    rows = soup.find_all("tr")
    table_data = []
    for row in rows:
        cols = row.find_all(["td", "th"])
        cols = [col.get_text(strip=True) for col in cols]
        table_data.append(cols)
    # 打印第二頁表格的內容
    for row in table_data:
        print("\t".join(row))
    # 存入檔案
    with open("table01_data.txt", "w", encoding="utf-8") as file:
        for row in table_data:
            file.write("\t".join(row) + "\n")
    print("數據已成功寫入 table01_data.txt")
finally:
    driver.quit()
可能有些小 bug 自己在改改就好
# pip install requests bs4
import json
from dataclasses import asdict, dataclass, field
from typing import List, Optional
import requests
from bs4 import BeautifulSoup
year = 112
co_id = 1101
@dataclass
class StockCompensation:
    """股票報酬資料"""
    shares: float  # 配發股數
    market_price: float  # 市場價格(元/股)
    amount_a: float  # 計算後的股票報酬總額
@dataclass
class CashCompensation:
    """現金報酬資料"""
    amount_b: float  # 現金報酬總額
@dataclass
class ManagerCompensation:
    """管理階層報酬總計"""
    stock: StockCompensation  # 股票報酬資訊
    cash: CashCompensation  # 現金報酬資訊
    total_amount: float  # 總報酬金額(股票 + 現金)
    percentage_of_net_income: float  # 佔公司淨利比例(%)
@dataclass
class Manager:
    """管理階層人員資訊"""
    title: str  # 職稱
    name: str  # 姓名
@dataclass
class CompanyCompensation:
    """公司管理階層報酬資訊"""
    company_code: str  # 公司代號
    company_name: str  # 公司名稱
    employee_compensation_year: int  # 員工薪酬所屬年度
    distribution_year: int  # 發放年度
    unit: str  # 單位(元/股)
    manager_compensation: ManagerCompensation  # 管理階層報酬總計
    managers: List[Manager] = field(default_factory=list)  # 管理階層成員列表
def get_company_detailed(co_id: int, year: int) -> Optional[CompanyCompensation]:
    req = requests.post(
        "https://mopsov.twse.com.tw/mops/web/ajax_t114sb07",
        data={
            "encodeURIComponent": 1,
            "firstin": True,
            "id": "",
            "key": "",
            "TYPEK": "sii",
            "step": 32,
            "home_step": 0,
            "co_id": co_id,
            "year": year,
        },
    )
    soup = BeautifulSoup(req.text, "html.parser")
    form = soup.select_one("form")
    if form is None:
        return
    tables1 = form.select("table:nth-child(1)")
    table1 = tables1[0]  # 基本訊息
    table2 = tables1[1]  # 單位
    table3 = form.select("table:nth-child(2)")[0]  # 經理人酬勞分派情形
    table4 = tables1[2]  # 經理人職稱及姓名
    table1_tds = list(table1.select("td"))
    table4_tds = [x.text for x in table4.select("td") if x.text.strip()]
    year_data = table1_tds[2].select_one("td").contents  # type: ignore
    table3_tr_odd = [float(x.text.replace(",", "")) for x in table3.select("tr:nth-child(4) > td")]
    manager_compensation = ManagerCompensation(
        stock=StockCompensation(
            shares=table3_tr_odd[0],
            amount_a=table3_tr_odd[1],
            market_price=table3_tr_odd[2],
        ),  # 股票報酬資訊
        cash=CashCompensation(amount_b=table3_tr_odd[3]),  # 現金報酬資訊
        total_amount=table3_tr_odd[4],  # 總報酬金額(股票 + 現金)
        percentage_of_net_income=table3_tr_odd[5],  # 佔公司淨利比例(%)
    )
    manager_compensation: ManagerCompensation
    return CompanyCompensation(
        company_code=table1_tds[0].contents[2].text.strip(),
        company_name=table1_tds[1].contents[2].text.strip(),
        employee_compensation_year=int(year_data[1].text),
        distribution_year=int(year_data[4].text),
        unit=table2.text.strip(),
        manager_compensation=manager_compensation,
        managers=[Manager(title=title, name=name) for title, name in zip(table4_tds[::2], table4_tds[1::2])],
    )
if company := get_company_detailed(co_id, year):
    company_dict = asdict(company)
    print(json.dumps(company_dict, ensure_ascii=False, indent=2))
{
  "company_code": "1101",
  "company_name": "台泥",
  "employee_compensation_year": 111,
  "distribution_year": 112,
  "unit": "單位:元/股",
  "manager_compensation": {
    "stock": {
      "shares": 0.0,
      "market_price": 0.0,
      "amount_a": 0.0
    },
    "cash": {
      "amount_b": 8376383.0
    },
    "total_amount": 8376383.0,
    "percentage_of_net_income": 0.1549
  },
  "managers": [
    {
      "title": "企業團總執行長",
      "name": "張安平"
    },
    {
      "title": "總經理",
      "name": "程耀輝"
    },
    {
      "title": "資深副總經理",
      "name": "黃健強"
    },
    {
      "title": "資深副總經理",
      "name": "呂克甫"
    },
    {
      "title": "副總經理",
      "name": "葛保羅"
    },
    {
      "title": "副總經理",
      "name": "王建全"
    },
    {
      "title": "副總經理",
      "name": "劉鳳萍"
    },
    {
      "title": "副總經理",
      "name": "葉毓君"
    },
    {
      "title": "財務長",
      "name": "于明仁"
    },
    {
      "title": "資深協理",
      "name": "蔡國嶼"
    },
    {
      "title": "資深協理",
      "name": "丘惠生"
    },
    {
      "title": "資深協理兼會計主管",
      "name": "葉國宏"
    },
    {
      "title": "資深協理",
      "name": "邱鈺文"
    },
    {
      "title": "協理",
      "name": "辜公怡"
    },
    {
      "title": "協理",
      "name": "余金龍"
    },
    {
      "title": "協理",
      "name": "藍岑藯"
    },
    {
      "title": "協理兼公司治理主管",
      "name": "賴家柔"
    },
    {
      "title": "協理",
      "name": "陳光熙"
    },
    {
      "title": "協理",
      "name": "魏家珮"
    },
    {
      "title": "協理",
      "name": "李國源"
    },
    {
      "title": "協理",
      "name": "蔣政道"
    },
    {
      "title": "協理",
      "name": "陳銀華"
    },
    {
      "title": "協理",
      "name": "陳怡中"
    },
    {
      "title": "資安長",
      "name": "張年旺"
    },
    {
      "title": "資深經理",
      "name": "陳進益"
    },
    {
      "title": "資深經理",
      "name": "吳雲德"
    },
    {
      "title": "資深經理",
      "name": "陳技竫"
    },
    {
      "title": "資深經理",
      "name": "梁詩聖"
    },
    {
      "title": "經理兼稽核主管",
      "name": "曹家華"
    },
    {
      "title": "資深副理",
      "name": "吳子揚"
    },
    {
      "title": "資深副理",
      "name": "張毓揚"
    },
    {
      "title": "總經理",
      "name": "李鐘培"
    },
    {
      "title": "資深協理",
      "name": "黃麟添"
    },
    {
      "title": "協理",
      "name": "洪維爵"
    },
    {
      "title": "協理",
      "name": "宋又新"
    },
    {
      "title": "資深經理",
      "name": "李明達"
    },
    {
      "title": "經理",
      "name": "劉志仁"
    }
  ]
}