javascript - 在 C# 中获取 JavaScript/HTML 变量的值

标签 javascript c# html web

我正尝试从一个网页中提取数据。通过查看页面源中的 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
            */
    }
}

关于javascript - 在 C# 中获取 JavaScript/HTML 变量的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48431235/

相关文章:

javascript - 使用 Google Prettify 显示 HTML

c# - 如何使用 Visual Studio Code 从 .NET Core 访问 Nuget 存储库

html - 如何将图像放在html页面的中心?

jquery - 在悬停/鼠标悬停时,文本不会随页内滚动条移动

javascript - 如何以编程方式触发 Mapbox GL JS Geocoder?

javascript - jQuery slider 与浏览器的兼容性

javascript - ckeditor 值不被 asp.net 和 vb.net 识别

c# - C# 中的协议(protocol)抽象

c# - ASP.NET MVC - 填充常用的下拉列表

javascript - JQuery 触发器不适用于生成的元素