建與API集成實戰(zhàn))
在自動化測試、數(shù)據(jù)抓取和網(wǎng)頁交互腳本開發(fā)中你是否厭倦了手動編寫和維護(hù)復(fù)雜的瀏覽器操作代碼當(dāng)業(yè)務(wù)需要模擬用戶登錄、表單提交、數(shù)據(jù)提取或頁面監(jiān)控時傳統(tǒng)的 Selenium 或 Puppeteer 腳本雖然強大但開發(fā)調(diào)試周期長對非專業(yè)開發(fā)者門檻較高。Figranium的出現(xiàn)為這類場景提供了一種全新的解決方案通過可視化拖拽構(gòu)建瀏覽器任務(wù)流并通過標(biāo)準(zhǔn) API 一鍵執(zhí)行整個過程支持 Docker 容器化部署極大地簡化了瀏覽器自動化的工程實踐。本文將為你完整拆解 Figranium 的核心概念、架構(gòu)設(shè)計、從零開始的部署流程以及如何通過 API 集成到你的項目中。無論你是測試工程師、后端開發(fā)者還是需要處理網(wǎng)頁自動化任務(wù)的數(shù)據(jù)分析師都能通過本文掌握一套高效、可復(fù)用的實戰(zhàn)方案。1. Figranium 是什么核心概念與價值1.1 可視化瀏覽器任務(wù)構(gòu)建器Figranium 的核心定位是一個“可視化瀏覽器任務(wù)構(gòu)建與執(zhí)行平臺”。你可以將其理解為一個低代碼/無代碼工具專門用于編排在瀏覽器中執(zhí)行的一系列操作。傳統(tǒng)方式使用 Python Selenium你需要編寫諸如find_element,click,send_keys的代碼并處理等待、iframe、彈窗等各種邊界情況。Figranium 方式在一個圖形化界面中通過拖拽預(yù)定義的“動作塊”如“打開網(wǎng)頁”、“輸入文本”、“點擊元素”、“提取數(shù)據(jù)”并以連線的方式定義執(zhí)行流程。這大大降低了創(chuàng)建自動化腳本的技術(shù)門檻。1.2 API 驅(qū)動的任務(wù)執(zhí)行構(gòu)建好的任務(wù)流并不是在 Figranium 的界面上直接運行。Figranium 將其封裝成可通過 HTTP API 調(diào)用的服務(wù)。這意味著解耦設(shè)計與執(zhí)行你可以在 Figranium 的 Web UI 中精心設(shè)計和調(diào)試你的任務(wù)流程。集成到任何系統(tǒng)任何能發(fā)送 HTTP 請求的程序你的后端服務(wù)、定時任務(wù)、命令行工具都可以通過調(diào)用 Figranium 提供的 API觸發(fā)一個或多個瀏覽器任務(wù)的執(zhí)行。標(biāo)準(zhǔn)化與復(fù)用任務(wù)被定義為可復(fù)用的“資產(chǎn)”通過 API 調(diào)用可以在不同場景、不同時間被反復(fù)執(zhí)行。1.3 Dockerized 部署“Dockerized”意味著 Figranium 被打包成了 Docker 鏡像。這帶來了幾個關(guān)鍵優(yōu)勢環(huán)境一致性避免了“在我機器上能跑”的經(jīng)典問題。無論是在開發(fā)、測試還是生產(chǎn)環(huán)境只要運行同一個 Docker 鏡像Figranium 的運行環(huán)境就是完全一致的??焖俨渴鹨粭ldocker run命令即可啟動全套服務(wù)通常包含前端 UI、后端 API 服務(wù)器和瀏覽器運行環(huán)境。資源隔離與擴展每個 Figranium 實例運行在獨立的容器中互不干擾。你可以輕松地通過 Docker Compose 或 Kubernetes 來編排多個實例以支持高并發(fā)任務(wù)執(zhí)行。1.4 解決什么問題降低自動化門檻讓不擅長編程的運營、產(chǎn)品人員也能創(chuàng)建簡單的網(wǎng)頁自動化流程。提升開發(fā)效率對于開發(fā)者可視化構(gòu)建可以快速原型驗證省去大量樣板代碼的編寫。便于協(xié)作與維護(hù)任務(wù)流程以圖形化方式呈現(xiàn)邏輯一目了然比閱讀代碼更易于團(tuán)隊理解和維護(hù)。打造自動化服務(wù)通過 API你可以將瀏覽器自動化能力作為一項微服務(wù)提供給其他系統(tǒng)調(diào)用構(gòu)建更復(fù)雜的自動化工作流。2. 環(huán)境準(zhǔn)備與部署指南在開始使用 Figranium 之前我們需要搭建其運行環(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ù)已啟動。Docker Compose版本 1.29.0 或更高如果使用 Compose 部署方式。Figranium 的部署通常需要協(xié)調(diào)多個容器Web UI、API Server、瀏覽器實例Compose 是最佳選擇。網(wǎng)絡(luò)服務(wù)器需要能訪問外網(wǎng)以便拉取 Docker 鏡像和任務(wù)中需要訪問的目標(biāo)網(wǎng)頁。硬件建議至少 2核 CPU4GB 內(nèi)存。運行瀏覽器實例尤其是多個并發(fā)比較消耗資源。2.2 獲取 Figranium 部署文件通常開源項目會提供docker-compose.yml文件來定義服務(wù)。你需要從 Figranium 的官方代碼倉庫如 GitHub獲取這個文件。假設(shè)項目倉庫地址為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 是一個相對較新的 Show HN 項目其具體的倉庫地址和部署文件可能發(fā)生變化。請以項目官方文檔為準(zhǔn)。本文的示例基于此類項目的通用結(jié)構(gòu)。2.3 使用 Docker Compose 啟動一個典型的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)建器的前端界面運行在 3000 端口。figranium-api核心 API 服務(wù)器接收任務(wù)執(zhí)行請求運行在 8080 端口。它將任務(wù)數(shù)據(jù)持久化到掛載的./data目錄。figranium-browser使用browserless/chrome鏡像提供無頭 Chrome 瀏覽器環(huán)境供 API 服務(wù)器驅(qū)動執(zhí)行任務(wù)。figranium-redisRedis 數(shù)據(jù)庫用于緩存任務(wù)狀態(tài)、管理隊列等。在包含docker-compose.yml的目錄下執(zhí)行以下命令啟動所有服務(wù)# 啟動服務(wù)后臺運行 docker-compose up -d # 查看服務(wù)運行狀態(tài) docker-compose ps # 查看實時日志 docker-compose logs -f figranium-api啟動成功后你可以通過瀏覽器訪問http://你的服務(wù)器IP:3000來打開 Figranium 的可視化構(gòu)建界面。3. 核心功能與可視化構(gòu)建實戰(zhàn)3.1 初識 Figranium 用戶界面訪問 UI (端口 3000) 后你通常會看到以下核心區(qū)域組件庫/動作面板羅列所有可用的瀏覽器操作“塊”如“Navigate”導(dǎo)航、“Click”點擊、“Type”輸入、“Extract Text”提取文本、“Screenshot”截圖、“Condition”條件判斷、“Loop”循環(huán)等。畫布/工作區(qū)拖拽動作塊到此區(qū)域并通過連線連接它們構(gòu)建任務(wù)流程圖。屬性/配置面板選中畫布上的某個動作塊在此面板配置其具體參數(shù)如要導(dǎo)航的URL、要點擊的元素選擇器、要輸入的文本等。任務(wù)列表/項目管理管理已創(chuàng)建的不同任務(wù)流。3.2 構(gòu)建你的第一個任務(wù)自動搜索并提取結(jié)果我們以“在百度搜索關(guān)鍵詞并提取第一頁結(jié)果標(biāo)題”為例演示構(gòu)建流程。步驟 1創(chuàng)建新任務(wù)在 UI 中點擊“New Task”或“創(chuàng)建新任務(wù)”命名為baidu_search_demo。步驟 2拖拽動作塊并連線Navigate從組件庫拖出“Navigate”塊到畫布。在屬性面板設(shè)置URL為https://www.baidu.com。這個塊代表打開百度首頁。Type拖出“Type”塊連接到“Navigate”塊的下方。在屬性面板設(shè)置Selector:#kw(這是百度搜索輸入框的CSS選擇器)。Text:Figranium 自動化測試。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ī)則通常你需要指定一個“選擇器”來定位多個結(jié)果項例如.result.c-container h3。然后為每個匹配的元素定義一個“提取字段”。例如定義一個字段title其提取方式為element.textContent。最終這個塊會輸出一個包含所有結(jié)果標(biāo)題的數(shù)組如[“Figranium 官網(wǎng)”, “GitHub - figranium”, “…]。Return/Output拖出一個“Return”或“Output”塊連接到“Extract”塊下方。將上一步提取的數(shù)據(jù)數(shù)組賦值給輸出變量例如output extracted_titles。最終你的畫布上應(yīng)該有一條清晰的流程線Navigate - Type - Click - Wait - Extract - Return。步驟 3調(diào)試與運行保存任務(wù)。點擊“Run”或“Test”Figranium UI 通常會啟動一個調(diào)試會話在界面內(nèi)嵌的瀏覽器或新窗口中執(zhí)行你構(gòu)建的流程。查看執(zhí)行日志與結(jié)果執(zhí)行過程中你可以看到每個步驟的日志成功/失敗。執(zhí)行完成后在結(jié)果面板可以看到提取到的標(biāo)題列表。通過這個簡單的例子你已經(jīng)體驗了可視化構(gòu)建的核心邏輯定義步驟What - 配置細(xì)節(jié)How - 連接順序When。3.3 高級功能條件、循環(huán)與變量變量你可以在任務(wù)中定義變量如search_keyword并在后續(xù)的“Type”塊中引用它Text: {{search_keyword}}。這使得任務(wù)可參數(shù)化。條件判斷使用“Condition”塊。例如你可以判斷“Extract”塊提取的數(shù)組是否為空如果為空則走一條發(fā)送警報的路徑否則走正常處理路徑。循環(huán)使用“Loop”塊。例如你可以遍歷一個URL列表對每個URL執(zhí)行相同的抓取操作。這些高級功能讓你能構(gòu)建出非常復(fù)雜和智能的瀏覽器工作流。4. API 調(diào)用詳解將任務(wù)集成到你的系統(tǒng)可視化構(gòu)建是手段API 調(diào)用才是將自動化能力賦能給其他系統(tǒng)的關(guān)鍵。4.1 API 概覽Figranium API Server (端口 8080) 通常提供 RESTful 接口。以下是一些核心端點具體路徑需參考官方文檔GET /api/tasks獲取所有任務(wù)列表。GET /api/tasks/{id}獲取特定任務(wù)的詳情包括其流程定義。POST /api/executions創(chuàng)建一個新的任務(wù)執(zhí)行實例。GET /api/executions/{id}查詢某個執(zhí)行實例的狀態(tài)和結(jié)果。POST /api/tasks/{id}/run可能是一個直接運行任務(wù)的快捷端點。4.2 執(zhí)行一個任務(wù)完整代碼示例假設(shè)我們已經(jīng)通過 UI 創(chuàng)建了一個任務(wù)其ID為task_baidu_search。現(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)通知 }請求體說明taskId: 要執(zhí)行的任務(wù)ID。parameters: 傳遞給任務(wù)的運行時參數(shù)。這對應(yīng)著你在UI中定義的變量。例如任務(wù)里可能有一個變量{{keyword}}這里傳入Docker 容器化任務(wù)執(zhí)行時就會使用這個值進(jìn)行搜索。callbackUrl: 可選。任務(wù)執(zhí)行完成后無論成功失敗Figranium API 會向這個 URL 發(fā)送一個 POST 請求包含執(zhí)行結(jié)果。這對于異步處理非常有用。響應(yīng)示例{ executionId: exec_abc123, taskId: task_baidu_search, status: queued, createdAt: 2023-10-27T08:00:00Z }你得到了一個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 從入門到實踐 - 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 項目中集成在實際項目中你需要在代碼中調(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 過程中你可能會遇到以下問題。問題現(xiàn)象可能原因排查步驟與解決方案Docker Compose 啟動失敗1. 端口被占用2. 鏡像拉取失敗3. 內(nèi)存不足1.docker-compose ps查看端口沖突修改docker-compose.yml中的端口映射。2.docker-compose logs查看具體錯誤檢查網(wǎng)絡(luò)嘗試docker pull鏡像。3.docker stats查看資源使用增加 Docker 內(nèi)存分配或服務(wù)器資源。UI 無法訪問 (localhost:3000)1. 服務(wù)未啟動2. 防火墻限制3. 容器內(nèi)部錯誤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ù)未運行2. 網(wǎng)絡(luò)配置錯誤3. 路徑錯誤1. 確認(rèn)figranium-api容器運行正常端口 8080 可訪問。2. 在 Docker 內(nèi)部使用docker-compose exec figranium-api curl localhost:8080/health檢查 API 健康狀態(tài)。3. 核對 API 文檔確認(rèn)端點路徑是否正確。任務(wù)執(zhí)行失敗錯誤提示元素未找到1. 頁面加載未完成2. 元素選擇器錯誤或已變更3. 頁面存在 iframe 或 Shadow DOM1. 在“Click”或“Type”等操作前添加“Wait”塊等待元素出現(xiàn)。2. 使用瀏覽器開發(fā)者工具重新檢查并更新元素選擇器。3. 對于 iframe需要使用“Switch to Frame”塊對于 Shadow DOM可能需要特殊的選擇器或使用 JavaScript 執(zhí)行。任務(wù)執(zhí)行超時1. 網(wǎng)絡(luò)慢或目標(biāo)網(wǎng)站響應(yīng)慢2. 任務(wù)邏輯有無限循環(huán)3. 瀏覽器實例崩潰1. 在任務(wù)配置或 API 調(diào)用時增加超時時間。2. 檢查任務(wù)流程圖中的循環(huán)邏輯確保有正確的退出條件。3. 查看figranium-browser容器的日志 (docker-compose logs figranium-browser)。提取的數(shù)據(jù)為空或格式不對1. 提取選擇器未匹配到任何元素2. 提取的字段配置錯誤3. 頁面結(jié)構(gòu)是動態(tài)加載的1. 在“Extract”塊中使用更通用的選擇器或在 UI 調(diào)試模式下查看當(dāng)前頁面的 HTML 結(jié)構(gòu)。2. 確認(rèn)字段的提取方式如textContent,innerHTML,getAttribute(‘href’)是否正確。3. 在提取數(shù)據(jù)前添加等待或觸發(fā)頁面滾動的操作確保數(shù)據(jù)已加載。API 返回429 Too Many Requests并發(fā)任務(wù)數(shù)超過限制1. 檢查figranium-browser服務(wù)的MAX_CONCURRENT_SESSIONS環(huán)境變量設(shè)置。2. 在你的調(diào)用代碼中實現(xiàn)請求隊列或增加重試間隔。api error: 400相關(guān)錯誤請求參數(shù)不符合 API 規(guī)范1. 仔細(xì)檢查 API 請求的 JSON 結(jié)構(gòu)、字段名和數(shù)據(jù)類型。2. 查閱 Figranium API 文檔確認(rèn)必填字段和參數(shù)格式。3. 對于thinking_budget等特定參數(shù)錯誤確認(rèn)傳入的是正整數(shù)。6. 最佳實踐與工程建議將 Figranium 用于生產(chǎn)環(huán)境時遵循以下最佳實踐可以提升穩(wěn)定性、可維護(hù)性和安全性。6.1 任務(wù)設(shè)計最佳實踐模塊化與復(fù)用將通用的操作序列如“登錄網(wǎng)站”、“處理彈窗”構(gòu)建成獨立的子任務(wù)或模板。在復(fù)雜任務(wù)中通過調(diào)用或引用來復(fù)用它們避免重復(fù)構(gòu)建。健壯的選擇器優(yōu)先使用id、name或穩(wěn)定的>