實現一個完整爬蟲並爬蟲能滿足工作流需求使用的工作量其實比較大,本文只是第一個章節,着重於搭建項目腳手架並使用clipsheet在一個網頁上探測出可爬取表格的簡單例子,更多的內容之後會持續更新
如果你想直接體驗univer-clipsheet的功能,而不關心具體實現可以參考這篇文章,這篇文章更着重介紹瞭如何使用univer-clipsheet。
一款更簡單好用的Chrome爬蟲插件 - Univer Clipsheet
本文的功能都是基於 univer-clipsheet 開源項目提供的能力去完成一個簡單的爬蟲項目,univer-clipsheet的能力的實現代碼實際是在 univer-clipsheet-core 的倉庫下,接下來我們會在項目中引入univer-clipsheet-core去幫助我們完成一個從網頁中採集表格的工作。
1. 初始化項目
我們推薦直接用 chrome-extension-boilerplate-react-vite作為我們插件項目的腳手架,執行以下命令初始化項目,git submodule add 是將我們的univer-clipsheet-core引入到項目中
git clone https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite.git
cd chrome-extension-boilerplate-react
git submodule add https://github.com/dream-num/univer-clipsheet-core submodules/univer-clipsheet-core
找到pnpm-workspace.yaml文件並新增一行
- 'submodules/univer-clipsheet-core/packages/**'
執行命令pnpm i去安裝依賴
`pnpm i
`
安裝依賴完畢後執行以下命令運行插件
`pnpm dev
`
成功運行後,打開項目的文件夾,會看到一個dist文件夾,打開chrome瀏覽器或者其他瀏覽器的擴展管理頁面,加載dist文件夾。
關於瀏覽器怎麼通過文件夾安裝插件可以參考這篇文章在github下載chrome擴展文件壓縮包後怎麼添加擴展到chrome(chrome添加hackbar擴展)_github插件 裝 chrome-CSDN博客
加載成功後,可以看到瀏覽器右上角已經顯示該插件,作者這裏以chrome為例,其他瀏覽器的入口所在位置也大徑相同。
2. 查找網頁中的表格
我們回到項目代碼中,導航到 pages/content目錄,並給package.json中聲明univer-clipsheet-core的依賴
"@univer-clipsheet-core/table": "workspace:*"
結束項目運行,重新執行以下命令,安裝依賴以及重新運行
pnpm i && pnpm dev
導航到 pages/content/index.ts 文件中,添加如下代碼保存,並刷新當前正在瀏覽的網頁並打開瀏覽器控制枱。
import type { IInitialSheet, ITableApproximationExtractionParam } from '@univer-clipsheet-core/table';
import { findApproximationTables, LazyLoadElements, LazyLoadTableElements } from '@univer-clipsheet-core/table';
// 該方法可以將table標籤元素轉換為IInitialSheet對象
function generateSheetByElement(element: HTMLTableElement) {
return new LazyLoadTableElements([element]).getAllSheets();
}
// 該方法可以將ExtractionParams對象轉換為IInitialSheet對象
function generateSheetByExtractionParams(params: ITableApproximationExtractionParam) {
return new LazyLoadElements([params]).getAllSheets();
}
window.addEventListener('load', () => {
const tableElements = document.querySelectorAll('table');
// 從body自上往下查找可能包含表格的元素(例如ui、li等列表標籤),並生成ExtractionParams對象
const extractionParamsList = findApproximationTables(document.body as HTMLBodyElement);
const allInitialSheets: IInitialSheet[] = [];
// 遍歷table標籤元素,生成IInitialSheet對象
tableElements.forEach(element => {
const sheets = generateSheetByElement(element as HTMLTableElement);
allInitialSheets.push(...sheets);
});
// 遍歷ExtractionParams對象,生成IInitialSheet對象
extractionParamsList.forEach(params => {
const sheets = generateSheetByExtractionParams(params);
allInitialSheets.push(...sheets);
});
allInitialSheets
// 過濾掉行數小於5的表格
.filter(sheet => sheet.rows.length > 5)
.forEach((sheet, sheetIndex) => {
console.log(`Sheet ${sheetIndex + 1} :`, sheet, 'sheet rows: ', sheet.rows);
});
});
代碼中已經添加了註釋,註釋説明了每行代碼的執行發生了什麼。
接下來,我們以react倉庫的issue頁面Issues · facebook/react · GitHub為例Issues · facebook/react · GitHub,跳轉到頁面並打開控制枱,我們可以看到控制枱打印出了我們在這個網頁中探測到的表格數據!
InitialSheet
initialSheet是univer-clipsheet對錶格的描述,大概關於initialSheet的類型定義我貼在下面
interface IInitialSheet {
sheetName: string;
columnName: string[];
rows: ISheet_Row[];
type: Initial_Sheet_Type_Num;
density: number;
cellCount: number;
weightedScore?: number;
selectorString?: string;
}
interface ISheet_Row {
cells: ISheet_Row_Cell[];
}
interface ISheet_Row_Cell {
type: Sheet_Cell_Type_Enum;
text: string;
url: string;
}
從類型定義我們可以看到,實際表格每個單元格的時候以SheetRowCell的類型定義,如果是文本元素我們會把值放在text字段上,如img、a、video等標籤,我們會解析它的資源放在url字段上。
結語:
以上就是我們通過univer-clipsheet開源能力做到的第一步,探測當前網頁中的表格,其實這也就是爬蟲需要做的事,採集網頁中的某一個表格,並加上更多自動化、定製化的能力,univer-clipsheet提供了很多能力來幫我們做到這些事,大家感興趣可以關注,這個系列會繼續更新~
聯繫我們
Clipsheet插件使用中有任何問題或者優化建議,歡迎通過github來提交issue上報問題,或通過以下方式來聯繫我們
[微信用户羣] 下滑到文檔最下方掃碼進入 Univer-Clipsheet 用户使用文檔
[Discord] discord.gg/rbZcJPm4un