化:低代碼構(gòu)建與API集成實(shí)戰(zhàn))
在自動(dòng)化測(cè)試、數(shù)據(jù)抓取和網(wǎng)頁交互腳本開發(fā)中你是否厭倦了手動(dòng)編寫和維護(hù)復(fù)雜的瀏覽器操作代碼當(dāng)業(yè)務(wù)需要模擬用戶登錄、表單提交、數(shù)據(jù)提取或頁面監(jiān)控時(shí)傳統(tǒng)的 Selenium 或 Puppeteer 腳本雖然強(qiáng)大但開發(fā)調(diào)試周期長(zhǎng)對(duì)非專業(yè)開發(fā)者門檻較高。Figranium的出現(xiàn)為這類場(chǎng)景提供了一種全新的解決方案通過可視化拖拽構(gòu)建瀏覽器任務(wù)流并通過標(biāo)準(zhǔn) API 一鍵執(zhí)行整個(gè)過程支持 Docker 容器化部署極大地簡(jiǎn)化了瀏覽器自動(dòng)化的工程實(shí)踐。本文將為你完整拆解 Figranium 的核心概念、架構(gòu)設(shè)計(jì)、從零開始的部署流程以及如何通過 API 集成到你的項(xiàng)目中。無論你是測(cè)試工程師、后端開發(fā)者還是需要處理網(wǎng)頁自動(dòng)化任務(wù)的數(shù)據(jù)分析師都能通過本文掌握一套高效、可復(fù)用的實(shí)戰(zhàn)方案。1. Figranium 是什么核心概念與價(jià)值1.1 可視化瀏覽器任務(wù)構(gòu)建器Figranium 的核心定位是一個(gè)“可視化瀏覽器任務(wù)構(gòu)建與執(zhí)行平臺(tái)”。你可以將其理解為一個(gè)低代碼/無代碼工具專門用于編排在瀏覽器中執(zhí)行的一系列操作。傳統(tǒng)方式使用 Python Selenium你需要編寫諸如find_element,click,send_keys的代碼并處理等待、iframe、彈窗等各種邊界情況。Figranium 方式在一個(gè)圖形化界面中通過拖拽預(yù)定義的“動(dòng)作塊”如“打開網(wǎng)頁”、“輸入文本”、“點(diǎn)擊元素”、“提取數(shù)據(jù)”并以連線的方式定義執(zhí)行流程。這大大降低了創(chuàng)建自動(dòng)化腳本的技術(shù)門檻。1.2 API 驅(qū)動(dòng)的任務(wù)執(zhí)行構(gòu)建好的任務(wù)流并不是在 Figranium 的界面上直接運(yùn)行。Figranium 將其封裝成可通過 HTTP API 調(diào)用的服務(wù)。這意味著解耦設(shè)計(jì)與執(zhí)行你可以在 Figranium 的 Web UI 中精心設(shè)計(jì)和調(diào)試你的任務(wù)流程。集成到任何系統(tǒng)任何能發(fā)送 HTTP 請(qǐng)求的程序你的后端服務(wù)、定時(shí)任務(wù)、命令行工具都可以通過調(diào)用 Figranium 提供的 API觸發(fā)一個(gè)或多個(gè)瀏覽器任務(wù)的執(zhí)行。標(biāo)準(zhǔn)化與復(fù)用任務(wù)被定義為可復(fù)用的“資產(chǎn)”通過 API 調(diào)用可以在不同場(chǎng)景、不同時(shí)間被反復(fù)執(zhí)行。1.3 Dockerized 部署“Dockerized”意味著 Figranium 被打包成了 Docker 鏡像。這帶來了幾個(gè)關(guān)鍵優(yōu)勢(shì)環(huán)境一致性避免了“在我機(jī)器上能跑”的經(jīng)典問題。無論是在開發(fā)、測(cè)試還是生產(chǎn)環(huán)境只要運(yùn)行同一個(gè) Docker 鏡像Figranium 的運(yùn)行環(huán)境就是完全一致的??焖俨渴鹨粭ldocker run命令即可啟動(dòng)全套服務(wù)通常包含前端 UI、后端 API 服務(wù)器和瀏覽器運(yùn)行環(huán)境。資源隔離與擴(kuò)展每個(gè) Figranium 實(shí)例運(yùn)行在獨(dú)立的容器中互不干擾。你可以輕松地通過 Docker Compose 或 Kubernetes 來編排多個(gè)實(shí)例以支持高并發(fā)任務(wù)執(zhí)行。1.4 解決什么問題降低自動(dòng)化門檻讓不擅長(zhǎng)編程的運(yùn)營(yíng)、產(chǎn)品人員也能創(chuàng)建簡(jiǎn)單的網(wǎng)頁自動(dòng)化流程。提升開發(fā)效率對(duì)于開發(fā)者可視化構(gòu)建可以快速原型驗(yàn)證省去大量樣板代碼的編寫。便于協(xié)作與維護(hù)任務(wù)流程以圖形化方式呈現(xiàn)邏輯一目了然比閱讀代碼更易于團(tuán)隊(duì)理解和維護(hù)。打造自動(dòng)化服務(wù)通過 API你可以將瀏覽器自動(dòng)化能力作為一項(xiàng)微服務(wù)提供給其他系統(tǒng)調(diào)用構(gòu)建更復(fù)雜的自動(dòng)化工作流。2. 環(huán)境準(zhǔn)備與部署指南在開始使用 Figranium 之前我們需要搭建其運(yùn)行環(huán)境。由于它是 Dockerized 的所以核心依賴就是 Docker 環(huán)境。2.1 基礎(chǔ)環(huán)境要求操作系統(tǒng)支持 Linux (推薦 Ubuntu/CentOS)、macOS 或 Windows (需安裝 Docker Desktop)。Docker版本 20.10.0 或更高。確保 Docker 服務(wù)已啟動(dòng)。Docker Compose版本 1.29.0 或更高如果使用 Compose 部署方式。Figranium 的部署通常需要協(xié)調(diào)多個(gè)容器Web UI、API Server、瀏覽器實(shí)例Compose 是最佳選擇。網(wǎng)絡(luò)服務(wù)器需要能訪問外網(wǎng)以便拉取 Docker 鏡像和任務(wù)中需要訪問的目標(biāo)網(wǎng)頁。硬件建議至少 2核 CPU4GB 內(nèi)存。運(yùn)行瀏覽器實(shí)例尤其是多個(gè)并發(fā)比較消耗資源。2.2 獲取 Figranium 部署文件通常開源項(xiàng)目會(huì)提供docker-compose.yml文件來定義服務(wù)。你需要從 Figranium 的官方代碼倉庫如 GitHub獲取這個(gè)文件。假設(shè)項(xiàng)目倉庫地址為https://github.com/figranium/figranium你可以通過以下命令獲取# 克隆倉庫如果提供 git clone https://github.com/figranium/figranium.git cd figranium/deploy # 進(jìn)入部署目錄 # 或者直接下載 docker-compose.yml 文件 curl -O https://raw.githubusercontent.com/figranium/figranium/main/docker-compose.yml重要提示由于 Figranium 是一個(gè)相對(duì)較新的 Show HN 項(xiàng)目其具體的倉庫地址和部署文件可能發(fā)生變化。請(qǐng)以項(xiàng)目官方文檔為準(zhǔn)。本文的示例基于此類項(xiàng)目的通用結(jié)構(gòu)。2.3 使用 Docker Compose 啟動(dòng)一個(gè)典型的docker-compose.yml文件可能如下所示version: 3.8 services: figranium-ui: image: figranium/ui:latest ports: - 3000:3000 environment: - API_SERVER_URLhttp://figranium-api:8080 depends_on: - figranium-api networks: - figranium-net figranium-api: image: figranium/api:latest ports: - 8080:8080 environment: - REDIS_URLredis://figranium-redis:6379 - BROWSER_WS_URLws://figranium-browser:3000 volumes: - ./data:/app/data depends_on: - figranium-redis - figranium-browser networks: - figranium-net figranium-browser: image: browserless/chrome:latest ports: - 3001:3000 environment: - CONNECTION_TIMEOUT60000 - MAX_CONCURRENT_SESSIONS10 networks: - figranium-net figranium-redis: image: redis:alpine ports: - 6379:6379 volumes: - redis-data:/data networks: - figranium-net networks: figranium-net: driver: bridge volumes: redis-data:服務(wù)說明figranium-ui可視化任務(wù)構(gòu)建器的前端界面運(yùn)行在 3000 端口。figranium-api核心 API 服務(wù)器接收任務(wù)執(zhí)行請(qǐng)求運(yùn)行在 8080 端口。它將任務(wù)數(shù)據(jù)持久化到掛載的./data目錄。figranium-browser使用browserless/chrome鏡像提供無頭 Chrome 瀏覽器環(huán)境供 API 服務(wù)器驅(qū)動(dòng)執(zhí)行任務(wù)。figranium-redisRedis 數(shù)據(jù)庫用于緩存任務(wù)狀態(tài)、管理隊(duì)列等。在包含docker-compose.yml的目錄下執(zhí)行以下命令啟動(dòng)所有服務(wù)# 啟動(dòng)服務(wù)后臺(tái)運(yùn)行 docker-compose up -d # 查看服務(wù)運(yùn)行狀態(tài) docker-compose ps # 查看實(shí)時(shí)日志 docker-compose logs -f figranium-api啟動(dòng)成功后你可以通過瀏覽器訪問http://你的服務(wù)器IP:3000來打開 Figranium 的可視化構(gòu)建界面。3. 核心功能與可視化構(gòu)建實(shí)戰(zhàn)3.1 初識(shí) Figranium 用戶界面訪問 UI (端口 3000) 后你通常會(huì)看到以下核心區(qū)域組件庫/動(dòng)作面板羅列所有可用的瀏覽器操作“塊”如“Navigate”導(dǎo)航、“Click”點(diǎn)擊、“Type”輸入、“Extract Text”提取文本、“Screenshot”截圖、“Condition”條件判斷、“Loop”循環(huán)等。畫布/工作區(qū)拖拽動(dòng)作塊到此區(qū)域并通過連線連接它們構(gòu)建任務(wù)流程圖。屬性/配置面板選中畫布上的某個(gè)動(dòng)作塊在此面板配置其具體參數(shù)如要導(dǎo)航的URL、要點(diǎn)擊的元素選擇器、要輸入的文本等。任務(wù)列表/項(xiàng)目管理管理已創(chuàng)建的不同任務(wù)流。3.2 構(gòu)建你的第一個(gè)任務(wù)自動(dòng)搜索并提取結(jié)果我們以“在百度搜索關(guān)鍵詞并提取第一頁結(jié)果標(biāo)題”為例演示構(gòu)建流程。步驟 1創(chuàng)建新任務(wù)在 UI 中點(diǎn)擊“New Task”或“創(chuàng)建新任務(wù)”命名為baidu_search_demo。步驟 2拖拽動(dòng)作塊并連線Navigate從組件庫拖出“Navigate”塊到畫布。在屬性面板設(shè)置URL為https://www.baidu.com。這個(gè)塊代表打開百度首頁。Type拖出“Type”塊連接到“Navigate”塊的下方。在屬性面板設(shè)置Selector:#kw(這是百度搜索輸入框的CSS選擇器)。Text:Figranium 自動(dòng)化測(cè)試。Delay (ms):500(可選模擬人類輸入延遲)。Click拖出“Click”塊連接到“Type”塊下方。設(shè)置Selector為#su(百度一下按鈕)。Wait For Navigation拖出“Wait”塊或類似功能塊連接到“Click”塊下方。設(shè)置Wait For為navigation或Timeout為10000等待頁面跳轉(zhuǎn)完成。Extract Data拖出“Extract”塊連接到“Wait”塊下方。這是我們?nèi)蝿?wù)的核心——獲取數(shù)據(jù)。配置提取規(guī)則通常你需要指定一個(gè)“選擇器”來定位多個(gè)結(jié)果項(xiàng)例如.result.c-container h3。然后為每個(gè)匹配的元素定義一個(gè)“提取字段”。例如定義一個(gè)字段title其提取方式為element.textContent。最終這個(gè)塊會(huì)輸出一個(gè)包含所有結(jié)果標(biāo)題的數(shù)組如[“Figranium 官網(wǎng)”, “GitHub - figranium”, “…]。Return/Output拖出一個(gè)“Return”或“Output”塊連接到“Extract”塊下方。將上一步提取的數(shù)據(jù)數(shù)組賦值給輸出變量例如output extracted_titles。最終你的畫布上應(yīng)該有一條清晰的流程線Navigate - Type - Click - Wait - Extract - Return。步驟 3調(diào)試與運(yùn)行保存任務(wù)。點(diǎn)擊“Run”或“Test”Figranium UI 通常會(huì)啟動(dòng)一個(gè)調(diào)試會(huì)話在界面內(nèi)嵌的瀏覽器或新窗口中執(zhí)行你構(gòu)建的流程。查看執(zhí)行日志與結(jié)果執(zhí)行過程中你可以看到每個(gè)步驟的日志成功/失敗。執(zhí)行完成后在結(jié)果面板可以看到提取到的標(biāo)題列表。通過這個(gè)簡(jiǎn)單的例子你已經(jīng)體驗(yàn)了可視化構(gòu)建的核心邏輯定義步驟What - 配置細(xì)節(jié)How - 連接順序When。3.3 高級(jí)功能條件、循環(huán)與變量變量你可以在任務(wù)中定義變量如search_keyword并在后續(xù)的“Type”塊中引用它Text: {{search_keyword}}。這使得任務(wù)可參數(shù)化。條件判斷使用“Condition”塊。例如你可以判斷“Extract”塊提取的數(shù)組是否為空如果為空則走一條發(fā)送警報(bào)的路徑否則走正常處理路徑。循環(huán)使用“Loop”塊。例如你可以遍歷一個(gè)URL列表對(duì)每個(gè)URL執(zhí)行相同的抓取操作。這些高級(jí)功能讓你能構(gòu)建出非常復(fù)雜和智能的瀏覽器工作流。4. API 調(diào)用詳解將任務(wù)集成到你的系統(tǒng)可視化構(gòu)建是手段API 調(diào)用才是將自動(dòng)化能力賦能給其他系統(tǒng)的關(guān)鍵。4.1 API 概覽Figranium API Server (端口 8080) 通常提供 RESTful 接口。以下是一些核心端點(diǎn)具體路徑需參考官方文檔GET /api/tasks獲取所有任務(wù)列表。GET /api/tasks/{id}獲取特定任務(wù)的詳情包括其流程定義。POST /api/executions創(chuàng)建一個(gè)新的任務(wù)執(zhí)行實(shí)例。GET /api/executions/{id}查詢某個(gè)執(zhí)行實(shí)例的狀態(tài)和結(jié)果。POST /api/tasks/{id}/run可能是一個(gè)直接運(yùn)行任務(wù)的快捷端點(diǎn)。4.2 執(zhí)行一個(gè)任務(wù)完整代碼示例假設(shè)我們已經(jīng)通過 UI 創(chuàng)建了一個(gè)任務(wù)其ID為task_baidu_search?,F(xiàn)在我們通過 API 來觸發(fā)它。使用 cURL 調(diào)用curl -X POST http://localhost:8080/api/executions \ -H Content-Type: application/json \ -d { taskId: task_baidu_search, parameters: { keyword: Docker 容器化 }, callbackUrl: https://your-server.com/webhook/figranium # 可選執(zhí)行完成后回調(diào)通知 }請(qǐng)求體說明taskId: 要執(zhí)行的任務(wù)ID。parameters: 傳遞給任務(wù)的運(yùn)行時(shí)參數(shù)。這對(duì)應(yīng)著你在UI中定義的變量。例如任務(wù)里可能有一個(gè)變量{{keyword}}這里傳入Docker 容器化任務(wù)執(zhí)行時(shí)就會(huì)使用這個(gè)值進(jìn)行搜索。callbackUrl: 可選。任務(wù)執(zhí)行完成后無論成功失敗Figranium API 會(huì)向這個(gè) URL 發(fā)送一個(gè) POST 請(qǐng)求包含執(zhí)行結(jié)果。這對(duì)于異步處理非常有用。響應(yīng)示例{ executionId: exec_abc123, taskId: task_baidu_search, status: queued, createdAt: 2023-10-27T08:00:00Z }你得到了一個(gè)executionId用于后續(xù)查詢結(jié)果。4.3 查詢執(zhí)行結(jié)果使用上一步得到的executionId來查詢狀態(tài)和獲取數(shù)據(jù)。curl -X GET http://localhost:8080/api/executions/exec_abc123響應(yīng)示例執(zhí)行中{ executionId: exec_abc123, taskId: task_baidu_search, status: running, startedAt: 2023-10-27T08:00:05Z, currentStep: Extract Data }響應(yīng)示例執(zhí)行成功{ executionId: exec_abc123, taskId: task_baidu_search, status: succeeded, startedAt: 2023-10-27T08:00:05Z, finishedAt: 2023-10-27T08:00:15Z, result: { output: [ Docker 容器化入門教程 - CSDN, 什么是 Docker 容器 | Docker 官方文檔, Docker 從入門到實(shí)踐 - GitBook ] } }響應(yīng)示例執(zhí)行失敗{ executionId: exec_abc123, taskId: task_baidu_search, status: failed, startedAt: 2023-10-27T08:00:05Z, finishedAt: 2023-10-27T08:00:08Z, error: { step: Click, message: Element not found with selector: #su, details: ... } }4.4 在 Python/Node.js 項(xiàng)目中集成在實(shí)際項(xiàng)目中你需要在代碼中調(diào)用這些 API。Python 示例 (使用 requests 庫)import requests import time FIGRANIUM_API_BASE http://localhost:8080 def run_figranium_task(task_id, paramsNone): 觸發(fā) Figranium 任務(wù)執(zhí)行 url f{FIGRANIUM_API_BASE}/api/executions payload { taskId: task_id, parameters: params or {} } resp requests.post(url, jsonpayload) resp.raise_for_status() return resp.json()[executionId] def get_execution_result(execution_id, timeout60, interval2): 輪詢獲取任務(wù)執(zhí)行結(jié)果 url f{FIGRANIUM_API_BASE}/api/executions/{execution_id} start_time time.time() while time.time() - start_time timeout: resp requests.get(url) resp.raise_for_status() data resp.json() status data[status] if status succeeded: return data[result] # 返回成功結(jié)果 elif status failed: raise Exception(fTask failed: {data.get(error, Unknown error)}) elif status in [queued, running]: print(fTask is {status}, waiting...) time.sleep(interval) else: raise Exception(fUnexpected status: {status}) raise TimeoutError(Task execution timeout) # 使用示例 if __name__ __main__: try: exec_id run_figranium_task(task_baidu_search, {keyword: Python API 調(diào)用}) print(fTask started. Execution ID: {exec_id}) result get_execution_result(exec_id) print(Search results:, result.get(output, [])) except Exception as e: print(fError: {e})Node.js 示例 (使用 axios)const axios require(axios); const FIGRANIUM_API_BASE http://localhost:8080; async function runFigraniumTask(taskId, params {}) { const url ${FIGRANIUM_API_BASE}/api/executions; const response await axios.post(url, { taskId, parameters: params }); return response.data.executionId; } async function getExecutionResult(executionId, timeout 60000, interval 2000) { const url ${FIGRANIUM_API_BASE}/api/executions/${executionId}; const startTime Date.now(); while (Date.now() - startTime timeout) { try { const response await axios.get(url); const data response.data; switch (data.status) { case succeeded: return data.result; case failed: throw new Error(Task failed: ${data.error?.message || Unknown error}); case queued: case running: console.log(Task is ${data.status}, waiting...); await new Promise(resolve setTimeout(resolve, interval)); break; default: throw new Error(Unexpected status: ${data.status}); } } catch (error) { throw error; } } throw new Error(Task execution timeout); } // 使用示例 (async () { try { const execId await runFigraniumTask(task_baidu_search, { keyword: Node.js 爬蟲 }); console.log(Task started. Execution ID: ${execId}); const result await getExecutionResult(execId); console.log(Search results:, result?.output || []); } catch (error) { console.error(Error:, error.message); } })();5. 常見問題與排查思路在部署和使用 Figranium 過程中你可能會(huì)遇到以下問題。問題現(xiàn)象可能原因排查步驟與解決方案Docker Compose 啟動(dòng)失敗1. 端口被占用2. 鏡像拉取失敗3. 內(nèi)存不足1.docker-compose ps查看端口沖突修改docker-compose.yml中的端口映射。2.docker-compose logs查看具體錯(cuò)誤檢查網(wǎng)絡(luò)嘗試docker pull鏡像。3.docker stats查看資源使用增加 Docker 內(nèi)存分配或服務(wù)器資源。UI 無法訪問 (localhost:3000)1. 服務(wù)未啟動(dòng)2. 防火墻限制3. 容器內(nèi)部錯(cuò)誤1.docker-compose ps確認(rèn)figranium-ui服務(wù)狀態(tài)為Up。2. 檢查服務(wù)器防火墻/安全組是否開放了3000端口。3.docker-compose logs figranium-ui查看前端容器日志。API 調(diào)用返回 404 或連接拒絕1. API 服務(wù)未運(yùn)行2. 網(wǎng)絡(luò)配置錯(cuò)誤3. 路徑錯(cuò)誤1. 確認(rèn)figranium-api容器運(yùn)行正常端口 8080 可訪問。2. 在 Docker 內(nèi)部使用docker-compose exec figranium-api curl localhost:8080/health檢查 API 健康狀態(tài)。3. 核對(duì) API 文檔確認(rèn)端點(diǎn)路徑是否正確。任務(wù)執(zhí)行失敗錯(cuò)誤提示元素未找到1. 頁面加載未完成2. 元素選擇器錯(cuò)誤或已變更3. 頁面存在 iframe 或 Shadow DOM1. 在“Click”或“Type”等操作前添加“Wait”塊等待元素出現(xiàn)。2. 使用瀏覽器開發(fā)者工具重新檢查并更新元素選擇器。3. 對(duì)于 iframe需要使用“Switch to Frame”塊對(duì)于 Shadow DOM可能需要特殊的選擇器或使用 JavaScript 執(zhí)行。任務(wù)執(zhí)行超時(shí)1. 網(wǎng)絡(luò)慢或目標(biāo)網(wǎng)站響應(yīng)慢2. 任務(wù)邏輯有無限循環(huán)3. 瀏覽器實(shí)例崩潰1. 在任務(wù)配置或 API 調(diào)用時(shí)增加超時(shí)時(shí)間。2. 檢查任務(wù)流程圖中的循環(huán)邏輯確保有正確的退出條件。3. 查看figranium-browser容器的日志 (docker-compose logs figranium-browser)。提取的數(shù)據(jù)為空或格式不對(duì)1. 提取選擇器未匹配到任何元素2. 提取的字段配置錯(cuò)誤3. 頁面結(jié)構(gòu)是動(dòng)態(tài)加載的1. 在“Extract”塊中使用更通用的選擇器或在 UI 調(diào)試模式下查看當(dāng)前頁面的 HTML 結(jié)構(gòu)。2. 確認(rèn)字段的提取方式如textContent,innerHTML,getAttribute(‘href’)是否正確。3. 在提取數(shù)據(jù)前添加等待或觸發(fā)頁面滾動(dòng)的操作確保數(shù)據(jù)已加載。API 返回429 Too Many Requests并發(fā)任務(wù)數(shù)超過限制1. 檢查figranium-browser服務(wù)的MAX_CONCURRENT_SESSIONS環(huán)境變量設(shè)置。2. 在你的調(diào)用代碼中實(shí)現(xiàn)請(qǐng)求隊(duì)列或增加重試間隔。api error: 400相關(guān)錯(cuò)誤請(qǐng)求參數(shù)不符合 API 規(guī)范1. 仔細(xì)檢查 API 請(qǐng)求的 JSON 結(jié)構(gòu)、字段名和數(shù)據(jù)類型。2. 查閱 Figranium API 文檔確認(rèn)必填字段和參數(shù)格式。3. 對(duì)于thinking_budget等特定參數(shù)錯(cuò)誤確認(rèn)傳入的是正整數(shù)。6. 最佳實(shí)踐與工程建議將 Figranium 用于生產(chǎn)環(huán)境時(shí)遵循以下最佳實(shí)踐可以提升穩(wěn)定性、可維護(hù)性和安全性。6.1 任務(wù)設(shè)計(jì)最佳實(shí)踐模塊化與復(fù)用將通用的操作序列如“登錄網(wǎng)站”、“處理彈窗”構(gòu)建成獨(dú)立的子任務(wù)或模板。在復(fù)雜任務(wù)中通過調(diào)用或引用來復(fù)用它們避免重復(fù)構(gòu)建。健壯的選擇器優(yōu)先使用id、name或穩(wěn)定的>