iT邦幫忙

2025 iThome 鐵人賽

DAY 10
0
生成式 AI

一起來打造 PTT 文章智慧問答系統!系列 第 10

【Day 10】使用 Celery + Redis 建立非同步排程 - 建立 Celery 設定與任務

  • 分享至 

  • xImage
  •  

Hi大家好,
這是我參加 iT 邦幫忙鐵人賽的第 1 次挑戰,這次的主題聚焦在結合 Python 爬蟲、RAG(檢索增強生成)與 AI,打造一套 PTT 文章智慧問答系統。在過程中,我會依照每天進度上傳程式碼到 GitHub ,方便大家參考學習。也歡迎留言或來信討論,我的信箱是 gerryearth@gmail.com


在前一天的進度中,我們已經成功讓 Django 專案能透過 Celery + Redis 執行背景任務,並且驗證了整個環境運作正常。

接下來,我們要更進一步,將 Celery 完整整合進 Django 專案,讓它在專案啟動時就自動載入,並且能方便地呼叫各種非同步任務。

今天的重點會放在建立專案層級的 Celery 設定檔,並將我們的 PTT 爬蟲功能轉換成 Celery 任務,讓資料能自動寫入資料庫,為後續的智慧問答系統打下基礎。


今日目標

  • 整合 Django 與 Celery

在 Django 專案中建立 Celery 設定

接下來我們要建立並註冊 Celery 任務系統,讓 Django 專案能正確初始化與使用背景任務。

一、在專案目錄下建立 celery.py

ptt_rag_dev/celery.py :

from celery import Celery
import os
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ptt_rag_dev.settings')
django.setup()

app = Celery("ptt_rag_dev", broker="redis://redis:6379/0", backend="redis://redis:6379/0")
app.autodiscover_tasks()

這個檔案是整個 Celery 的「進入點」,它的作用是:

  1. 設定 Celery 要讀取哪個 Django 專案的設定(DJANGO_SETTINGS_MODULE
  2. 建立一個 Celery 實例(app = Celery(...)
  3. 讓 Celery 自動搜尋 Django 各個 app 裡的任務(app.autodiscover_tasks()

這樣 Celery 才知道你在哪裡定義了任務(例如 @shared_task

二、在 __init__.py 載入 celery

ptt_rag_dev/__init__.py

from .celery import app as celery_app

__all__ = ['celery_app']

這是為了當你執行 Django 的任何指令(像是啟動伺服器、執行 shell)時,Celery 就會跟著初始化,確保:

  • Celery 任務會被註冊到 Django 專案中
  • 你在其他地方可以直接使用 celery_app

建立爬蟲任務(Task)

因為我們前面測試過爬蟲沒問題了,我們接下來可以把程式碼改成用一個任務就把 ptt 文章寫進資料庫。
首先請把 scraper.pyptt_scrape 改為:

def ptt_scrape(board: str) -> list:
    board_url = 'https://www.ptt.cc/bbs/' + board + '/index.html'  # 首先建立看板網址
    board_html = get_html(board_url)  # 由看板網址取得 html
    article_urls = get_urls_from_board_html(board_html)  # 由看板 html 取得文章網址
    article_id_list=[]
    for article_url in article_urls:
        article_html = get_html(article_url)  # 由文章網址取得 html
        article_data = get_data_from_article_html(article_html)  # 由文章 html 取得文章資訊
        article = Article.objects.create(
            board=board,
            title=article_data["title"],
            author=article_data["author"],
            url=article_url,
            content=article_data["content"],
            post_time=article_data["post_time"]
        )
        article_id_list.append(article.id)
    return article_id_list

並引入前天寫好的 Article:

from article.models import Article

目的是讓這個函式除了爬蟲之外還能順便寫入資料,並回傳寫入資料的 id ,而這個 article_id_list 在幾天之後會說明它的用途。

改好之後可以測試一下資料有沒有寫入成功:

if __name__ == "__main__":
    ptt_scrape('Gossiping')
    print('完成所有寫入!')

明天【Day 11】使用 Celery + Redis 建立非同步排程 - 實作 Celery Beat,我們將要進一步讓爬蟲「自動化」!


上一篇
【Day 09】認識 Celery & Redis - 認識、安裝與設定 Celery 與 Redis
下一篇
【Day 11】使用 Celery + Redis 建立非同步排程 - 實作 Celery Beat
系列文
一起來打造 PTT 文章智慧問答系統!13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言