利用 Large Language Model (LLM) 審閱 iThome 鐵人賽投稿 – (2) 使用 ChatGPT 撰寫爬蟲程式

我很榮幸可以擔任 2023 iThome 鐵人賽的評審,這是我嘗試使用 LLM 審閱投稿的過程紀錄。這一篇說明怎麼用 ChatGPT 撰寫爬蟲程式,並且透過 Unix pipeline 將不同組件黏合在一起。

系列文章 2 / 5使用 LLM 審閱 iThome 鐵人賽

上一篇文章中,我們用 ChatGPT (with GPT-4) 驗證了「用 LLM 閱讀文章,提供摘要、評論,並檢查其中的錯誤」的可行性。接著只要複製貼上 5,732 篇文章……等等!

Working Jim Carrey

只要我的手速夠快!

對於程式設計師來說,「懶惰是一種美德」1,我們可以透過自動化來避免重複的任務。

程式自動化是指使用軟體程式來自動完成重複性高或常規性的任務,以減少人工操作。這種做法可以提高效率、準確度,並節省時間。例如,自動化可以用於數據分析、檔案管理、系統監控,或是網頁爬蟲等應用。透過撰寫程式碼,可以讓電腦自動執行這些任務,不需要人為不斷重複相同的操作。這也意味著可以將人力資源轉移到更需要創造性和策略性思考的工作上。 – ChatGPT

我認識不少人,他們常常因為對技術感到陌生,就幫自己貼上「非程式設計師」的標籤。儘管 ChatGPT 能提供幫助,但他們認為每次都需複製貼上,對於不複雜的問題,手動處理會更快。當提到透過學習程式設計來解決這些問題時,他們經常以消極的「我學不會」態度回應,這種心態不知不覺中限制了他們的成長。

然而,我認為 LLM 為對話式介面帶來了革命性的變化:**只要會提問,就能得到答案。**即使你不懂程式語言,ChatGPT 也能指導甚至代為編寫。特別是其 Code Interpreter 功能不僅能執行程式碼,遇到錯誤時還會嘗試修正,大大提高解決問題的效率。

Simon Willison(Django 網頁框架的共同作者)說 ChatGPT Code Interpreter 的正確名稱應該是「ChatGPT 編碼實習生 (ChatGPT Coding Intern)」。我認為 ChatGPT 為不熟悉程式語言的人打開了新世界的大門。

ChatGPT Coding Intern

Source: Open questions for AI engineering by Simon Willison


撰寫爬蟲程式

注意:使用爬蟲程式時,我們必須嚴格遵守法律規範,避免侵犯版權,尊重網站的隱私政策,並注意流量管理,以免對目標網站造成壓力。

我已經事先通知主辦單位,會使用爬蟲及 AI 來自動化審閱流程。

為了順利使用 ChatGPT Coding Intern 撰寫爬蟲程式,您需要掌握以下知識,而這些都可以透過詢問 ChatGPT 來獲得:

  • HTML 原始碼的基本結構。
  • Python 程式的執行方式。
  • Python 中用於網頁抓取的套件,例如 Beautiful Soup。
  • 瞭解 robots.txt 協定

文章爬蟲程式

我們來看看 iThome 的文章頁面。以同樣是今年 iThome 鐵人賽冠軍作品「為你自己學 Ru…..st」為例,打開第一篇「[為你自己學 Rust] 前言」這篇文章後,使用瀏覽器的 Inspector 功能,你會發現我們所需的內容都位於名為 qa-panel__contentdiv 元素內:

Inspector

用 Inspector 看看 iThome 網頁原始碼的長相

使用 ChatGPT Coding Intern 撰寫網路爬蟲程式的步驟如下:

  1. 上傳網頁的 HTML 原始碼,並讓 ChatGPT 分析指定的 HTML 區塊(以這裡來說是 qa-panel__content),這樣它才「真正看過」,以便後續的資訊提取。
  2. 指定要抓取的資訊。因為 ChatGPT 的理解能力,我不用指定每個 HTML 區塊的位置,只要說「取得文章標題、系列名稱、作者名稱、文章內容」並驗證輸出結果。
  3. 根據前兩步的資料,指示 ChatGPT 撰寫完整的爬蟲程式碼。

大概五分鐘就可以寫好一個文章爬蟲程式啦~具體操作步驟可以看我的 ChatGPT 對話範例

