如何匯入Facebook專頁貼文至WordPress (2021)

使用Python抓取Fb專頁Posts的實踐應用例子

Chris K.Y. Fung
數碼文明推廣教室
9 min readJan 2, 2020

--

使用Python抓取Fb專頁Posts的實踐應用例子 — 如何匯入Facebook專頁貼文至WordPress

本文於2021年7月20日已就 facebook-scraper v0.2.45 更新內容

最近在為一個慈善團體的客戶重建網站,需要把該組織的 Facebook Page 內容轉貼變成網站的文章。專頁上有多達超過 100 個 posts,使用 Copy & Paste 來人手複製貼上固然可以,但是將會是一份苦悶的工作。而且客戶期望轉到網站文章與 Facebook 貼文的標示相同的發佈日期,使得在手動操作上工序多,容易犯上人為錯誤。於是計劃通過編程一個簡單的自動化程式,去抓取 Facebook Page 上的帖文 Data,並格式化 (format) 成為可匯入 (importable) 網站系統的數據檔案。

理想的方案是透過利用 Facebook Graph API 去讀取專業上的資料,但客戶並不善長 IT,若要取得 Fb 專頁的 API 權限,又不能不費一番功夫。於是在此條件的折衷之下,選擇了不使用 API 的方法去處理。於是在 GitHub 上找到了 kevinzg/facebook-scraper 這個 Python Package,可以不用 API Key 來抓取 Facebook Page。我把編好了的 Python 腳本上載了到 Repl.it(@chriskyfung),名為 FbPage2WordPressXMLImport,你可以在這個雲端編碼平台上執行測試 (test run)。

套件依存 Package Dependency

打開 requirement.txt,你會看到

facebook-scraper

只需要這一個 package,Repl.it 在執行腳會時會自動下載並安裝其他的 Dependencies。

腳本說明

main.py 是主腳本程式檔。首先通過以下兩行程式導入所需的套件,

from datetime import datetime
from facebook_scraper import get_posts
import urllib

get_posts 是用來取得 Facebook 帖文的 function,而 urllib 將用於轉換字串成 URL。

設定變數

接著,指定需要抓取的 Facebook Page ID、抓取的頁數,以及匯出文章的標題字數及分類。以下使用了 Medium 的 Facebook 專頁為例子,

FBPAGE_ID = 'medium'  # 目標的Fb專頁名稱
NUMOFPAGES = 1 # 要抓取的Fb頁數
EXPORTFILE = '{}-fb-page-export.xml'.format(FBPAGE_ID) # 輸出檔名TITLELEN = 16 # 抽取為文章標題的字數
CATEGORY = 'Imported from Fb Page' # WP中的分類名稱
CATEGORY_SLUG = urllib.parse.quote_plus(CATEGORY) # 分類的slug
COOKIES = '.cookies.json' # JSON 格式 Cookie 文件的路徑

facebook-scraper v0.2.45 或以上需要使用者從 Facebook 導入瀏覽器工作階段的 Cookie,才能夠獲取登入狀態進行爬蟲。

在登錄 Facebook 後,您可以使用 EditThisCookie (Chrome)Cookie Quick Manager (Firefox) 等擴充套件從瀏覽器中提取 Cookie。

寫入XML標頭

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:wp="http://wordpress.org/export/1.2/">
<channel>
<wp:wxr_version>1.2</wp:wxr_version>

以上的<xml>、<rss>以<channel>標頭,必需包含在 WordPress 的 XML 匯入檔案,否則 XML 資料將不能被讀取進 WordPress 成為文章。

處理Fb專頁帖子資料並寫入成XML格式

這裡使用了 For-loop 逐一處理由 get_posts() 回傳 Facebook 貼文的資料,把post_idtextimagetime,以及 post_url 格式化並寫入檔案。分別被轉換成以下 WordPress 文章的屬性:

  • 文章標題 <title> — 由於 Facebook 帖子本身並沒有標題項目,因此摘取內文的開首部份代替。若內文長度超過上文提述的 TITLELEN,將會在被裁剪的字串之後加上省略號(...)。
  • 文章內容 <content:encoded> — 這裡需要使用 CDATA[] 來包裝 get_posts 所取得的文字。
  • 文章的slug <wp:post_name> — 為了方便追溯原來的 Facebook 貼文,我選擇了以 get_posts 所取得的 post_id。
  • 文章日期 <wp:post_date_gmt> — 因為 get_posts() 所取得是依 GMT 標準時間,利用這個 wp 屬性在匯入 WordPress 的時候就會依系統時區,正確地自動計算出要顯示的日期時間。
  • <!-- orig_fb_post_url …--> — 透過 XML 注釋保留 Facebook 貼文的 URL 在輸出文件之內,但不會被匯入 WordPress。

至於圖片,WordPress的 匯入文件格式有些怪誕,特式圖片(Featured Image)是填 SQL 內儲存的媒體 ID。我暫時未找到合適的屬性來填入媒體的 URL,所以透過 HTML tag 把 get_posts() 所取得的 image 插入到文章內容代替。每一篇貼文將被輸出至格式:

<item>
<title>text的首N個字...</title>
<content:encoded>
<![CDATA[<p><img src="image url"></p><p>text</p>]]>
</content:encoded>
<wp:post_name>post_id</wp:post_name>
<wp:post_date_gmt><![CDATA[time]]></wp:post_date_gmt>
<wp:status><![CDATA[draft]]></wp:status>
<wp:comment_status><![CDATA[open]]></wp:comment_status>
<wp:post_type><![CDATA[post]]></wp:post_type>
<category domain="category" nicename="CATEGORY_SLUG">
<![CDATA[CATEGORY]]></category>
<!-- orig_fb_post_url="post_url" -->
</item>

在這裡再補充 wp:status 屬性,用以把 <item> 匯入成為「草稿狀態,以及 category屬性將文章歸納到自訂義的 WP 分類之下,方便再修訂文章及審核之後才正式公開發佈至網站上。

寫入XML結尾

    </channel>
</rss>

配合 XML 的標頭,在文件結尾寫入以上編號。運行 Python 腳本之後,就可以把產生的 XML 文件儲存到你的電腦上,然後使用 WordPress 的匯入工具測試一下是否成功添加文章。

此程式的局限性

  1. 無法直接上載圖片至 WordPress。
  2. facebook-scraper 並不能指定要抓取日期範圍,它只能從專頁由最新貼文開始逐頁向下捲動抓取舊的貼文。若在中途發生錯誤,則無法抓取到更之前的貼文。

最新版本原始碼:

生成的可匯入 WordPress 檔案 (樣本):

如果您喜歡這篇文章,請為此文章 👏 👏 👏 👏 👏 👏 👏,並分享至你的 Facebook 及 Twitter。

假如您有任何疑問或建議,歡迎標註留言或透過 Facebook 專頁 聯繫我 🙂

--

--

Chris K.Y. Fung
數碼文明推廣教室

📝集中分享提升生產力、自動化至開發等技能📢📈 博客及開發人員,於香港理工大學MPhil畢業,並多年在大學從事學術研究,喜歡學習多元化知識和技術。歡迎訂閱・標註回應,共享交流啟發性話題🐱‍🏍 about.me/chriskyfungfb.com/chriskyfung 😪📘