[Rails] Capybara 搭配 Nokogiri 動態網站爬蟲 Web Scraping & Parsing
前言
最近碰到了一個與動態爬蟲有關的功能需求,順便筆記一下 2019 年在 RoR 上動態爬蟲的方案之一: Capybara + Nokogiri
Nokogiri
Nokogiri 是 Rails 內用來爬取標籤文件(例如:HTML、XML)的套件,大部分的 RoR 實作爬蟲的方式就是使用這個套件,但因為現代網頁的內容通常不會直接定義在 HTML 內了,所以光是會靜態網站爬蟲已經很難爬到想要的資料了
Capybara
Capybara 原本是用來做 integration test 的套件,但它的 browser 模擬也很適合用來搭配 Nokogiri 做動態爬蟲
Step 1: 搭建環境
首先開啟一個新的 Rails 專案並在 Gemfile 加入以下套件,Capybara 在 Gemfile 內原本就有定義了,但因為他放在 test 環境內,所以要移出來其他環境使用
gem 'selenium-webdriver'gem 'capybara'gem 'webdrivers' # 讓使用 driver 變得更方便
然後新增一個 initializer,設為 selenium 方便在開發的時候觀察網頁模擬操作的情形
可以把 driver 設為 headless 讓爬蟲能在 server 上運行,而且執行起來很快,無負擔,詳細設定在:https://thoughtbot.com/blog/headless-feature-specs-with-chrome
Step 2: 了解目標網頁的行為觸發
大俠,平日閒暇時間多使用 chrome 的開發模式觀察網頁內容
所謂知己知彼,百戰百勝啊 🤷♀️🤷♂️
設定完 Capybara 後,就可以來爬蟲了🐞,本篇以台大醫院的看診進度的分頁為例,網址如下:https://reg.ntuh.gov.tw/webadministration/ClinicCurrentLightNoByDeptCode.aspx
Step 2–1: 網頁元件
進入連結後,會看到以下四個元件
- 3 個選擇列表
- 1 個查詢按鈕
這個分頁只有一個功能,選擇了醫院、科別與時間後就會自動查詢,不過只要選擇科部後就會自動 render 出該科部的內容了,因為該元件中 onchange()
定義如下
另外該元件的 id 為 SelectHospDeptAndAMPM_DropDownDept
Step 2–2: 行為觸發
當在 --選擇科部--
中選擇內科部後,頁面會自動 render 出該科別所有門診的看診進度
Step 3: 寫程式模擬行為
Step 3–1: Capybara 模擬瀏覽器行為
- Capybara browser, driver 宣告
- 造訪網頁
- 在
--選擇科別--
選擇內科部(id 在前個步驟有說明,如果忘記了請往上找)
Step 3–2: 使用 Nokogiri 爬取網站內容
3–1 做完,執行時已經可以看到網頁出現 2–2 中的畫面了,接下來我們要用 nokogiri 來爬我們需要的內容
使用 driver
中的 page_source
取得 HTML 內容,然後再使用標籤中的 css 輔助查找需要的元件與元件內容,過程我就不贅述了,在開發模式找一找就好~
執行上面兩段程式碼會得到以下四個結果
- 98 診
- 主治醫師
- 醫師約診
nil
(因為現在是空號)
功能實作到此完結撒花🎊 🎉
後記
是不是 Hen 簡單呢,既然提到 Capybara 小弟就順便分享一下我曾踩過的兩個雷
- 有些元件被包太緊會找不到,要一層一層一層剝開它的心
- 在 selenium chrome(non-headless) 模式中曾經遇到預設開啟的視窗太小,所以找不到元件,可以的話在設定裡面定義一下應該能避免~
覺得文章不錯的話歡迎分享與追蹤我的個人帳號
順便拍拍手👏👏👏
謝謝🙇♂️