• flask 平台如何產生rss.xml

  •     
    推文至Facebook  
  •      觀看次數:92
  • 要在flask平台產生rss.xml
    為什麼要rss.xml?
    這是SEO的需要,方便網路爬蟲尋找並收錄
    YAHOO或GOOGLE才方便收錄



    如在public_html/rss目錄產生rss.xml
    這時需要到資料庫撈取相關資料並產生檔案
    但是內文會有html格式,所以要去除


    在頭部加入

    import traceback
    import re
    import html

     


    加一個function產生rss.xml

    def clean_html(raw_html):
        if not raw_html:
            return ""
        # 1. 將 HTML 實體字元(例如  , &, <)還原為正常文字
        unescaped_text = html.unescape(raw_html)
        # 2. 利用正則表達式清除所有 <...> 格式的 HTML 標籤
        clean_re = re.compile('<.*?>')
        clean_text = re.sub(clean_re, '', unescaped_text)
        # 3. 去除前後多餘的空白與換行
        return clean_text.strip()

    @app.route("/admin/addrss", methods=['GET', 'POST'])
    def addrss():
        conn = check_db_connection()
        cursor = conn.cursor(dictionary=True)
        list_apps = list_app()

        if session.get('uid') is None or session.get('shell') is None:
            session['message'] = "你無權限操作!"
            return redirect(url_for('admin_index', message=session['message']))

        try:
            # 1. 撈取最新的消息 (從你現有的 net_config 資料表)
            config_sql = "SELECT * FROM `net_config` WHERE id='1'"
            cursor.execute(config_sql)
            configs = cursor.fetchone()

            # 🔔 注意:你原本這段的 channel 變數是在下面才宣告的,這裡提早使用會導致 NameError!
            # 為了測試,我們先宣告 rss 與 channel
            rss = ET.Element("rss", version="2.0")
            channel = ET.SubElement(rss, "channel")

            # 網站基本資訊
            title = ET.SubElement(channel, "title")
            title.text = configs['webname']

            link = ET.SubElement(channel, "link")
            link.text = configs['weburl']

            description = ET.SubElement(channel, "description")
            description.text = configs['webdis']

            # 撈取最新的消息
            sql = "SELECT * FROM net_state ORDER BY hid DESC"
            cursor.execute(sql)
            state_list = cursor.fetchall()

            language = ET.SubElement(channel, "language")
            language.text = "zh-tw"

            # 逐筆加入 Item
            for state in state_list:
                item = ET.SubElement(channel, "item")
                item_title = ET.SubElement(item, "title")
                item_title.text = state['subject']

                item_link = ET.SubElement(item, "link")
                item_link.text = f"{configs['weburl']}/state?hid={state['hid']}"

                item_desc = ET.SubElement(item, "description")
                item_desc.text = clean_html(state['content'])

                item_guid = ET.SubElement(item, "guid", isPermaLink="true")
                item_guid.text = f"{configs['weburl']}/state?hid={state['hid']}"

            # 格式化 XML
            raw_xml = ET.tostring(rss, encoding="utf-8")
            parsed_xml = minidom.parseString(raw_xml)
            pretty_xml = parsed_xml.toprettyxml(indent="  ", encoding="utf-8")

            # 寫入檔案
            base_dir = "/home/flow/public_html"
            rss_dir = os.path.join(base_dir, "rss")
            if not os.path.exists(rss_dir):
                os.makedirs(rss_dir, exist_ok=True)

            rss_file_path = os.path.join(rss_dir, "rss.xml")
            with open(rss_file_path, "wb") as f:
                f.write(pretty_xml)

            echo_message = "<script>alert('RSS.XML 檔案已成功寫入 /public_html/rss/rss.xml!');</script>"
            return redirect(url_for('admin_main', echo_message=echo_message))

        except Exception as e:
            # ─── 🛠️ DEBUG 機制:如果出錯,直接在網頁上印出最詳細的報錯行數 ───
            error_class = e.__class__.__name__  # 取得錯誤類型
            detail = e.args[0] if e.args else ""  # 取得詳細內容
            cl, exc, tb = sys.exc_info()  # 取得 Call Stack
            last_call_stack = traceback.extract_tb(tb)[-1]  # 取得最後出錯的那一行
            file_name = last_call_stack[0]  # 檔案名稱
            line_num = last_call_stack[1]  # 錯誤行數
            func_name = last_call_stack[2]  # 函數名稱

            # 拼湊成網頁看得懂的 Error Traceback
            full_traceback = traceback.format_exc()

            # 直接回傳錯誤訊息,中斷跳轉,讓你在畫面上能直接看見
            debug_html = f"""
            <div style="background-color: #ffebee; color: #c62828; padding: 20px; border: 2px solid #ef5350; font-family: monospace; border-radius: 5px; margin: 20px;">
                <h2 style="margin-top: 0;">❌ 偵測到程式執行錯誤 (Debug Mode)</h2>
                <p><b>錯誤檔案:</b> {file_name}</p>
                <p><b>出錯行數:</b> 第 <span style="font-size: 20px; font-weight: bold; background: yellow; padding: 2px 6px; border-radius: 3px;">{line_num}</span> 行</p>
                <p><b>觸發函數:</b> {func_name}()</p>
                <p><b>錯誤類型:</b> {error_class}: {detail}</p>
                <hr style="border: 1px solid #ef5350;">
                <h3>完整 Traceback 錯誤日誌:</h3>
                <pre style="background: #263238; color: #eceff1; padding: 15px; overflow: auto; border-radius: 4px; font-size: 14px;">{full_traceback}</pre>
                <br>
                <a href="javascript:history.back()" style="background: #c62828; color: white; padding: 10px 15px; text-decoration: none; border-radius: 4px;">返回上一頁</a>
            </div>
            """
            return make_response(debug_html, 500)

        finally:
            conn.close()

     



    這樣就能在該網址的/rss/rss.xml看到該檔案了
    flask, rss

  • flask, rss
  • 相關文章:
NetYea 客服 NetYea 客服
NetYea 客服