Selenium WebDriver 是一組開源 API,用于自動測試 Web 應用程序,利用它可以通過代碼來控制chrome edge等瀏覽器!
有時候我們需要mock接口的返回,或者攔截和轉發請求,今天就來實現這個功能
本插件代碼已開源:https://github.com/yuzd/OpenQA.Selenium.Chrome.Fiddler
nuget
OpenQA.Selenium.Chrome.Fiddler
開始coding
我們新創建一個功能:OpenQA.Selenium.Chrome.Fiddler
一個chrome擴展 最起碼有2個文件
manifest.json
background.js
稍微解釋一下:
manifest.json 是來描述chrome擴展的
{"version":?"1.0.0","manifest_version":?2,"name":?"Chrome?Fiddler","permissions":?["proxy","tabs","unlimitedStorage","storage","<all_urls>","webRequest","webRequestBlocking"],"background":?{"scripts":?["background.js"]},"minimum_chrome_version":"22.0.0"
}
background.js 是邏輯處理模塊
因為攔截api 或者 轉發 需要用的chrome的api
chrome.webRequest.onBeforeRequest.addListener(function(details)?{//邏輯處理},{?urls:?['<all_urls>']},['blocking',?'extraHeaders',?'requestBody']
);
這個api的函數 接收的details參數
details.url 是api的接口
函數的返回
{cancel:true} ?攔截請求
{redirectUrl:''} 轉發到指定url
寫selenium.chrome插件
新建一個netstand工程,然后引用
Selenium.WebDriver
復制以下代碼
///?<summary>
///?Add?Fiddler?extention
///?</summary>
///?<param?name="options">Chrome?options</param>
///?<param?name="fiddlerOption">Proxy?host</param>
public?static?void?AddFiddler(this?ChromeOptions?options,?FiddlerOption?fiddlerOption)
{var?backgroundProxyJs?=?ReplaceTemplates(background_js,?fiddlerOption);if?(!Directory.Exists("Plugins"))Directory.CreateDirectory("Plugins");var?guid?=?Guid.NewGuid().ToString();var?manifestPath?=?$"Plugins/manifest_{guid}.json";var?backgroundPath?=?$"Plugins/background_{guid}.js";var?archiveFilePath?=?$"Plugins/proxy_auth_plugin_{guid}.zip";File.WriteAllText(manifestPath,?manifest_json);File.WriteAllText(backgroundPath,?backgroundProxyJs);using?(var?zip?=?ZipFile.Open(archiveFilePath,?ZipArchiveMode.Create)){zip.CreateEntryFromFile(manifestPath,?"manifest.json");zip.CreateEntryFromFile(backgroundPath,?"background.js");}File.Delete(manifestPath);File.Delete(backgroundPath);options.AddExtension(archiveFilePath);
}private?static?string?ReplaceTemplates(string?str,?FiddlerOption?fiddlerOption)
{if?(fiddlerOption.OnBeforeRequestOptions?!=?null){var?beforeConfigs?=?Newtonsoft.Json.JsonConvert.SerializeObject(fiddlerOption.OnBeforeRequestOptions);str?=?str.Replace("{before_configs}",?beforeConfigs);}return?str;
}
上面的代碼主要是創建一個chrome擴展zip包
然后再selenium.chrome啟動的時候傳進去這個zip包的地址
使用方法
var?driverBinary?=?@"D:\soft\chrome\chrome2\Chrome-bin\";ChromeOptions?options?=?new?ChromeOptions
{BinaryLocation?=?Path.Combine(driverBinary,?"chrome.exe")
};Environment.SetEnvironmentVariable("webdriver.chrome.driver",?driverBinary);
options.AddArgument("--disable-blink-features=AutomationControlled");
options.AddArguments("--disable-infobars");
List<string>?ls?=?new?List<string>?{?"enable-automation"?};
options.AddExcludedArguments(ls);#region?Fillderoptions.AddFiddler(new?FiddlerOption
{OnBeforeRequestOptions?=?new?List<FiddlerOnBeforeRequestOptions>{//?配置轉發new?FiddlerOnBeforeRequestOptions{Match?=?"https://www.cnblogs.com/yudongdong/ajax/GetPostStat",//正則RedirectUrl?=?"http://localhost:5000/GetPostStat",//如果匹配成功則將requestBody轉發到這個url中去Cancel?=?false//如果配置了cancel=true那么轉發將無效,true的意思是直接攔截這次的請求,不去發送了},//?配置攔截new?FiddlerOnBeforeRequestOptions{Match?=?"https://www.cnblogs.com/yudongdong/ajax/blogStats",Cancel?=?true//true的意思是直接攔截這次的請求,不去發送了},}
});#endregionvar?chrome?=?new?ChromeDriver(driverBinary,?options);
實現效果

可能有人問,selenium, webdriver 有太多的特征了,如何繞過風控呢
我的解決辦法是修改chromium的源碼來改變,感興趣的可以加我一起探討!
我是正東,學的越多不知道也越多,關注高效率寫代碼!