核心方法:使用 HttpWebRequest (推荐)

这是最标准、最灵活的方法,它允许你以编程方式向任何 URL 发送 HTTP 请求,并获取响应内容(包括 HTML 源代码)。

silverlight获取网页源代码
(图片来源网络,侵删)

基本步骤:

  1. 创建 HttpWebRequest 实例:使用 HttpWebRequest.Create 方法,传入目标 URL。
  2. 设置请求头 (可选但推荐):可以设置 User-Agent 等头信息,模拟浏览器访问,避免被某些网站拦截。
  3. 获取响应流:调用 GetResponse() 方法获取 HttpWebResponse 对象,然后从该对象获取响应流 (.GetResponseStream())。
  4. :使用 StreamReader 将流中的数据读取为字符串。
  5. 异步处理:由于网络请求是 I/O 密集型操作,为了不阻塞 UI 线程,强烈建议使用异步方法 (BeginGetResponse / EndGetResponse 或 .NET 4.5+ 的 async/await)。

代码示例 (使用 .NET 4.5+ 的 async/await)

这是现代 Silverlight 应用中最推荐的方式,代码简洁清晰。

using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
namespace SilverlightWebScraper
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            this.Loaded += MainPage_Loaded;
        }
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // 示例:获取 bing.com 的首页源代码
            string url = "http://www.bing.com";
            GetWebSourceCodeAsync(url);
        }
        public async void GetWebSourceCodeAsync(string url)
        {
            try
            {
                // 1. 创建 HttpWebRequest
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
                // 2. (可选) 设置请求头,模拟浏览器
                request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36";
                request.Accept = "text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8";
                // 3. 异步获取响应
                // await 会在此处暂停,直到网络请求完成,不会阻塞UI线程
                HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
                // 4. 使用 StreamReader 读取响应流
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    string sourceCode = await reader.ReadToEndAsync();
                    // 5. 在 UI 上显示结果
                    // 注意:UI 更新必须在 UI 线程上执行
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        ResultTextBlock.Text = sourceCode;
                    });
                }
            }
            catch (WebException ex)
            {
                // 处理网络错误,如 404 Not Found, 500 Server Error 等
                MessageBox.Show("网络请求失败: " + ex.Message);
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    ResultTextBlock.Text = "错误: " + ex.Message;
                });
            }
            catch (Exception ex)
            {
                // 处理其他异常
                MessageBox.Show("发生未知错误: " + ex.Message);
            }
        }
    }
}

XAML 界面 (MainPage.xaml)

<UserControl x:Class="SilverlightWebScraper.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="800" Height="600">
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="ResultTextBlock" TextWrapping="Wrap" IsReadOnly="True" VerticalScrollBarVisibility="Auto" Margin="10"/>
    </Grid>
</UserControl>

其他方法

使用 WebClient (简单场景)

WebClientHttpWebRequest 的一个更高级的封装,对于简单的 GET 请求非常方便。

优点:代码更简洁。 缺点:灵活性较低,难以自定义复杂的请求头。

silverlight获取网页源代码
(图片来源网络,侵删)
using System.Net;
using System.Windows;
// ...
public void GetWebSourceCodeWithWebClient(string url)
{
    WebClient client = new WebClient();
    // 设置 User-Agent
    client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0...";
    // DownloadString 会同步阻塞线程,在 Silverlight 中非常不推荐!
    // 应该使用 DownloadStringAsync
    client.DownloadStringCompleted += (sender, e) =>
    {
        if (e.Error == null)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                ResultTextBlock.Text = e.Result;
            });
        }
        else
        {
            MessageBox.Show("下载失败: " + e.Error.Message);
        }
    };
    // 异步开始下载
    client.DownloadStringAsync(new Uri(url));
}

获取当前宿主页面的源代码 (Limited Use Case)

如果你想在 Silverlight 中获取当前 Silverlight 应用所在的那个 HTML 页面的源代码,可以使用 HtmlPage 类。

注意:这不是获取任意网页源代码的方法,它只能获取承载 Silverlight 插件的那个页面。

using System.Windows.Browser; // 需要引入此命名空间
// ...
// 获取当前页面的 Document 对象
HtmlDocument doc = HtmlPage.Document;
// 获取页面的完整 HTML 源代码
string currentPageSource = doc.DocumentElement.GetAttribute("outerHTML");
// 显示结果
ResultTextBlock.Text = currentPageSource;

重要注意事项和限制

  1. 跨域安全策略

    • 这是 Silverlight 中最重要的限制,出于安全考虑,Silverlight 应用默认只能向其宿主域名的服务器发起请求。
    • 例如:如果你的 Silverlight 应用托管在 www.mywebsite.com 上,那么它默认只能请求 www.mywebsite.com 下的资源,而不能直接请求 www.google.com 的资源。
    • 解决方案:如果你需要请求其他域名的资源,目标服务器必须在响应头中明确允许跨域请求,这通过设置 Access-Control-Allow-Origin 头来实现。
      • 如果目标服务器是 Apache,可以通过 .htaccess 文件设置。
      • 如果目标服务器是 IIS,可以通过 web.config 文件设置。
      • 允许任何来源:Access-Control-Allow-Origin: *
      • 或者只允许特定来源:Access-Control-Allow-Origin: http://www.mywebsite.com
  2. UI 线程

    silverlight获取网页源代码
    (图片来源网络,侵删)
    • 所有与 UI 相关的操作(如修改 TextBlockText 属性)都必须在 UI 线程上执行。
    • 网络请求是异步的,当请求完成时,代码可能运行在后台线程,在更新 UI 前,必须使用 Deployment.Current.Dispatcher.BeginInvokeDeployment.Current.Dispatcher.Invoke 将代码调度回 UI 线程,上面的示例已经展示了这一点。
  3. HTTPS 和证书

    默认情况下,Silverlight 只信任受信任根证书机构颁发的 SSL 证书,如果目标网站使用的是自签名证书,请求会失败,如果必须访问这类站点,可能需要更复杂的证书处理逻辑。

  4. 浏览器兼容性

    • Silverlight 本身是跨浏览器的,但 HttpWebRequest 的行为在不同浏览器中可能存在细微差别。User-Agent 字符串也可能因浏览器和版本而异。
方法 适用场景 优点 缺点
HttpWebRequest 通用、推荐,适用于任何需要自定义请求、处理复杂响应的场景。 灵活性最高,功能最强大,是 .NET 网络编程的标准。 代码相对繁琐,需要手动处理异步和 UI 线程。
WebClient 简单的 GET/POST 请求。 代码简洁,易于使用。 灵活性低,难以处理复杂的 HTTP 头和认证。
HtmlPage 获取当前宿主页面的源代码。 非常简单,无需网络请求。 用途非常有限,无法获取外部网页。

对于绝大多数“获取网页源代码”的需求,请优先使用 HttpWebRequest 结合 async/await 模式,这是最健壮和可维护的解决方案,务必处理好跨域策略UI 线程问题。