Linux中國

用 Python 構建你自己的 RSS 提示系統

人生苦短,我用 PythonPython 是非常棒的快速構建應用程序的編程語言。在這篇文章中我們將學習如何使用 Python 去構建一個 RSS 提示系統,目標是使用 Fedora 快樂地學習 Python。如果你正在尋找一個完整的 RSS 提示應用程序,在 Fedora 中已經準備好了幾個包。

Fedora 和 Python —— 入門知識

Python 3.6 在 Fedora 中是默認安裝的,它包含了 Python 的很多標準庫。標準庫提供了一些可以讓我們的任務更加簡單完成的模塊的集合。例如,在我們的案例中,我們將使用 sqlite3 模塊在資料庫中去創建表、添加和讀取數據。在這個案例中,我們試圖去解決的是這樣的一個特定問題,在標準庫中沒有包含,而有可能已經有人為我們開發了這樣一個模塊。最好是使用像大家熟知的 PyPI Python 包索引去搜索一下。在我們的示例中,我們將使用 feedparser 去解析 RSS 源。

因為 feedparser 並不是標準庫,我們需要將它安裝到我們的系統上。幸運的是,在 Fedora 中有這個 RPM 包,因此,我們可以運行如下的命令去安裝 feedparser:

$ sudo dnf install python3-feedparser

我們現在已經擁有了編寫我們的應用程序所需的東西了。

存儲源數據

我們需要存儲已經發布的文章的數據,這樣我們的系統就可以只提示新發布的文章。我們要保存的數據將是用來辨別一篇文章的唯一方法。因此,我們將存儲文章的標題和發布日期。

因此,我們來使用 Python sqlite3 模塊和一個簡單的 SQL 語句來創建我們的資料庫。同時也添加一些後面將要用到的模塊(feedparse,smtplib,和 email)。

創建資料庫

#!/usr/bin/python3
import sqlite3
import smtplib
from email.mime.text import MIMEText

import feedparser

db_connection = sqlite3.connect('/var/tmp/magazine_rss.sqlite')
db = db_connection.cursor()
db.execute(' CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)')

這幾行代碼創建一個名為 magazine_rss.sqlite 文件的新 sqlite 資料庫,然後在資料庫創建一個名為 magazine 的新表。這個表有兩個列 —— titledate —— 它們能存諸 TEXT 類型的數據,也就是說每個列的值都是文本字元。

檢查資料庫中的舊文章

由於我們僅希望增加新的文章到我們的資料庫中,因此我們需要一個功能去檢查 RSS 源中的文章在資料庫中是否存在。我們將根據它來判斷是否發送(有新文章的)郵件提示。Ok,現在我們來寫這個功能的代碼。

def article_is_not_db(article_title, article_date):
    """ Check if a given pair of article title and date
    is in the database.
    Args:
        article_title (str): The title of an article
        article_date  (str): The publication date of an article
    Return:
        True if the article is not in the database
        False if the article is already present in the database
    """
    db.execute("SELECT * from magazine WHERE title=? AND date=?", (article_title, article_date))
    if not db.fetchall():
        return True
    else:
        return False

這個功能的主要部分是一個 SQL 查詢,我們運行它去搜索資料庫。我們使用一個 SELECT 命令去定義我們將要在哪個列上運行這個查詢。我們使用 * 符號去選取所有列(titledate)。然後,我們使用查詢的 WHERE 條件 article_titlearticle_date 去匹配標題和日期列中的值,以檢索出我們需要的內容。

最後,我們使用一個簡單的返回 True 或者 False 的邏輯來表示是否在資料庫中找到匹配的文章。

在資料庫中添加新文章

現在我們可以寫一些代碼去添加新文章到資料庫中。

def add_article_to_db(article_title, article_date):
    """ Add a new article title and date to the database
    Args:
        article_title (str): The title of an article
        article_date (str): The publication date of an article
    """
    db.execute("INSERT INTO magazine VALUES (?,?)", (article_title, article_date))
    db_connection.commit()

