CoolFace
Apppublic

Pikachu0309/20250412_law

sourceHugging Faceotherupdated 1y agoView on Hugging Face
0likes
app.py197 linesDownload Raw Back to root
1import streamlit as st2 3# ✅ st.set_page_config 必須是第一個 Streamlit 命令4st.set_page_config(5    page_title="最新法規爬蟲工具",6    page_icon="⚖️",7    layout="wide"8)9 10import requests11from bs4 import BeautifulSoup12import pandas as pd13import re14import base6415from io import BytesIO16import plotly.graph_objects as go17from plotly.subplots import make_subplots18import plotly.express as px19 20# 設定背景圖片21def set_background(png_file):22    with open(png_file, "rb") as f:23        data = f.read()24    encoded_data = base64.b64encode(data).decode()25    st.markdown(26        f"""27        <style>28        .stApp {{29            background-image: url(data:image/png;base64,{encoded_data});30            background-size: cover;31        }}32        </style>33        """,34        unsafe_allow_html=True35    )36 37# 設定背景圖為law.png38set_background('law.png')39 40# 網頁標題和介紹41st.title("⚖️ 最新法規爬蟲工具 ⚖️")42st.markdown("這個應用程式可以從台灣法務部網站抓取法規資訊。您可以指定抓取的資料筆數和目標網址。")43 44# 側邊欄設置45with st.sidebar:46    st.header("設定")47    url = st.text_input("目標網址", "https://law.moj.gov.tw/")48    max_items = st.slider("抓取筆數", 1, 30, 10)49 50    st.markdown("---")51    st.markdown("### 關於")52    st.markdown("此工具使用 Python 的 BeautifulSoup 和 requests 庫來爬取法務部網站的法規資訊。")53    st.markdown("資料僅供參考,請以法務部官方公告為準。")54 55# 定義爬蟲函數56@st.cache_data(ttl=3600)57def scrape_moj_website(url, max_items=10):58    headers = {59        'User-Agent': 'Mozilla/5.0'60    }61    try:62        with st.spinner(f"正在從 {url} 抓取資料..."):63            response = requests.get(url, headers=headers)64            response.raise_for_status()65            soup = BeautifulSoup(response.text, 'html.parser')66            results = []67 68            news_table = soup.find('table', {'class': 'table'})69            if news_table:70                rows = news_table.find_all('tr')71                for row in rows:72                    cells = row.find_all('td')73                    if len(cells) >= 3:74                        try:75                            publish_date = cells[0].text.strip()76                            law_type = cells[1].text.strip()77                            content_cell = cells[2].find('a')78                            if content_cell:79                                content = content_cell.text.strip()80                                content_url = content_cell.get('href', '')81                                if content_url and not content_url.startswith('http'):82                                    if content_url.startswith('/'):83                                        base_url = '/'.join(url.split('/')[:3])84                                        content_url = base_url + content_url85                                    else:86                                        content_url = url.rstrip('/') + '/' + content_url87 88                                results.append({89                                    '發布時間': publish_date,90                                    '法條類型': law_type,91                                    '條文': content,92                                    '連結': content_url93                                })94 95                                if len(results) >= max_items:96                                    break97                        except Exception as e:98                            st.warning(f"處理行時出錯: {e}")99                            continue100 101            if len(results) < max_items:102                st.warning(f"無法從網站找到足夠的資料,將添加示例資料至 {max_items} 筆")103                num_to_add = max_items - len(results)104                for i in range(num_to_add):105                    results.append({106                        '發布時間': f'114-04-{12+i}',107                        '法條類型': '法規草案',108                        '條文': f'示例法規 #{i+1}',109                        '連結': 'https://gazette.nat.gov.tw/egFront/detail.do?metaid=156524&log=detailLog'110                    })111 112            return pd.DataFrame(results)113 114    except Exception as e:115        st.error(f"抓取資料時發生錯誤: {e}")116        data = []117        for i in range(max_items):118            data.append({119                '發布時間': f'114-04-{12+i}',120                '法條類型': '法規草案',121                '條文': f'示例法規 #{i+1}',122                '連結': 'https://gazette.nat.gov.tw/egFront/detail.do?metaid=156524&log=detailLog'123            })124        return pd.DataFrame(data)125 126# 下載功能127 128def get_csv_download_link(df, filename="data.csv"):129    csv = df.to_csv(index=False, encoding='utf-8-sig')130    b64 = base64.b64encode(csv.encode('utf-8-sig')).decode()131    href = f'<a href="data:file/csv;base64,{b64}" download="{filename}">點擊下載 CSV 檔案</a>'132    return href133 134def get_excel_download_link(df, filename="data.xlsx"):135    output = BytesIO()136    writer = pd.ExcelWriter(output, engine='xlsxwriter')137    df.to_excel(writer, index=False, sheet_name='法規資料')138    writer.close()139    processed_data = output.getvalue()140    b64 = base64.b64encode(processed_data).decode()141    href = f'<a href="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,{b64}" download="{filename}">點擊下載 Excel 檔案</a>'142    return href143 144# 主程式區域145col1, col2 = st.columns([3, 1])146 147with col2:148    if st.button("開始抓取", type="primary", use_container_width=True):149        st.session_state.df = scrape_moj_website(url, max_items)150        st.session_state.scraped = True151 152    if st.button("清除資料", type="secondary", use_container_width=True):153        st.session_state.pop('df', None)154        st.session_state.pop('scraped', None)155 156with col1:157    if 'scraped' in st.session_state and 'df' in st.session_state:158        st.success(f"已成功抓取 {len(st.session_state.df)} 筆資料")159        st.dataframe(st.session_state.df, use_container_width=True)160 161        st.markdown("### 下載選項")162        col_a, col_b = st.columns(2)163        with col_a:164            st.markdown(get_csv_download_link(st.session_state.df, "法務部法規資料.csv"), unsafe_allow_html=True)165        with col_b:166            st.markdown(get_excel_download_link(st.session_state.df, "法務部法規資料.xlsx"), unsafe_allow_html=True)167    else:168        st.info("請點擊「開始抓取」按鈕來獲取法規資料")169 170# 資料分析171if 'scraped' in st.session_state and 'df' in st.session_state and not st.session_state.df.empty:172    with st.expander("📊 資料分析"):173        st.subheader("法條類型分布")174        type_counts = st.session_state.df['法條類型'].value_counts().reset_index()175        type_counts.columns = ['法條類型', '數量']176        st.bar_chart(type_counts.set_index('法條類型'))177 178        st.subheader("發布時間分布")179        date_counts = st.session_state.df['發布時間'].value_counts().sort_index().reset_index()180        date_counts.columns = ['發布時間', '數量']181        st.line_chart(date_counts.set_index('發布時間'))182 183        st.subheader("基本統計")184        st.write(f"- 總筆數: {len(st.session_state.df)}")185        st.write(f"- 不同法條類型數量: {st.session_state.df['法條類型'].nunique()}")186        st.write(f"- 平均條文長度: {st.session_state.df['條文'].str.len().mean():.1f} 字元")187 188# 頁腳189st.markdown("---")190st.markdown("### 使用說明")191st.markdown("""1921. 在側邊欄設定目標網址和要抓取的筆數1932. 點擊「開始抓取」按鈕進行資料抓取1943. 查看結果並下載資料1954. 使用「清除資料」按鈕清除當前結果196""")197