CODE-透過WPF WebBrowser執行JavaScript
3 | 19,085 |
計劃在WPF內嵌WebBrowser元件,並透過JavaScript取得網頁元素資訊。經過一番研究,總算試出解法,簡單筆記如下: (以擷取Google新聞網站的焦點新聞為例)
- 在WPF加入WebBrowser,指定Source連向Google新聞URL,另一項重點則是要指定LoadCompleted事件,該事件會在網頁載入完成後觸發,某些動作(例如: 在網頁上執行JavaScript)必須在網頁載入後執行才不致出錯。
排版顯示純文字<Window x:Class="TestWebBrowser.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded_1">
<Grid>
<WebBrowser x:Name="browser"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Source="http://news.google.com.tw/"
LoadCompleted="bowser_LoadCompleted" />
</Grid>
</Window>
- C#部分程式有幾個重點:
1) 宣告一個ScriptHelper類別(必須為ComVisible),提供Method供網頁透過JavaScript呼叫
2) 在Window Loaded事件中將ScriptHelper設為WebBrowser的ObjectForScripting物件
3) 網頁載入完成時,可透過WebBrowser.InvokeScript(function_name, arg1, arg2…)呼叫網頁內的JavaScript函數。但因為我們要執行的是自訂程式作業,故藉用windows.eval()傳入要執行的JavaqScript程式字串當參數,如此達到執行任意指令的效果。
4) 由於先前指定了ScriptHelper做為溝通物件,在JavaScript中可透過window.external.SendMessage()觸發ScriptHelper的SendMessage方法,將結果傳回.NET端。
完整程式碼如下:
排版顯示純文字using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Navigation;
namespace TestWebBrowser
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void bowser_LoadCompleted(object sender, NavigationEventArgs e)
{
//加入ProcMessage事件,處理傳回字串
sh.ProcMessage = (s) =>
{
MessageBox.Show(s);
};
//執行Script,取得熱門新聞,注意: 必須要在網頁載入完成後才可呼叫
browser.InvokeScript("eval", @"
var list = document.getElementsByClassName('top-stories-section')[0]
.getElementsByTagName('h2');
var news = [];
for (var i = 0; i < list.length; i++) {
news.push(list[i].getElementsByTagName('span')[0].innerHTML);
}
window.external.SendMessage(news.join('\n'));
");
}
#region 供從WebBrowser網頁呼叫C#方法的溝通物件
[ComVisible(true)]
public class ScriptHelper
{
public Action<string> ProcMessage = null;
public void SendMessage(string msg)
{
if (ProcMessage != null)
ProcMessage(msg);
}
}
private ScriptHelper sh = new ScriptHelper();
#endregion
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
//指定ObjectForScripting,網頁可透過window.external存取該物件
browser.ObjectForScripting = sh;
}
}
}
執行程式,就能成功用WPF抓出網頁內容囉~
Comments
# by debbie@asrc.tw
Good!
# by DEREK
請問,有出現錯誤訊息,是因為來源格式改變所影起的嗎??
# by Jeffrey
to DEREK,有錯誤訊息可以參考嗎?