【问题标题】:Scraping web page source code for windows phone applicationwindows phone 应用抓取网页源代码
【发布时间】:2012-01-22 22:53:17
【问题描述】:

我对使用 C# for WP7 进行开发非常陌生。我正在尝试编写一个简单的应用程序,它将从 textBox1 获取 url,并在按下 button1 时使用该页面的源代码更新 textBlock1 中的文本。

我坚持的部分是如何将 DownloadStringCallback2 中的 Result 传递回 LoadSiteContent 函数,以便它可以作为变量 sourceCode 返回。

代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace TestApp1
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            string url = textBox1.Text;
            string sourceCode = LoadSiteContent(url);
            textBlock1.Text = sourceCode;
        }

        /// <summary>
        /// method for retrieving information from a specified URL
        /// </summary>
        /// <param name="url">url to retrieve data from</param>
        /// <returns>source code of URL</returns>
        public string LoadSiteContent(string url)
        {
            //create a new WebClient object
            WebClient client = new WebClient();

            //create a byte array for holding the returned data
            string sourceCode = "Fail";
            client.DownloadStringCompleted += new    DownloadStringCompletedEventHandler(DownloadStringCallback2);
           client.DownloadStringAsync(new Uri(url));

           //use the UTF8Encoding object to convert the byte
           //array into a string
           //UTF8Encoding utf = new UTF8Encoding();

           //return the converted string
           //return utf.GetString(html, 0, html.Length);
           return sourceCode;
        }

        private static void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
        {
           // If the request was not canceled and did not throw
           // an exception, display the resource.
           if (!e.Cancelled && e.Error == null)
           {
               string textString = (string)e.Result;
           } 
        }
    }
}

【问题讨论】:

    标签: c# windows-phone-7 asynchronous event-handling webclient


    【解决方案1】:

    您无法按照自己的意愿进行操作,因为 WP7 (silverlight) 中的所有 Web 请求都是异步的。 这意味着代码在下载网页时不会停止,在同一行和函数中完成后继续,而是创建一个新线程,下载文件并调用回调函数。

    您必须继续使用回调函数(在您的情况下为 DownloadStringCallback2)。 在该函数中,您必须将源代码(e.Result)放入文本框中。

    如果您遇到跨线程异常,或者您希望在执行任务时保持 UI 正常可用,我可以补充一下,您可以使用以下命令:

    Dispatcher.BeginInvoke(new Action (() => LoadContent("http://www.google.com")));
    

    这个命令修复了跨线程异常(如果我没记错的话)并在与 UI 线程不同的线程上执行代码,从而保持稳定的 UI。

    编辑我认为你的代码应该是这样的:

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            string url = textBox1.Text;
            LoadSiteContent(url);
        }
    
        public string LoadSiteContent(string url)
        {
            //create a new WebClient object
            WebClient client = new WebClient();
    
            client.DownloadStringCompleted += new    DownloadStringCompletedEventHandler(DownloadStringCallback2);
           client.DownloadStringAsync(new Uri(url));
        }
    
        private static void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
        {
           // If the request was not canceled and did not throw
           // an exception, display the resource.
           if (!e.Cancelled && e.Error == null)
           {
               textBlock1.Text = (string)e.Result;
               //If you get the cross-thread exception then use the following line instead of the above
               //Dispatcher.BeginInvoke(new Action (() => textBlock1.Text = (string)e.Result));
           } 
        }
    

    【讨论】:

    • 我将回调函数更新为如下所示:资源。 if (!e.Cancelled && e.Error == null) { textBlock1.Text = (string)e.Result; } }` 我收到错误消息:非静态字段、方法或属性“TestApp1.MainPage.textBlock1”需要对象引用你知道我做错了什么吗?
    • 之所以这样说是因为您正在尝试编辑 MainPage 上的 textBlock1,并且因为您的回调函数是静态的,所以它不知道 textBlock1。我处理这个问题的方法是使用委托。由于异步事件,委托在 wp7 中非常有用,如果您不知道它们,我建议您查找它们。您还可以添加public static MainPage mainPage; 并将其填充到mainPage = this; 之类的构造函数中,然后您可以使用它用mainPage.textBlock1.Text = (string)e.Result; 填充textBlock1。可能有更简单的方法,但我无法测试 atm。
    • 我才意识到我从未跟进过这篇文章。您的建议非常有帮助,我会投票赞成您的答案,但我是新用户。感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2015-11-08
    • 2016-03-22
    • 1970-01-01
    相关资源
    最近更新 更多