Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2447

CODE-透過WPF WebBrowser執行JavaScript

$
0
0

計劃在WPF內嵌WebBrowser元件,並透過JavaScript取得網頁元素資訊。經過一番研究,總算試出解法,簡單筆記如下: (以擷取Google新聞網站的焦點新聞為例)

  1. 在WPF加入WebBrowser,指定Source連向Google新聞URL,另一項重點則是要指定LoadCompleted事件,該事件會在網頁載入完成後觸發,某些動作(例如: 在網頁上執行JavaScript)必須在網頁載入後執行才不致出錯。
    <Windowx: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>
    <WebBrowserx:Name="browser"
    VerticalAlignment="Stretch"HorizontalAlignment="Stretch"
    Source="http://news.google.com.tw/"
    LoadCompleted="bowser_LoadCompleted"/>
    </Grid>
    </Window>
  2. 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
    {
    publicpartialclass MainWindow : Window
        {
    public MainWindow()
            {
                InitializeComponent();
            }
     
    privatevoid 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)]
    publicclass ScriptHelper
            {
    public Action<string> ProcMessage = null;
    publicvoid SendMessage(string msg)
                {
    if (ProcMessage != null)
                        ProcMessage(msg);
                }
            }
    private ScriptHelper sh = new ScriptHelper();
    #endregion
     
    privatevoid Window_Loaded_1(object sender, RoutedEventArgs e)
            {
    //指定ObjectForScripting,網頁可透過window.external存取該物件
                browser.ObjectForScripting = sh;
            }
        }
    }

執行程式,就能成功用WPF抓出網頁內容囉~


Viewing all articles
Browse latest Browse all 2447

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>