[英]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
*/
}
}
您需要使用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
。
如果JSON.stringify
方法返回null,則嘗試將下一個代碼添加到HTML頁面:
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' >
</head>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.