在 C# 中获取 JavaScript/HTML 变量的值
Posted
技术标签:
【中文标题】在 C# 中获取 JavaScript/HTML 变量的值【英文标题】:Getting the value of JavaScript/HTML variables in C# 【发布时间】:2018-07-04 00:21:46 【问题描述】:我正在尝试从中提取数据的网页。通过查看页面 Source 中的 html,我可以在 script 标签中找到我感兴趣的数据。 如下所示:
<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# 代码。
【问题讨论】:
gon
是否会具有确定性值?您确定它不会从其他变量、用户输入或 AJAX 请求中填充其成员吗?
对 C# Webbrowser 了解不多,但如果您可以调用 javascript JSON.stringify(gon)
可能会有所帮助,然后解析 json 字符串
@charleifl :我假设您的意思是将行 var Myjson = JSON.stringify(gon) 添加到 javascript?不幸的是,我根本无法编辑源 html/javascript。
@AI.G. : 在这种情况下,给定一个特定的 url,'gon' 的值不应该改变
你试过this问题的答案中给出的技术吗?
【参考方案1】:
您可以将 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
*/
【讨论】:
【参考方案2】:您需要使用JSON.stringify 将您的gon.books_jsonarray
变量转换为JSON 字符串
在您可以使用下一个C#
代码检索 JSON 之后:
var gonFromJS = mydoc.InvokeScript("eval", new object[] "JSON.stringify(gon.books_jsonarray)" ).ToString();
在您可以使用 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 主题:here 和 here。
如果 JSON.stringify
方法返回 null 然后尝试将下一个代码添加到您的 HTML 页面:
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' >
</head>
【讨论】:
以上是关于在 C# 中获取 JavaScript/HTML 变量的值的主要内容,如果未能解决你的问题,请参考以下文章
使用 Twitter Bootstrap、C#、asp.net 和 javascript 上传文件
有没有办法使用 Javascript/HTML5 从 USB 设备获取 GPS 位置?