這個功能很簡單,我們使用了一個 SQL 查詢去插入一個新行到 magazine 表的 article_titlearticle_date 列中。然後提交它到資料庫中永久保存。

這些就是在資料庫中所需要的東西,接下來我們看一下,如何使用 Python 實現提示系統和發送電子郵件。

發送電子郵件提示

我們使用 Python 標準庫模塊 smtplib 來創建一個發送電子郵件的功能。我們也可以使用標準庫中的 email 模塊去格式化我們的電子郵件信息。

def send_notification(article_title, article_url):
    """ Add a new article title and date to the database

    Args:
        article_title (str): The title of an article
        article_url (str): The url to access the article
    """

    smtp_server = smtplib.SMTP('smtp.gmail.com', 587)
    smtp_server.ehlo()
    smtp_server.starttls()
    smtp_server.login('your_email@gmail.com', '123your_password')
    msg = MIMEText(f'nHi there is a new Fedora Magazine article : {article_title}. nYou can read it here {article_url}')
    msg['Subject'] = 'New Fedora Magazine Article Available'
    msg['From'] = 'your_email@gmail.com'
    msg['To'] = 'destination_email@gmail.com'
    smtp_server.send_message(msg)
    smtp_server.quit()

在這個示例中,我使用了谷歌郵件系統的 smtp 伺服器去發送電子郵件,在你自己的代碼中你需要將它更改為你自己的電子郵件服務提供者的 SMTP 伺服器。這個功能是個樣板,大多數的內容要根據你的 smtp 伺服器的參數來配置。代碼中的電子郵件地址和憑證也要更改為你自己的。

如果在你的 Gmail 帳戶中使用了雙因子認證,那麼你需要配置一個密碼應用程序為你的這個應用程序提供一個唯一密碼。可以看這個 幫助頁面

讀取 Fedora Magazine 的 RSS 源

我們已經有了在資料庫中存儲文章和發送提示電子郵件的功能,現在來創建一個解析 Fedora Magazine RSS 源並提取文章數據的功能。

def read_article_feed():
    """ Get articles from RSS feed """
    feed = feedparser.parse('https://fedoramagazine.org/feed/')
    for article in feed['entries']:
        if article_is_not_db(article['title'], article['published']):
            send_notification(article['title'], article['link'])
            add_article_to_db(article['title'], article['published'])

if __name__ == '__main__':
    read_article_feed()
    db_connection.close()

在這裡我們將使用 feedparser.parse 功能。這個功能返回一個用字典表示的 RSS 源,對於 feedparser 的完整描述可以參考它的 文檔

RSS 源解析將返回最後的 10 篇文章作為 entries,然後我們提取以下信息:標題、鏈接、文章發布日期。因此,我們現在可以使用前面定義的檢查文章是否在資料庫中存在的功能,然後,發送提示電子郵件並將這個文章添加到資料庫中。

當運行我們的腳本時,最後的 if 語句運行我們的 read_article_feed 功能,然後關閉資料庫連接。

運行我們的腳本

給腳本文件賦於正確運行許可權。接下來,我們使用 cron 實用程序去每小時自動運行一次我們的腳本。cron 是一個作業計劃程序,我們可以使用它在一個固定的時間去運行一個任務。

$ chmod a+x my_rss_notifier.py
$ sudo cp my_rss_notifier.py /etc/cron.hourly

為了使該教程保持簡單,我們使用了 cron.hourly 目錄每小時運行一次我們的腳本,如果你想學習關於 cron 的更多知識以及如何配置 crontab,請閱讀 cron 的 wikipedia 頁面

總結

在本教程中,我們學習了如何使用 Python 去創建一個簡單的 sqlite 資料庫、解析一個 RSS 源、以及發送電子郵件。我希望通過這篇文章能夠向你展示,使用 Python 和 Fedora 構建你自己的應用程序是件多麼容易的事。

這個腳本在 GitHub 上可以找到。

via: https://fedoramagazine.org/never-miss-magazines-article-build-rss-notification-system/

作者:Clément Verna 譯者:qhwdw 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國