文章列表爬蟲程式

我們可以用文章爬蟲程式,輕鬆地取得單篇文章的內容。然而,一個系列文章通常包含至少 30 篇文章,為了有效取得這些文章,我們需要再撰寫一個文章列表爬蟲程式,以抓取整個系列中所有文章的網址。

作法跟撰寫文章爬蟲程式大致相同,具體操作步驟可以看我的 ChatGPT 對話範例

spider icon

用 DALL·E 畫的爬蟲圖示

最後我再透過 ChatGPT 稍作修改,讓文章爬蟲程式把抓取的資訊存到目錄下的 data/{系列名稱}/{文章標題}.json 檔案裡,以便後續使用。

目前我們已經有兩個 Python 程式:

  • article_scraper.py 是文章爬蟲程式
  • series_scraper.py 是文章列表爬蟲程式。

你可以看看這兩支程式的完整程式碼

小技巧

如果你用 ChatGPT 撰寫程式,但是看不太懂它在做什麼的話,可以把程式碼再貼給 ChatGPT,讓他逐行加上註解:

我是一個 Python 程式語言新手,請說明這個程式的用途,並且幫我逐行加上註解

使用「膠水」黏合程式

想像一下,如果今天我們要打造一個網站,這就像是在組裝一個複雜的機器,需要精心設計每一部分。但有時,我們面對的任務並不需要這麼複雜的構建 — 比如說,僅僅是爬取一些網頁資料。在這種情況下,我們可以用一種更簡單、更直接的方式來處理: Unix 的 pipeline

Unix pipeline 用一個簡單的 | 符號表示,它讓我們可以將多個簡單的指令連接起來,形成一個資料處理鏈。每個指令處理一小部分工作,然後將其輸出傳遞給下一個指令。這就像用「膠水」將不同的組件黏合在一起,每個組件完成它的任務,然後將結果傳遞給下一個組件。

在我們的案例中,只需要以下幾個工具:

  • Unix 的 cat, xargs 兩個指令。
  • jq:一個在 Unix 下處理 JSON 的工具。

來看一下我們的指令:

cat series.txt | xargs -I {} sh -c " \
  python series_scraper.py {} | \
  jq -r '.[].link' | \
  xargs -I % sh -c 'python article_scraper.py %; sleep 5' \
"

這條指令的作用是:

  1. 讀取列表文件(cat series.txt:這個指令讀取了包含所有目標文章網址的 series.txt 文件。
  2. 對列表中的每一項進行操作(xargs -I {} sh -c "...":接下來,對於文件中的每一行,這個指令都會執行一些操作,並用 pipeline 的膠水將它們黏合在一起。
  3. 從每個系列中抓取文章鏈接(python series_scraper.py {}:這裡,我們對每個系列文章網址執行 series_scraper.py 程式,它會去抓取這個系列文章中所有的文章網址,匯出一個 JSON 格式。
  4. 提取文章鏈接(jq -r '.[].link':利用 jq 這個強大的工具,我們從上一步匯出的 JSON 中提取出所需的文章網址,就像用膠水精準地連接兩個部件。
  5. 抓取每篇文章的內容(python article_scraper.py %; sleep 5:最後,對於每一個提取出的文章網址,我們執行 article_scraper.py 程式來獲取文章內容。在抓取完一篇文章後,這個指令會暫停 5 秒,然後再處理下一篇文章,這樣做可以避免因為訪問過於頻繁而被網站封鎖。

最終,當這一串指令執行完畢之後,我就得到了 173 份系列文章的完整資料了。

downloaded folders

173 份系列文章,目錄裡面是每篇文章的 JSON 檔案

前置作業完成,可以準備用 AI 改考卷啦! 🎊


如果這篇文章對你有幫助,請按讚、分享、訂閱,也歡迎線上刷卡請我喝咖啡。也歡迎造訪我的個人網站

1

Larry Wall(Perl 程式語言的原作者)在《Programming Perl》這本書中提到程式設計師的三大美德。這邊的懶惰是一種「高級懶」,指的是通過自動化來避免不必要的重複勞動。這種懶惰意味著你不僅僅是想著要懶惰,而是思考著如何從現在開始,一直懶惰到可預見的未來。例如,程式設計師可能會開發一個腳本,來自動完成某些繁瑣的資料處理任務,從而釋放更多時間進行創新或解決更複雜的問題。