本次內容主要是講解如果剝離微軟Power Automate Desktop控制瀏覽器得部分API,
通過剝離其API, 用於集成在自身的軟件業務當中, 實現控制瀏覽器及獲取相關數據得實現。
分析
PAD本身也是一個基於WPF開發的客戶端應用程序, 本質上來講它也無非是使用C#的類庫來實現其功能, 那么只要找到對應API的位置以及實現方法,
我們即可將其實現集成在自己的軟件當中。為了能夠找到對應的API, 需要分析幾個部分, 一個是調用DLL的文件位置,另外一個是PAD當中的參數傳遞部分。
查找DLL
在PAD當中,控制瀏覽器的部分歸屬在Web自動化下,如下所示:

那么找到對應的DLL其實也很簡單, 與Web相關的有兩個值得注意的文件,如下所示:

但是現在還不夠, 你不太確定他具體調用了哪個方法,這個時候,我們就可以在PAD當中查看文檔, 找到具體調用的方法。
首先,我們嘗試查找獲取瀏覽器數據的功能,查看對應的文檔,可以注意到瀏覽器結尾給我們留下來了一點訊息:
https://docs.microsoft.com/zh-cn/power-automate/desktop-flows/actions-reference/webautomation#getdetailsofwebpage
通過 getdetailsofwebpage去搜索到對應的方法,不出意外,找到了,如下所示:

到了這一步, 我們就得動用反編譯軟件了, 因為要把具體的實現剝離出來,就得分析對應的代碼結構。
反編譯查找
通過反編譯軟件, 找到了對應的方法實現, 可以看到繼承了一個ActionBase。

那既然是ActionBase, 說明可能具體的操作還不是在這里, 而是在其他的地方, 可以注意到該功能是在Web數據提取下面。
那么是不是對應的會有一個數據提取的類, 他間接繼承於ActionBse?
不出意外,看到了一個用於數據提取的類,如下所示:

如何判斷就是它呢?這個時候就需要用PAD來進行校驗, 看看PAD當中的輸入參數是否能與該類一致,只要能對上, 說明就是它。
代碼實現
通過PAD的可視化界面, 可以發現對應的參數都有,那么我們嘗試自己寫一個類來模擬該功能。
ExtractData 類中包含一下重要參數:
- BrowserInstance: 瀏覽器實例
- StoreDataMode : 數據存儲模式
- ExtractionMode: 提取數據類型
- ExtractionParameters: 傳入的提取參數
- Control: 設置CSS選擇器
示例代碼,即如下所示:
ExtractData extractData = new ExtractData();
extractData.BrowserInstance = edgeBase.BrowserInstance;
extractData.StoreDataMode = Robin.Modules.WebAutomation.Actions
.Enums.StoreDataMode.Variable;
extractData.ExtractionMode = Robin.Modules.WebAutomation
.Actions.Enums.ExtractionMode.Table;
extractData.ExtractionParameters = table;
extractData.Control = new Robin.Core.Types.WebControl()
{ };
有了這些代碼之后, 我們就差一個示范了, 我們模擬獲取網頁的列表數據,看看是否可行。
開始動手
有了基本的思路之后,我們開始分步驟:
1.創建一個瀏覽器實例,打開測試的網頁
2.設置ExtractData
3.執行Execute
4.獲取ExtractedData
具體代碼如下所示:
LaunchEdgeBase edgeBase = new LaunchEdgeBase();
edgeBase.LaunchMode = Robin.Modules.WebAutomation.Actions.Enums.LaunchMode.LaunchNew;
edgeBase.Url = "https://s.taobao.com/search?initiative_id=tbindexz_20170306&ie=utf8&spm=a21bo.21814703.201856-taobao-item.2&sourceId=tb.index&search_type=item&ssid=s5-e&commend=all&imgfile=&q=%E6%89%8B%E6%9C%BA%E5%A3%B3&suggest=0_1&_input_charset=utf-8&wq=shouji&suggest_query=shouji&source=suggest";
edgeBase.WaitForPageToLoad = true;
edgeBase.WindowState = Robin.Modules.WebAutomation.Actions.Enums.BrowserWindowState.Maximized;
edgeBase.Execute(null);
DataTable table = new DataTable();
table.Columns.Add("cssSelector");
table.Columns.Add("attribute");
table.Columns.Add("regex");
table.Columns.Add("columnName");
table.Rows.Add("div:eq(1) > div:eq(1) > a", "Own Text", null, "value1");
table.Rows.Add("div:eq(1) > div:eq(2) > div:eq(0) > a > span:eq(1)", "Own Text", null, "value2");
ExtractData extractData = new ExtractData();
extractData.BrowserInstance = edgeBase.BrowserInstance;
extractData.StoreDataMode = Robin.Modules.WebAutomation.Actions
.Enums.StoreDataMode.Variable;
extractData.MaxWebPagesToProcess = 1;
extractData.ExtractionMode = Robin.Modules.WebAutomation
.Actions.Enums.ExtractionMode.Table;
extractData.ExtractionParameters = table;
extractData.Control = new Robin.Core.Types.WebControl()
{
Selector = "html > body > div:eq(0) > div:eq(1) > div:eq(2) > div:eq(0) > div:eq(20) > div > div > div:eq(0) > div"
};
extractData.Execute(null);
table = extractData.ExtractedData;
