簡體   English   中英

在C#中獲取JavaScript / HTML變量的值

[英]Getting the value of JavaScript/HTML variables in C#

我正在嘗試從中提取數據的網頁。 通過查看頁面Source中的HTML,我可以在腳本標記中找到我感興趣的數據。 它看起來如下:

<html>
<script type="text/javascript">

window.gon = {};
gon.default_profile_mode = false; 
gon.user = null;  
gon.product = "shoes";
gon.books_jsonarray = [
{
    "title": "Little Sun",
    "authors": [
        "John Smith"
    ],
    edition: 2,
    year: 2009
},
{
    "title": "Little Prairie",
    "authors": [
        "John Smith"
    ],
    edition: 3,
    year: 2009
},
{
    "title": "Little World",
    "authors": [
        "John Smith",
        "Mary Neil",
        "Carla Brummer"
    ],
    edition: 3,
    year: 2014
}
];

</script>
</html>

我想要實現的是,使用其URL調用網頁,然后從JavaScript中檢索'gon'變量並將其存儲在C#變量中。 換句話說,在C#中,我希望有一個數據結構(例如字典),它將保存'gon'的值。

我已經嘗試過研究如何通過C#WebBrowser獲取JavaScript中定義的變量,這就是我發現的:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using mshtml;

namespace Mynamespace
{

  public partial class Form1 : Form
  {
    public WebBrowser WebBrowser1 = new WebBrowser();

    private void Form1_Load(object sender, EventArgs e)
    {
        string myurl = "http://somewebsite.com"; //Using WebBrowser control to load web page   
        this.WebBrowser1.Navigate(myurl);
    }    


    private void btnGetValueFromJs_Click(object sender, EventArgs e)
    {
        var mydoc = this.WebBrowser1.Document;
        IHTMLDocument2 vDocument = mydoc.DomDocument as IHTMLDocument2;
        IHTMLWindow2 vWindow = (IHTMLWindow2)vDocument.parentWindow;
        Type vWindowType = vWindow.GetType();
        object strfromJS = vWindowType.InvokeMember("mystr",
                            BindingFlags.GetProperty, null, vWindow, new object[] { }); 
//Here, I am able to see the string "Hello Sir"

        object gonfromJS = vWindowType.InvokeMember("gon",
                            BindingFlags.GetProperty, null, vWindow, new object[] { }); 
//Here, I am able to see the object gonfromJS as a '{System.__ComObject}'

        object gonbooksfromJS = vWindowType.InvokeMember("gon.books_jsonarray",
                            BindingFlags.GetProperty, null, vWindow, new object[] { }); 
//This error is thrown: 'An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll; (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))'

    }

  }
}

我能夠檢索字符串或數字變量的值,例如:

var mystr = "Hello Sir";
var mynbr = 8;

但是,即使我能夠看到'gon'變量作為'{System .__ ComObject}'傳遞,我也不知道如何解析它以查看其子組件的值。 如果我可以解析它會很好,但如果沒有,我想要的是一個C#數據結構,其中的鍵/值包含gon變量的所有子信息,尤其是能夠查看變量'gon.books_jsonarray'。

任何有關如何實現這一目標的幫助將非常感激。 請注意,我無論如何都無法更改源html / javascript,因此,我需要的是一個C#代碼,可以實現我的目標。

您可以將InvokeMember()的結果轉換為動態,並直接在C#代碼中使用屬性名稱。 數組索引很棘手但可以通過另一種InvokeScript()來完成,請參閱我的示例:

private void btnGetValueFromJs_Click(object sender, EventArgs e)
{
    var mydoc = this.WebBrowser1.Document;
    IHTMLDocument2 vDocument = mydoc.DomDocument as IHTMLDocument2;
    IHTMLWindow2 vWindow = (IHTMLWindow2)vDocument.parentWindow;
    Type vWindowType = vWindow.GetType();

    var gonfromJS = (dynamic)vWindowType.InvokeMember("gon",
                        BindingFlags.GetProperty, null, vWindow, new object[] { });

    var length = gonfromJS.books_jsonarray.length;

    for (var i = 0; i < length; ++i)
    {
        var book = (dynamic) mydoc.InvokeScript("eval", new object[] { "gon.books_jsonarray[" + i + "]" });
        Console.WriteLine(book.title);
        /* prints:
            * Little Sun
            * Little Prairie
            * Little World
            */
    }
}
  1. 您需要使用JSON.stringify將您的gon.books_jsonarray變量轉換為JSON字符串

  2. 在使用下一個C#代碼檢索JSON之后:

    var gonFromJS = mydoc.InvokeScript(“eval”,new object [] {“JSON.stringify(gon.books_jsonarray)”})。ToString();

  3. 在使用Newtonsoft.Json將JSON反序列化為對象之后

我的完整代碼在這里:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var webBrowser = new WebBrowser();

            webBrowser.DocumentCompleted += (s, ea) =>
            {
                var mydoc = webBrowser.Document;
                var gonFromJS = mydoc.InvokeScript("eval", new object[] { "JSON.stringify(gon.books_jsonarray)" }).ToString();
                var gonObject = JsonConvert.DeserializeObject<List<Books>>(gonFromJS);
            };

            var myurl = "http://localhost/test.html";
            webBrowser.Navigate(myurl);
        }

        private class Books
        {
            public string Title { get; set; }
            public List<string> Authors { get; set; }
            public int Edition { get; set; }
            public int Year { get; set; }
        }
    }
}

您還可以在屏幕截圖上看到輸出: 在此輸入圖像描述

編輯

您也可能遇到JSON.stringify方法的問題。

它可以返回null

在這種情況下,您可以查看SO主題: 此處此處

如果JSON.stringify方法返回null,則嘗試將下一個代碼添加到HTML頁面:

<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' >
</head>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM