我正在使用 Essential 对象库来读取网站。
我之前曾使用 Windows Forms WebBrowser 完成此操作,但这次该网站无法使用 Windows Forms WebBrowser 运行,因此我不得不更改为 EO WebView。
纪录片太差了,我找不到答案。
在 Windows 窗体 Web 浏览器中,您有一个 HtmlElementCollection,原则上它是 HtmlElement 的列表。 在这些元素上,您可以读出属性或创建 InvokeMember("Click") 并浏览子/父元素。
EO WebView 中与此 HtmlElementCollection/HtmlElement 等效的是什么? 如何浏览 HTML 树?
顺便说一句:我将它与 C# 一起使用。
最佳答案
本质上,你必须依赖执行 JavaScript 的能力。
您可以通过多种方式访问文档 JavaScript 对象:
JSObject document = (JSObject)_webView.EvalScript("document");
//or: Document document = _webView.GetDOMWindow().document;
GetDOMWindow()
返回一个 EO.WebBrowser.DOM.Document
实例;该类型派生自 JSObject
并提供一些额外的属性(例如,有一个 body
属性可以获取 EO.WebBrowser.DOM.Element< 类型的 BODY 元素
)。
但总的来说,这些提供的 API 并没有丰富多少。
你可以像这样使用 JSObject:
// access a property on the JavaScript object:
jsObj["children"]
// access an element of an array-like JavaScript object:
var children = (JSObject)jsObj["children"];
var first = (JSObject)children[0];
// (note that you have to cast; all these have the `object` return type)
// access an attribute on the associated DOM element
jsObj.InvokeFunction("getAttribute", "class")
// etc.
这一切都有点繁琐,但是您可以编写一些扩展方法来让您的生活更轻松(但是,请参阅下面有关性能的注释):
public static class JSObjectExtensions
{
public static string GetTagName(this JSObject jsObj)
{
return (jsObj["tagName"] as string ?? string.Empty).ToUpper();
}
public static string GetID(this JSObject jsObj)
{
return jsObj["id"] as string ?? string.Empty;
}
public static string GetAttribute(this JSObject jsObj, string attribute)
{
return jsObj.InvokeFunction("getAttribute", attribute) as string ?? string.Empty;
}
public static JSObject GetParent(this JSObject jsObj)
{
return jsObj["parentElement"] as JSObject;
}
public static IEnumerable<JSObject> GetChildren(this JSObject jsObj)
{
var childrenCollection = (JSObject)jsObj["children"];
int childObjectCount = (int)childrenCollection["length"];
for (int i = 0; i < childObjectCount; i++)
{
yield return (JSObject)childrenCollection[i];
}
}
// Add a few more if necessary
}
然后你可以这样做:
private void TraverseElementTree(JSObject root, Action<JSObject> action)
{
action(root);
foreach(var child in root.GetChildren())
TraverseElementTree(child, action);
}
以下是如何使用此方法的示例:
TraverseElementTree(document, (currentElement) =>
{
string tagName = currentElement.GetTagName();
string id = currentElement.GetID();
if (tagName == "TD" && id.StartsWith("codetab"))
{
string elementClass = currentElement.GetAttribute("class");
// do something...
}
});
但是,这又有点繁琐 - 虽然这似乎工作得相当好,但您需要进行一些实验以找到可能导致错误的任何棘手部分,并找出如何修改方法来实现它更稳定。
性能说明
另一种选择是使用 JavaScript 进行大部分元素处理,并仅返回需要在 C# 代码中使用的值。根据逻辑的复杂程度,这在某些情况下可能会更有效,因为它会导致单个浏览器引擎往返,因此如果性能成为问题,则需要考虑。 (请参阅“性能”部分 here。)
关于c# - 基本对象 WebView 如何在 HTML 树中导航?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61455398/