# Playwright 離線爬 OB
Playwright 可以通過結合排程工具和離線運行模式實現自動化任務。例如,你可以使用 **Node.js** 的排程工具(如 `node-cron`)來定期執行 Playwright 腳本,並且 Playwright 可以在無頭模式下(`headless` 模式)運行,這意味著它可以在沒有顯示器的情況下(如伺服器或雲端)離線運行。
### 使用 `node-cron` 排程 Playwright 腳本
`node-cron` 是一個簡單易用的 Node.js 排程工具,可以幫助你定期執行 Playwright 爬蟲或自動化任務。
#### 步驟
1. **安裝必要套件**
- 安裝 `playwright` 和 `node-cron`:
```bash
npm install playwright node-cron
```
2. **撰寫 Playwright 爬蟲代碼**
下面是一個結合 `node-cron` 來定期執行 Playwright 爬蟲並抓取網頁數據的範例:
```javascript
const { chromium } = require('playwright');
const cron = require('node-cron');
// 定義一個爬蟲函數
async function runScraper() {
// 啟動無頭模式的 Chromium 瀏覽器
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
// 打開目標網站
await page.goto('https://example.com');
// 抓取 h1 標籤的文字內容
const headingText = await page.$eval('h1', el => el.textContent);
console.log('Page heading:', headingText);
// 關閉瀏覽器
await browser.close();
}
// 設定排程,每天的早上 9:00 執行一次爬蟲
cron.schedule('0 9 * * *', () => {
console.log('Running scheduled task...');
runScraper().catch(console.error); // 執行爬蟲
});
console.log('Cron job scheduled. Waiting for the next run...');
```
#### 3. 配置 `cron` 表達式
`node-cron` 使用標準的 **cron 表達式**來定義排程。這是一些常見的時間排程範例:
- `* * * * *`:每分鐘執行一次。
- `0 9 * * *`:每天早上 9 點執行一次。
- `0 */2 * * *`:每兩小時執行一次。
- `0 0 * * MON`:每周一的午夜執行一次。
你可以根據需求修改表達式以自動執行 Playwright 腳本。
### Playwright 離線模式的實現
當 Playwright 使用 `headless: true` 啟動瀏覽器時,它運行在無頭模式下,這意味著它不會顯示任何瀏覽器界面,可以離線運行在無顯示器的環境中,例如伺服器或雲端平台上。
#### 步驟
1. **運行在本地伺服器或雲伺服器**:你可以將 Playwright 腳本部署到雲端伺服器(如 AWS、Google Cloud、DigitalOcean)或是家中的 Raspberry Pi 等設備上。
2. **使用無頭模式運行**:確保 Playwright 瀏覽器是以無頭模式(`headless: true`)運行,這樣就不需要顯示器,適合在無 UI 的環境中執行。
```javascript
const browser = await chromium.launch({ headless: true });
```
### 延伸功能:將數據保存到本地或資料庫
你可以擴展這個腳本,使其不僅能夠排程執行,還能將爬取到的數據存儲到文件或資料庫中。以下是一些常見的操作:
1. **保存數據到文件**:
```javascript
const fs = require('fs');
async function saveDataToFile(data) {
fs.writeFileSync('scraped_data.txt', data, 'utf8');
console.log('Data saved to scraped_data.txt');
}
async function runScraper() {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com');
const headingText = await page.$eval('h1', el => el.textContent);
await saveDataToFile(headingText); // 儲存數據到文件
await browser.close();
}
```
2. **儲存數據到資料庫**:
如果你使用 MySQL、MongoDB 或其他資料庫,則可以將 Playwright 爬蟲的結果插入到資料庫中。請參考之前關於 Playwright 儲存數據到資料庫的範例。
### 使用 PM2 管理 Node.js 進程
如果你希望確保 Playwright 爬蟲腳本在伺服器重啟或出錯後能夠自動重新啟動,你可以使用 **PM2** 來管理 Node.js 應用程式。
1. 安裝 PM2:
```bash
npm install pm2 -g
```
2. 使用 PM2 啟動腳本:
```bash
pm2 start your-script.js
```
3. 查看 PM2 的排程狀態:
```bash
pm2 list
```
這樣,即使伺服器重啟或腳本發生錯誤,PM2 也能自動重新啟動你的爬蟲腳本,確保任務持續執行。
### 總結
1. **Playwright 支援無頭模式**,這讓它可以離線運行。
2. **使用 `node-cron`** 來排程定期執行的 Playwright 爬蟲任務。
3. **結合資料庫或文件系統**,將爬取的數據存儲起來。
4. 使用 **PM2** 等工具來管理 Node.js 應用程式,確保腳本穩定運行。
這種方式能夠實現定期執行爬蟲並在離線環境中實現自動化。
要從沒有 API 提供的資料庫(如 OB 資料庫)中爬取數據,可以通過自動化方式與資料庫的網頁界面進行互動來完成,但需要注意幾點:
1. **爬取可行性**:如果 OB 資料庫有網頁後台或管理介面且你可以登入,那麼可以使用 Playwright 這類工具來模擬人工操作,進行資料抓取。這種方法的成功率取決於網站的結構以及防爬機制。
2. **模擬登入**:通常無 API 的系統需要通過網頁登入才能進入資料庫管理介面。Playwright 可以幫助你模擬這一過程。
3. **資料爬取方式**:
- 如果資料庫資料是以表格、報表或其他 HTML 元素的形式呈現,Playwright 可以提取這些內容。
- 可以將抓取到的資料儲存到本地檔案或你的資料庫。
4. **排程執行**:如之前提到的,可以使用 `node-cron` 或其他排程工具來定期執行爬蟲操作。
### 如何爬取 OB 無 API 資料庫的數據
#### 1. 模擬登入
假設 OB 資料庫的登入頁面類似於其他傳統網站,以下是如何用 Playwright 模擬登入的一個範例:
```javascript
const { chromium } = require('playwright');
async function loginToOBDatabase() {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
// 前往登入頁面
await page.goto('https://ob-database-login-url.com');
// 填寫帳號和密碼
await page.fill('input[name="username"]', 'your-username');
await page.fill('input[name="password"]', 'your-password');
// 點擊登入按鈕
await page.click('button[type="submit"]');
// 等待重定向或登入後的特定元素
await page.waitForSelector('#dashboard'); // 假設登入後有 dashboard 元素
console.log('Login successful!');
// 後續的爬取操作放在這裡
// ...
// 關閉瀏覽器
await browser.close();
}
loginToOBDatabase();
```
#### 2. 爬取資料
一旦登入成功,你可以通過 Playwright 抓取表格、報表或其他數據。以下是一個範例,展示如何抓取表格數據:
```javascript
async function scrapeOBData() {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
// 登入後前往數據頁面
await page.goto('https://ob-database-url.com/data-page');
// 抓取表格中的數據
const data = await page.$$eval('table tr', rows => {
return rows.map(row => {
const columns = row.querySelectorAll('td');
return Array.from(columns).map(column => column.innerText);
});
});
console.log('Scraped data:', data);
// 關閉瀏覽器
await browser.close();
}
scrapeOBData();
```
#### 3. 排程執行
使用 `node-cron` 定期執行這個爬蟲腳本,如下所示:
```javascript
const cron = require('node-cron');
const { chromium } = require('playwright');
async function loginAndScrape() {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
// 登入流程...
await page.goto('https://ob-database-login-url.com');
await page.fill('input[name="username"]', 'your-username');
await page.fill('input[name="password"]', 'your-password');
await page.click('button[type="submit"]');
await page.waitForSelector('#dashboard');
// 抓取數據...
await page.goto('https://ob-database-url.com/data-page');
const data = await page.$$eval('table tr', rows => {
return rows.map(row => {
const columns = row.querySelectorAll('td');
return Array.from(columns).map(column => column.innerText);
});
});
console.log('Scraped data:', data);
// 關閉瀏覽器
await browser.close();
}
// 排程設定:每天的早上 9 點執行一次
cron.schedule('0 9 * * *', () => {
console.log('Running scheduled task...');
loginAndScrape().catch(console.error);
});
```
### 需要注意的挑戰
1. **登入驗證**:如果 OB 資料庫的登入頁面有驗證碼(CAPTCHA)或其他安全防護措施,爬蟲可能會變得更加困難。需要考慮手動輸入驗證碼或使用一些工具來繞過這些安全措施。
2. **反爬機制**:部分網站有防爬機制,如 IP 限制或頻繁請求的封鎖。你可能需要通過降低爬取頻率或使用代理來避免封禁。
3. **網站變動**:如果網站的結構或界面發生變動(例如,HTML 標籤結構或網址變化),你的爬蟲腳本需要進行調整。
4. **法律與合規問題**:在爬取網站數據時,務必遵守網站的使用條款和隱私政策,以確保不違反法律規定。
### 總結
1. **可行性**:可以通過 Playwright 爬取 OB 資料庫等無 API 的系統數據,只要你有權限登錄網頁界面並能夠模擬操作。
2. **技術細節**:透過模擬登入、抓取表格或報表數據,再結合 `node-cron` 排程,可以實現自動化的資料抓取。
3. **挑戰與解決方案**:注意應對可能的登入驗證和反爬機制,同時確保法律合規性。
這樣的方案既可以用於日常排程任務,也適用於長期自動化數據抓取工作。