内容简介:http://stackoverflow.com/questions/9502968/net-webbrowser-firebug-style-inspect-html-element
是否可以使用.NET 3.5 / 4.0检查WinForm Web浏览器中的HTML元素?
可能使用IHighlightRenderingServices接口或Html敏捷包?
我希望应用程序的功能像FireBug:
只需用鼠标悬停要检查的元素,然后单击它.在1.7之前的Firebug版本中,它自动切换到HTML面板,并在节点视图中选择适当的元素.
编辑:
哇,我刚刚碰到了 http://www.selectorgadget.com/ 这正是我想要做的.在Javascript中,在过去2个小时内查看源代码后,我仍然没有一个线索如何将其并入我的程序…
从我可以告诉它使用DOM元素的标记和递归分析来计算CSS选择器路径: http://www.selectorgadget.com/stable/lib/dom.js .
编辑:好的我已经将selectorgadget加载到我的应用程序.它允许您选择与Firebug完全相同的HTML元素!甚至创建Xpath查询.
但是,我正在使用AxWebBrowser,我坚持使用HtmlAgilityPack …
private void xpathQuery_Click(object sender, EventArgs e) { // Load Browser HtmlWindow window = axWebBrowser1.Document.Window; // <---- 'object' does not contain a definition for 'Window' string str = window.Document.Body.OuterHtml; // Load HTML HtmlAgilityPack.HtmlDocument HtmlDoc = new HtmlAgilityPack.HtmlDocument(); HtmlDoc.LoadHtml(str); //Process Xpath Query HtmlAgilityPack.HtmlNodeCollection Nodes = HtmlDoc.DocumentNode.SelectNodes(xpathText.Text); //Print in Text box foreach (HtmlAgilityPack.HtmlNode Node in Nodes) { richTextBox1.Text += Node.OuterHtml + "\r\n"; } }
编辑:
我不能让AxWebBrowser与HtmlAgilityPack一起工作,所以我只是使用WebClient类加载URL,然后用HtmlAgilityPack解析它.
我刚刚完成了Web Scraper.它的功能与Visual Web Ripper和所有其他价格为$1,000的其他功能类似.
我以前做过这样的事情.您必须将文档转换为IExpando,那么您可以对其进行反射调用以获取成员.我实际上创建了一个DynamicNode类,它允许您使用dynamic关键字与文档进行交互.
您可能想要使用mshtml COM对象,而不是: Reusing MSHTML
>在COM参考列表中添加对mshtml的引用
>创建一个var document = new mshtml.HTMLDocument()的实例;
>转换为IExpando:var window =(IExpando)document.parentWindow;
>创建动态对象包装器(见下文)
>使用动态关键字与文档交互.
例如这里是我的动态节点:
class DynamicNode : DynamicObject, IExpando, IEnumerable { private IExpando value; public DynamicNode(IExpando value) { this.value = value; } public override bool TryUnaryOperation(UnaryOperationBinder binder, out object result) { switch (binder.Operation) { case System.Linq.Expressions.ExpressionType.Convert: case System.Linq.Expressions.ExpressionType.ConvertChecked: result = this.value; return true; } return base.TryUnaryOperation(binder, out result); } public override IEnumerable<string> GetDynamicMemberNames() { return this.value .GetMembers(BindingFlags.Instance | BindingFlags.Public) .Select(m => m.Name) .Distinct() .ToArray(); } public override bool TryConvert(ConvertBinder binder, out object result) { result = this.value; return true; } public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { if (indexes.Length == 1) { var memberName = indexes[0].ToString(); result = ReflectionHelpers.GetValue(this.value, memberName); result = DynamicNode.Wrap(result); return true; } return base.TryGetIndex(binder, indexes, out result); } public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) { if (indexes.Length == 1) { var memberName = indexes[0].ToString(); value = DynamicNode.Unwrap(value); ReflectionHelpers.SetValue(this.value, memberName, value); return true; } return base.TrySetIndex(binder, indexes, value); } public override bool TryGetMember(GetMemberBinder binder, out object result) { if (base.TryGetMember(binder, out result)) return true; result = ReflectionHelpers.GetValue(this.value, binder.Name); result = DynamicNode.Wrap(result); return true; } public override bool TrySetMember(SetMemberBinder binder, object value) { ReflectionHelpers.SetValue(this.value, binder.Name, value); return true; } public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { if (binder.Name == "New") { var constructorArgs = new object[args.Length - 1]; Array.ConstrainedCopy(args, 1, constructorArgs, 0, constructorArgs.Length); result = ReflectionHelpers.New(this.value, (string)args[0], constructorArgs); } else { result = ReflectionHelpers.Invoke(this.value, binder.Name, args); } result = DynamicNode.Wrap(result); return true; } public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { IExpando self = this.value; object[] constructorArgs = new object[0]; if (args.Length > 0) { self = (IExpando)DynamicNode.Unwrap(args[0]); constructorArgs = new object[args.Length - 1]; Array.ConstrainedCopy(args, 1, constructorArgs, 0, constructorArgs.Length); } result = ReflectionHelpers.Call(this.value, self, constructorArgs); result = DynamicNode.Wrap(result); return true; } private static object Wrap(object value) { if (value != null && Marshal.IsComObject(value)) value = new DynamicNode((IExpando)value); return value; } public static object Unwrap(object value) { DynamicNode node = value as DynamicNode; if (node != null) return node.value; return value; } public IEnumerator GetEnumerator() { var members = this.value.GetProperties(BindingFlags.Public | BindingFlags.Instance); var indexProperties = new List<Tuple<int, PropertyInfo>>(); var isArray = true; foreach (var member in members) { int value = 0; if (!int.TryParse(member.Name, out value)) { isArray = false; break; } var propertyMember = member as PropertyInfo; if (propertyMember != null) indexProperties.Add(Tuple.Create(value, propertyMember)); } if (isArray) { indexProperties.Sort((left, right) => left.Item1.CompareTo(right.Item1)); foreach (var prop in indexProperties) yield return prop.Item2.GetValue(this.value, null); } else { foreach (var member in members) yield return member.Name; } } #region IExpando FieldInfo IExpando.AddField(string name) { return this.value.AddField(name); } MethodInfo IExpando.AddMethod(string name, Delegate method) { return this.value.AddMethod(name, method); } PropertyInfo IExpando.AddProperty(string name) { return this.value.AddProperty(name); } void IExpando.RemoveMember(MemberInfo m) { this.value.RemoveMember(m); } FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr) { return this.value.GetField(name, bindingAttr); } FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr) { return this.value.GetFields(bindingAttr); } MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr) { return this.value.GetMember(name, bindingAttr); } MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr) { return this.value.GetMembers(bindingAttr); } MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr) { return this.value.GetMethod(name, bindingAttr); } MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { return this.value.GetMethod(name, bindingAttr, binder, types, modifiers); } MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr) { return this.value.GetMethods(bindingAttr); } PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr) { return this.value.GetProperties(bindingAttr); } PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { return this.value.GetProperty(name, bindingAttr, binder, returnType, types, modifiers); } PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr) { return this.value.GetProperty(name, bindingAttr); } object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters) { return this.value.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); } Type IReflect.UnderlyingSystemType { get { return this.value.UnderlyingSystemType; } } #endregion } [ComVisible(true)] public class ScriptObject : IReflect, IExpando { private readonly Type type; private dynamic _constructor; private dynamic _prototype; public ScriptObject() { type = this.GetType(); } [DispId(0)] protected virtual object Invoke(object[] args) { return "ClrObject"; } public dynamic constructor { get { return _constructor; } set { this._constructor = value; } } public dynamic prototype { get { return _prototype; } set { this._prototype = value; } } public string toString() { return "ClrObject"; } #region IReflect Members MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { return type.GetMethod(name, bindingAttr, binder, types, modifiers); } MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr) { return type.GetMethod(name, bindingAttr); } protected virtual MethodInfo[] GetMethods(BindingFlags bindingAttr) { return type.GetMethods(bindingAttr); } MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr) { return GetMethods(bindingAttr); } FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr) { return type.GetField(name, bindingAttr); } FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr) { return new FieldInfo[0]; // type.GetFields(bindingAttr); } PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr) { return type.GetProperty(name, bindingAttr); } PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { return type.GetProperty(name, bindingAttr, binder, returnType, types, modifiers); } protected virtual PropertyInfo[] GetProperties(BindingFlags bindingAttr) { return type.GetProperties(bindingAttr); } PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr) { return GetProperties(bindingAttr); } MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr) { return type.GetMember(name, bindingAttr); } MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr) { return type.GetMembers(bindingAttr); } protected virtual object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) { if (name == "[DISPID=0]") { return this.Invoke(args); } return type.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); } object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) { return this.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); } Type IReflect.UnderlyingSystemType { get { return type.UnderlyingSystemType; } } #endregion #region IExpando Members public FieldInfo AddField(string name) { throw new NotImplementedException(); } public MethodInfo AddMethod(string name, Delegate method) { throw new NotImplementedException(); } public PropertyInfo AddProperty(string name) { throw new NotImplementedException(); } public void RemoveMember(MemberInfo m) { throw new NotImplementedException(); } #endregion } public static class ReflectionHelpers { private const BindingFlags DefaultFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; public static object New(this IExpando scope, string functionName, params object[] args) { var constructor = (IExpando)scope.GetValue(functionName); var proto = constructor.GetValue("prototype"); var obj = (IExpando)scope.GetValue("Object"); var instance = (IExpando)obj.Invoke("create", new object[] { proto }); Call(constructor, instance, args); return instance; } public static object Call(this IExpando function, IExpando scope, params object[] args) { object[] callArgs = new object[args.Length + 1]; callArgs[0] = scope; Array.Copy(args, 0, callArgs, 1, args.Length); return Invoke(function, "call", callArgs); } public static void SetValue(this IExpando instance, string propertyName, object value) { if (instance == null) throw new ArgumentNullException("instance"); if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("Must specify a value.", "propertyName"); Invoke(instance, propertyName, InvokeFlags.DISPATCH_PROPERTYPUT, new object[] { value }); } public static object GetValue(this IExpando instance, string propertyName) { return Invoke(instance, propertyName, InvokeFlags.DISPATCH_PROPERTYGET, new object[0]); } public static object Invoke(this IExpando instance, string functionName, object[] args) { if (instance == null) throw new ArgumentNullException("instance"); if (string.IsNullOrEmpty(functionName)) throw new ArgumentException("Must specify a value.", "functionName"); return Invoke(instance, functionName, InvokeFlags.DISPATCH_METHOD, args); } private static object Invoke(IExpando instance, string functionName, InvokeFlags flags, object[] args) { try { args = args.Select(arg => DynamicNode.Unwrap(arg)).ToArray(); switch (flags) { case InvokeFlags.DISPATCH_METHOD: var method = instance.GetMethod(functionName, DefaultFlags); return method.Invoke(instance, args); case InvokeFlags.DISPATCH_PROPERTYGET: var getProp = instance.GetProperty(functionName, DefaultFlags); return getProp.GetValue(instance, null); case InvokeFlags.DISPATCH_PROPERTYPUT: case InvokeFlags.DISPATCH_PROPERTYPUTREF: var setProp = instance.GetProperty(functionName, DefaultFlags); if (setProp == null) setProp = instance.AddProperty(functionName); setProp.SetValue(instance, args[0], null); return null; default: throw new NotSupportedException(); } } catch (COMException comex) { switch ((uint)comex.ErrorCode) { // Unexpected script error. This will be handled by the IProcess.UnhandledException event case 0x80020101: return null; default: throw; } } } private enum InvokeFlags { DISPATCH_METHOD = 1, DISPATCH_PROPERTYGET = 2, DISPATCH_PROPERTYPUT = 4, DISPATCH_PROPERTYPUTREF = 8, } }
实际上,您可以将.net对象以这种方式粘贴到文档中,或者从.net中提取对象并与其进行交互.您也可以将eval作为字符串,并将其调用为.net函数.以下是一些用法的代码片段:
获取和设置一个js对象的成员:
this.host.Window.eval(@" Foo = { }; "); var foo = this.host.Window.Foo; foo.B = 7.11; Assert.Equal(7.11, foo.B);
从C#调用js函数:
this.host.eval("function add(x, y) { return x + y; }"); var z = (int)this.host.Window.add(7, 11); Assert.Equal(7 + 11, z);
将.net对象插入文档并从js调用其成员:
this.host.Window.Custom2 = new Custom2(); this.host.Window.eval(@" function test() { return Custom2.Test().Value; }"); bool success = this.host.Window.test(); Assert.True(success);
您只能将继承自ScriptObject的对象粘贴到文档(但是在上面的代码块中定义).好吧,我想你可以把任何东西放在那里,但是如果不实施IReflect,你会得到奇怪的行为.
http://stackoverflow.com/questions/9502968/net-webbrowser-firebug-style-inspect-html-element
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- WPF从代码后面设置命名样式元素?
- 使用CSS定义页面元素的外观样式
- 「前篇」JavaScript如何获取一个元素的样式信息
- JS 的平凡之路 -- 我们到底可以通过多少种方式修改元素样式
- 微软对 Chromium 新贡献:为 HTML 元素引入更现代化样式
- 1.6 常用CSS样式2:其它样式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Wikis For Dummies
Dan Woods、Peter Thoeny / For Dummies / 2007-7-23 / USD 24.99
Corporations have finally realized the value of collaboration tools for knowledge sharing and Wiki is the open source technology for creating collaborative Web sites, as either a public site on the In......一起来看看 《Wikis For Dummies》 这本书的介绍吧!