2012-02-29 6 views
15

WinForm Webブラウザで.NET 3.5/4.0を使用してHTML要素を検査することは可能ですか?.NET WebBrowser - FireBugスタイルHTML要素の検査

IHighlightRenderingServices InterfaceまたはHtml Agility Packを使用している可能性がありますか?

私は、アプリケーションが放火犯のように機能したいと思います:

は、単にあなたがマウスを使って検査し、それをクリックする要素を置きます。 1.7以前のバージョンのFirebugでは、自動的にHTMLパネルに切り替わり、ノードビュー内の適切な要素を選択します。

Inspect Element

EDIT:

うわー、私はちょうど私がやろうとしている正確に何である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"; 
     }   
    } 

enter image description here

AxWebBrowserをHtmlAgilityPackと連携させるために、WebClientクラスを使用してURLをロードした後、HtmlAgilityPackで解析します。

私はちょうどWebスクレーパーで終了しました。これは、Visual Web Ripperと同様に、$ 1,000 +を要する他のすべての機能を果たします。

enter image description here

+0

私はあなたのコードのサンプルを持っていますか? – Amir

答えて

0

私はあなたがHtmlAgillityパックでそれを行うことはできないと思います。私がそう思っている理由は、ブラウザのメモリに多くのことが起こるということです(javascriptのためなど)。したがって、JavaScriptの結果でレンダリングされるすべての要素が欠落します。 JSを介して動的にスタイルが適用されることもありません。

おそらく、mshtml(Microsoft HTML、mshtmlの場合はgoogleを検索)を使用し、Document_Loadedイベントでは、ドキュメント内のすべての要素を繰り返して、javascriptでマウスを追加して強調表示します。次に、現在選択されているCSSクラスまたは適用された特定のボーダープロパティを持つDOM内で見つかった要素を取得し、そのプロパティを繰り返して検査します。

0

Firebug Liteは、元のFirebugと非常によく似た機能を備えています。

2

私は実際にこれを前に行っています。あなたは文書をIExpandoにキャストしなければなりません。そしてそれに対してリフレクションコールを行い、メンバーを得ることができます。私は実際にDynamicNodeクラスを作成しました。このクラスを使用すると、動的キーワードを使用してドキュメントとやりとりすることができます。

あなたはかかわらず、代わりにMSHTML COMオブジェクトを使用することがあります:var window = (IExpando)document.parentWindow;Reusing MSHTML

  1. はIExpandoにvar document = new mshtml.HTMLDocument();
  2. キャストのインスタンスを作成します
  3. COMの参照リストにMSHTMLへの参照を追加します。
  4. 動的オブジェクトラッパーを作成する(下記参照)
  5. 動的キーワードを使用して、ドキュメントとやり取りします。たとえば、

ここに私の動的なノードである:

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から彼らと対話することができます。 jsを文字列として評価し、.net関数を呼び出すこともできます。ここでの用法のいくつかのコードスニペットは、次のとおりです。

は取得とjsオブジェクトのメンバを設定する:

this.host.Window.eval(@" Foo = { }; "); 

var foo = this.host.Window.Foo; 
foo.B = 7.11; 
Assert.Equal(7.11, foo.B); 

JSのC#から関数を呼び出す:文書に.NETオブジェクトを挿入し、そのを呼び出す

this.host.eval("function add(x, y) { return x + y; }"); 
var z = (int)this.host.Window.add(7, 11); 
Assert.Equal(7 + 11, z); 

を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); 

Scripから継承するオブジェクトのみを貼り付けることができますtObjectをドキュメントに挿入します(上記のコードブロックで定義されています)。私はあなたがそこに何かを置くことができると思いますが、IReflectを実装していないと、あなたは奇妙な行動を取るでしょう。

関連する問題