/// <summary>
/// 组装节点对象
/// </summary>
/// <param name="browser"></param>
/// <param name="tag"></param>
/// <param name="document"></param>
/// <returns></returns>
public static string AssembleIframeDocument(this IBrowser browser, string tag, string document = "document")
{
string script = "document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue.contentWindow.document";
return script;
}
/// <summary>
/// 组装节点对象
/// </summary>
/// <param name="browser"></param>
/// <param name="tag"></param>
/// <param name="document"></param>
/// <returns></returns>
public static string AssembleDocument(this IBrowser browser, string tag, string document = "document")
{
string script = "document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue";
return script;
}
/// <summary>
/// 获取元素所在位置
/// </summary>
/// <param name="browser">浏览器对象</param>
/// <param name="tag">标签(NodeName)</param>
/// <param name="document">html文档(xpath才技持)</param>
/// <returns></returns>
public static BoundingClientRect GetBoundingClientRect(this IBrowser browser, string tag, string document = "document")
{
var isXPath = Regex.IsMatch(tag, "(^//.*)");
if (isXPath)
{
string script = "(function(){";
script += "var doc= document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;";
script += @"if(doc != null){
let bntRect = doc.getBoundingClientRect();
let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom });
return result;
};
return null;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
var response = result.Result;
if (response.Success && response.Result == null) return null;
if (response.Result == null) return null;
BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString());
return bc;
}
else
{
string script = "(function(){";
script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");";
script += @"if(doc!=null){
let bntRect = doc.getBoundingClientRect();
let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom });
return result;
};
return null;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
var response = result.Result;
if (response.Success && response.Result == null) return null;
if (response.Result == null) return null;
BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString());
return bc;
}
}
/// <summary>
/// 通过ini指定值获取坐标
/// </summary>
/// <param name="browser"></param>
/// <param name="key">ini配置文件<k,v> k</param>
/// <param name="path">ini配置文件路径</param>
/// <returns></returns>
public static BoundingClientRect GetPosition(this IBrowser browser, string key, string path, string document = "document")
{
string tagText = INIHelper.Read("tag", key, path);//@"input[name=pass]";
tagText = string.IsNullOrWhiteSpace(tagText)
? INIHelper.Read("tagXPath", key, path)
: tagText;
var isLabel = browser.CheckLabel(tagText, document);
if (!isLabel) return null;
var bc = browser.GetBoundingClientRect(tagText, document);//获取登录按钮位置
if (bc == null) return null;
return bc;
}
/// <summary>
/// 模拟点击指定选择符DOM元素
/// </summary>
/// <param name="selector">jQuery选择符</param>
public static void ClickElement(this IBrowser browser, double? left, double? top, bool isFocusEvent = false)
{
var host = browser.GetHost();
var x = Convert.ToInt32(left) + 5;
var y = Convert.ToInt32(top) + 5;
host.SendMouseMoveEvent(x, y, false, CefEventFlags.None);//移动鼠标
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键
Thread.Sleep(50);
host.SendFocusEvent(isFocusEvent);
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键
}
/// <summary>
/// 全选
/// </summary>
/// <param name="browser"></param>
/// <param name="left"></param>
/// <param name="top"></param>
public static void SelectAllKeyEvent(this IBrowser browser)
{
KeyEvent k = new KeyEvent
{
WindowsKeyCode = 0x41, // A = 0x41,
FocusOnEditableField = true,
Modifiers = CefEventFlags.ControlDown,
Type = KeyEventType.KeyDown,
IsSystemKey = false
};
browser.GetHost().SendKeyEvent(k);
Thread.Sleep(100);
k = new KeyEvent
{
WindowsKeyCode = 0x41, // A = 0x41,
FocusOnEditableField = true,
Modifiers = CefEventFlags.ControlDown,
Type = KeyEventType.KeyUp,
IsSystemKey = false
};
browser.GetHost().SendKeyEvent(k);
Thread.Sleep(100);
}
/// <summary>
/// 向前删除
/// </summary>
/// <param name="browser"></param>
public static void BackSpaceKeyEvent(this IBrowser browser)
{
KeyEvent k = new KeyEvent
{
WindowsKeyCode = 0x08, // Back = 0x08,
FocusOnEditableField = true,
Modifiers = CefEventFlags.None,
IsSystemKey = false,
Type = KeyEventType.KeyDown
};
browser.GetHost().SendKeyEvent(k);
Thread.Sleep(100);
k = new KeyEvent
{
WindowsKeyCode = 0x08, // Back = 0x08,
FocusOnEditableField = true,
Modifiers = CefEventFlags.None,
IsSystemKey = false,
Type = KeyEventType.KeyUp
};
browser.GetHost().SendKeyEvent(k);
Thread.Sleep(100);
}
/// <summary>
/// 按下回车事件
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public static void HitEnterKeyEvent(this IBrowser browser, double? left, double? top)
{
KeyEvent k = new KeyEvent
{
WindowsKeyCode = 0x0D, // Enter
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyDown
};
browser.GetHost().SendKeyEvent(k);
//browser.GetHost().SendFocusEvent();
Thread.Sleep(100);
k = new KeyEvent
{
WindowsKeyCode = 0x0D, // Enter
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyUp
};
browser.GetHost().SendKeyEvent(k);
Thread.Sleep(100);
}
/// <summary>
/// 输入内容
/// </summary>
/// <param name="browser"></param>
/// <param name="inputString"></param>
public static void Input(this IBrowser browser, string inputString)
{
//var inputString = "CefSharp Was Here!";
var host = browser.GetHost();
foreach (var c in inputString)
{
host.SendKeyEvent(new KeyEvent { WindowsKeyCode = c, Type = KeyEventType.Char });
}
}
/// <summary>
/// 输入帐号
/// </summary>
/// <param name="browser">当前浏览器</param>
/// <param name="userName">用户名</param>
/// <param name="x">x坐标</param>
/// <param name="y">y坐标</param>
public static void InputUser(this IBrowser browser, string userName, double? x, double? y)
{
browser.ClickElement(x, y, true);
Thread.Sleep(100);
browser.Input(userName);//输入帐号
Thread.Sleep(300);
}
/// <summary>
/// 输入密码
/// </summary>
/// <param name="browser"></param>
/// <param name="pass"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public static void InputPass(this IBrowser browser, string pass, double? x, double? y)
{
browser.ClickElement(x, y, true);
Thread.Sleep(100);
browser.Input(pass);//输入帐号
Thread.Sleep(300);
}
/// <summary>
/// 判断标签是否存在
/// </summary>
/// <param name="browser">浏览器对象</param>
/// <param name="tag">标签(NodeName)</param>
/// <param name="document">html文档(xpath才技持)</param>
/// <returns></returns>
public static bool IsQuerySelector(this IBrowser browser, string tag, string document = "document")
{
var isXPath = Regex.IsMatch(tag, "(^//.*)");
if (isXPath)
{
string script = "(function(){";
script += "var doc= document.evaluate(\"" + tag.Replace("\"", "'") + "\","+ document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;";
script += @"if(doc == null) return null;
let result =JSON.stringify({ data:true });
return result;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
if (result == null) return false;
var response = result.Result;
if (response.Success && response.Result == null) return false;
return true;
}
else
{
string script = "(function(){";
script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");";
script += @"if(doc==null) return null;
let result =JSON.stringify({ data:true });
return result;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait(); //等待脚本执行完
var response = result.Result;
if (response.Success && response.Result == null) return false;
if (response.Result == null) return false;
return true;
}
}
/// <summary>
/// 发送鼠标滚轮事件
/// </summary>
/// <param name="browser">浏览器对象</param>
/// <param name="left">x</param>
/// <param name="top">y</param>
public static void SendMouseWheel(this IBrowser browser, double? left, double? top)
{
var host = browser.GetHost();
var x = Convert.ToInt32(left) + 5;
var y = Convert.ToInt32(top) + 5;
host.SendMouseWheelEvent(Convert.ToInt32(0), Convert.ToInt32(top), x, y, CefEventFlags.None);
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键
Thread.Sleep(50);
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键
}
/// <summary>
/// 滚动到指定元素上
/// </summary>
/// <param name="browser">浏览器对象</param>
/// <param name="tag">标签(NodeName)</param>
/// <param name="document">html文档(xpath才技持)</param>
/// <returns></returns>
private static bool ScrollIntoView(this IBrowser browser, string tag, string document = "document")
{
var isXPath = Regex.IsMatch(tag, "(^//.*)");
if (isXPath)
{
string script = "(function(){";
script += "var doc= document.evaluate(\"" + tag + "\","+ document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;";
script += @"if(doc != null){doc.scrollIntoView({block: 'center',behavior: 'smooth'}); return true};
return false;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
var response = result.Result;
if (response.Success && response.Result == null) return false;
if (response.Result == null) return false;
var bo = (bool)response.Result;
return bo;
}
else
{
string script = "(function(){";
script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");";
script += @"if(doc != null){doc.scrollIntoView({block: 'center',behavior: 'smooth'}); return true};
return false;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait(); //等待脚本执行完
var response = result.Result;
if (response.Success && response.Result == null) return false;
if (response.Result == null) return false;
var bo = (bool)response.Result;
return bo;
}
}
/// <summary>
/// 滚动到指定元素上
/// </summary>
/// <param name="browser"></param>
/// <param name="key">ini配置文件<k,v> k</param>
/// <param name="path">ini配置文件路径</param>
/// <param name="document"></param>
/// <returns></returns>
public static bool ScrollIntoView(this IBrowser browser, string key, string path, string document = "document")
{
string tagText = INIHelper.Read("tag", key, path);
tagText = string.IsNullOrWhiteSpace(tagText)
? INIHelper.Read("tagXPath", key, path)
: tagText;
var isLabel = browser.CheckLabel(tagText, document);
if (!isLabel) return false;
var bc = browser.ScrollIntoView(tagText, document);
if (bc == false) return false;
return bc;
}
/// <summary>
/// 检查标签是否存在
/// </summary>
/// <param name="browser">浏览器对象</param>
/// <param name="tag">标签(NodeName)</param>
/// <param name="document">html文档(xpath才技持)</param>
/// <returns></returns>
public static bool CheckLabel(this IBrowser browser, string tag, string document = "document")
{
var isXPath = Regex.IsMatch(tag, "(^//.*)");
bool isTrue = false;
if (isXPath)
{
isTrue = Policy
.Handle<Exception>()
.OrResult<bool>(r => r == false)
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
}).Execute(() =>
{
return browser.IsQuerySelector(tag, document);
});
return isTrue;
}
else
{
isTrue = Policy
.Handle<Exception>()
.OrResult<bool>(r => r == false)
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
}).Execute(() =>
{
return browser.IsQuerySelector(tag);
});
return isTrue;
}
}
/// <summary>
/// 检查标签是否存在
/// </summary>
/// <param name="browser">浏览器对象</param>
/// <param name="key">ini配置文件<k,v> k</param>
/// <param name="path">ini配置文件路径</param>
/// <param name="document">html文档(xpath才技持)</param>
/// <returns></returns>
public static bool CheckLabel(this IBrowser browser, string key, string path, string document = "document")
{
string tagText = INIHelper.Read("tag", key, path);//@"input[name=pass]";
tagText = string.IsNullOrWhiteSpace(tagText)
? INIHelper.Read("tagXPath", key, path)
: tagText;
var isXPath = Regex.IsMatch(tagText, "(^//.*)");
bool isTrue = false;
if (isXPath)
{
isTrue = Policy
.Handle<Exception>()
.OrResult<bool>(r => r == false)
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
}).Execute(() =>
{
return browser.IsQuerySelector(tagText, document);
});
return isTrue;
}
else
{
isTrue = Policy
.Handle<Exception>()
.OrResult<bool>(r => r == false)
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
}).Execute(() =>
{
return browser.IsQuerySelector(tagText);
});
return isTrue;
}
}BoundingClientRect类:
[Serializable]
public class BoundingClientRect
{
public double? x { get; set; }
public double? y { get; set; }
public double? r { get; set; }
public double? b { get; set; }
}用法:
chromeBrowser.GetBrowser().GetBoundingClientRect("button[name=login]")
评论区