0

我有兴趣检查网站的内容,内容经常变化,当我在任何浏览器上查看网站时,它每 30 秒刷新一次。我想知道内容何时发生了变化。

我正在使用winforms,我只想每30秒单击一个按钮来启动一个循环。我不想太频繁地访问网站,事实上网页本身的刷新已经足够满足我的需要了。

我的代码在我单击按钮 (btnCheckWebsite) 时有效,如果我稍等片刻然后再次单击 btnCheckWebsite,我的消息框会弹出,因为网页已更改。这很好,但是我想在 while 循环中执行此操作。当我取消注释我的 while 循环时, DocumentText 永远不会改变。我已经对其进行了调试,由于某种原因,它每次都是相同的文本,即使网页在现实世界中发生了变化,它在我的代码中也保持不变。

所以我的问题是为什么我不能使用循环,我可以做些什么来重复运行它而不需要我的任何输入?

作为奖励,我想删除我添加的 .Refresh() ,因为没有它它就无法工作,但是据我所知,这会刷新整个页面。当我使用浏览器时,即使我没有刷新整个页面,我也会看到页面更新。

仅作为背景信息,我确实首先在我的表单上有一个 WebBrowser 控件,页面会自动刷新。我使用了相同的代码并且遇到了同样的问题,有趣的是,我的 Windows 窗体上的 WebBrowser 控件自行刷新没问题,直到我单击 btnCheckWebsite 然后它停止刷新!我也知道 webrequest,但我不知道如何将它用于我的目的。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Check_Website
{
    public partial class Form1 : Form
    {
        public WebBrowser _memoryWebBrowser = new WebBrowser();
        String _previousSource = "emptySource";

        public Form1()
        {
            InitializeComponent();

           _memoryWebBrowser.Navigate(new Uri("http://www.randomurl.com/"));

        }

        private void btnCheckWebsite_Click(object sender, EventArgs e)
        {
            //I want to un-comment this while loop and let my code run itself but it stops working
            //when I introduce my while loop.

            //while (1 < 2 )
            //{
                //Thread.Sleep(30000);

                checkWebsite();

            //}
        }

        private void checkWebsite()
        {
            //Why do I need this refresh? I would rather not have to hit the web page with a refresh.
            //When I view the webpage it refreshed with new data however when I use a WebBrowser
            //the refresh just doesn't happen unless I call Refresh.
            _memoryWebBrowser.Refresh();

            Thread.Sleep(500);

            while (((_memoryWebBrowser.ReadyState != WebBrowserReadyState.Complete) || (_memoryWebBrowser.DocumentText.Length < 3000)))
            {
                Thread.Sleep(1000);
            }


            String source = _memoryWebBrowser.DocumentText;

            if ((source != _previousSource) && (_previousSource != "emptySource"))
            {
                //Hey take a look at the interesting new stuff on this web page!!
                MessageBox.Show("Great news, there's new stuff on this web page www.randomurl.co.uk!!" );
            }

            _previousSource = source;

        }
    }
}
4

4 回答 4

1

您需要对DocumentCompleted事件进行处理。此事件是异步的,因此如果您想在循环中执行此操作,执行线程必须泵送消息以触发此事件。在 WinFroms 应用程序中,您的 UI 线程已经在Applicaiton.Run输入消息,并且在同一线程上进入嵌套消息循环的唯一其他认可方式是通过模态表单(这是如何完成的,请参阅评论)。另一种(IMO,更好的)在没有嵌套消息循环的情况下执行此类Navigate/DocumentCompleted逻辑的方法是使用async/await这里是 how。在经典意义上,这并不完全是一个循环,但从概念上和句法上讲,它可能正是您正在寻找的。

于 2013-08-22T22:06:19.590 回答
0

您可以捕获 WebBrowser.Navigated 事件以在重新加载页面时获得通知。所以你不需要一个循环。(我的意思是就绪循环)

只需每 30 秒循环一次导航到页面,在导航事件中,您可以检查站点是否已更改。

于 2013-08-22T20:23:05.750 回答
0

你最好连接 DocumentCompleted 事件来检查它的 DocumentText 属性!

于 2013-08-22T20:25:50.740 回答
0

WebBrowser 元素有很多错误,并且有很多开销可以满足您的需求。相反,您应该使用 WebRequest。因为您说您不知道如何使用,所以这里有一个(工作)示例供您使用。

using System;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace Check_Website
{
    public partial class Form1 : Form
    {
        String _previousSource = string.Empty;
        System.Windows.Forms.Timer timer;

        private System.Windows.Forms.CheckBox cbCheckWebsite;
        private System.Windows.Forms.TextBox tbOutput;

        public Form1()
        {
            InitializeComponent();

            this.cbCheckWebsite = new System.Windows.Forms.CheckBox();
            this.tbOutput = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // cbCheckWebsite
            // 
            this.cbCheckWebsite.AutoSize = true;
            this.cbCheckWebsite.Location = new System.Drawing.Point(12, 12);
            this.cbCheckWebsite.Name = "cbCheckWebsite";
            this.cbCheckWebsite.Size = new System.Drawing.Size(80, 17);
            this.cbCheckWebsite.TabIndex = 0;
            this.cbCheckWebsite.Text = "checkBox1";
            this.cbCheckWebsite.UseVisualStyleBackColor = true;
            // 
            // tbOutput
            // 
            this.tbOutput.Location = new System.Drawing.Point(12, 35);
            this.tbOutput.Multiline = true;
            this.tbOutput.Name = "tbOutput";
            this.tbOutput.Size = new System.Drawing.Size(260, 215);
            this.tbOutput.TabIndex = 1;
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.tbOutput);
            this.Controls.Add(this.cbCheckWebsite);
            this.Name = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

            timer = new System.Windows.Forms.Timer();
            timer.Interval = 30000;
            timer.Tick += timer_Tick;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            if (!cbCheckWebsite.Checked) return;

            WebRequest request = WebRequest.Create("http://localhost/check_website.html");
            request.Method = "GET";

            WebResponse response = request.GetResponse();

            string newContent;
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                newContent = sr.ReadToEnd();
            }

            tbOutput.Text += newContent + "\r\n";

            if (_previousSource == string.Empty)
            {
                tbOutput.Text += "Nah. It's empty";
            }
            else if (_previousSource == newContent)
            {
                tbOutput.Text += "Nah. Equals the old content";
            }
            else
            {
                tbOutput.Text += "Oh great. Something happened";
            }

            _previousSource = newContent;
        }
    }
}
于 2013-08-23T00:02:44.490 回答