我正在使用基本对象库来读取网站。
我以前在上也这样做过,但是这次该网站没有使用,所以我不得不更改为EO webView。
这部纪录片太穷了,我找不到答案。
在webbrowser中,您有一个HtmlElementCollection,它原则上是一个HtmlElement列表。在这些元素上,您可以读取属性或创建一个InvokeMember("Click"),并在子元素/父元素中导航。
EO WebView与这个HtmlElementCollection / HtmlElement的等价性是什么?如何在HTML树中导航?
顺便说一句:我正在和C#一起使用它。
发布于 2020-05-04 22:52:12
本质上,您必须依赖于执行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#代码中使用的值。根据逻辑的复杂程度,这在某些情况下可能会更有效,因为它将导致一个浏览器引擎往返,因此如果性能成为问题,则需要考虑。(请参见性能部分这里。)
发布于 2021-10-19 08:23:27
由于这是处理EO.WebBrowser的元素/子问题的罕见问题之一,而且由于我对VB.NET更感兴趣,所以我很难完成上述工作。我花了相当长的时间才弄明白这一点,所以对于所有对VB.NET更感兴趣的人来说,下面是一些VB的等效工具。
访问文档并检索带有子元素的元素:
win = WebView1.GetDOMWindow()
doc = win.document
Dim element As EO.WebBrowser.DOM.Element = doc.getElementById("ddlSamples")访问类似数组的对象的元素:
Dim children = CType(element("children"), EO.WebBrowser.JSObject)
Dim childrenCount As Integer = CInt(children("length"))获取元素中所选的选项-子元素,并获取子元素的innerText:
Dim child As EO.WebBrowser.JSObject
Dim txt As String = Nothing
For c = 0 To childrenCount - 1
child = CType(children(c), EO.WebBrowser.JSObject)
If GetAttribute(child, "selected") = "selected" Then
txt = CStr(child("text"))
Exit For
End If
Next当然,声明'GetAttribute‘函数:
Public Shared Function GetAttribute(ByVal jsObj As EO.WebBrowser.JSObject, ByVal attribute As String) As String
Return If(TryCast(jsObj.InvokeFunction("getAttribute", attribute), String), String.Empty)
End Function希望人们能从中受益。
https://stackoverflow.com/questions/61455398
复制相似问题