65.9K
CodeProject 正在变化。 阅读更多。
Home

简单的网页检查(爬虫)

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (9投票s)

2007年1月10日

CPOL

2分钟阅读

viewsIcon

29349

downloadIcon

660

一个小应用程序,用于检查网站列表中的指定文本

Sample Image - WebPageCheck.gif

引言

待办事项:一个应用程序,用于检查列表中的站点是否存在,以及(如果存在)是否包含指定的文本!

我设计了一个 GUI,如上图所示。界面有三个多行文本框

  1. txtImitialList(要检查的 URL 列表将粘贴在此处,每行一个 URL)
  2. txtGood(如果检查结果为正 - 页面存在并包含我们搜索的文本 - URL 将出现在此处)
  3. txtBad(坏页面 - 检查结果为负)

我们还需要一个文本框来放置我们要查找的文本:txtMustContain,以及一个复选框(区分大小写检查或不检查)。

最后.... btnStart,一个启动进程的按钮!主要工作由这个只有一个 static 函数的类完成

public static string WebFetch(string url)

这个函数接收一个 string 参数,即页面的 URL,并将其源作为 string 返回。

using System;
using System.Text;
using System.Net;
using System.IO;

namespace WindowsApplication1
{
    class WebFetchClass
    {
        public static string WebFetch(string url)
        {
            // used to build entire input
            StringBuilder sb = new StringBuilder();

            // used on each read operation
            byte[] buf = new byte[8192];

            // prepare the web page we will be asking for
            HttpWebRequest request = (HttpWebRequest)
                WebRequest.Create(url);

            // execute the request
            HttpWebResponse response = (HttpWebResponse)
                request.GetResponse();

            // we will read data via the response stream
            Stream resStream = response.GetResponseStream();

            string tempString = null;
            int count = 0;

            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);

                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    tempString = Encoding.ASCII.GetString(buf, 0, count);

                    // continue building the string
                    sb.Append(tempString);
                }
            }
            while (count > 0); // any more data to read?

            // return page source
            return sb.ToString();
        }
    }
}

不要忘记包含命名空间 System.Net(用于 HttpWebResponseHttpWebRequest)和 System.IO(用于 stream 函数)

using System.Net;
using System.IO;

form1.cs 文件中,我编写了三个函数(为了更容易理解程序)。每个函数在一些小的差异下完成几乎相同的工作。

这三个函数是

  • CheckPageLoad()          //check only if specified page exists on server 
  • DoCheckCaseSensitive()   //DoCheck() - case Sensitive
  • DoCheck()                // Case Insensitive check for specified text 

此函数的代码如下

private void CheckPageLoad()
        {
            int totalLinks;
            int count = 0;
            url_arr = txtImitialList.Text.Split('\n');
            totalLinks = url_arr.Length;

            for (int i = 0; i < totalLinks; i++)
            {
                count++;
                try
                {
                    if (WebFetchClass.WebFetch(url_arr[i]).Trim().Length > 10)
                        txtGood.Text += url_arr[i] + "\n";
                    else
                        txtBad.Text += url_arr[i] + "\n";
                    txtBad.Update();
                    txtGood.Update();
                }
                catch
                {
                    txtBad.Text += url_arr[i] + "\n";
                    txtBad.Update();
                }
                lblStatusCurrentPos.Text = count.ToString() + "/" + 
                        totalLinks.ToString();
                this.Update();
            }
        }
        private void DoCheckCaseSensitive()
        {
            int totalLinks;
            int count = 0;
            string to_check = txtMustContain.Text.Trim();
            url_arr = txtImitialList.Text.Split('\n');
            totalLinks = url_arr.Length;

            for (int i = 0; i < totalLinks; i++)
            {
                count++;
                try
                {
                    if (WebFetchClass.WebFetch(url_arr[i]).Trim().IndexOf(to_check) > 0)
                        txtGood.Text += url_arr[i] + "\n";
                    else
                        txtBad.Text += url_arr[i] + "\n";
                    txtBad.Update();
                    txtGood.Update();
                }
                catch
                {
                    txtBad.Text += url_arr[i] + "\n";
                    txtBad.Update();
                }
                lblStatusCurrentPos.Text = count.ToString() + "/" + 
                    totalLinks.ToString();
                this.Update();
            }
        }
        private void DoCheck()
        {
            int totalLinks;
            int count = 0;
            string to_check = txtMustContain.Text.Trim().ToLower();
            url_arr = txtImitialList.Text.Split('\n');
            totalLinks = url_arr.Length;

            for (int i = 0; i < totalLinks; i++)
            {
                count++;
                try
                {
                    if (WebFetchClass.WebFetch(url_arr[i]).Trim().ToLower().IndexOf
                                (to_check) > 0)
                        txtGood.Text += url_arr[i] + "\n";
                    else
                        txtBad.Text += url_arr[i] + "\n";
                    txtBad.Update();
                    txtGood.Update();
                }
                catch
                {
                    txtBad.Text += url_arr[i] + "\n";
                    txtBad.Update();
                }
                lblStatusCurrentPos.Text = count.ToString() + "/" + 
                    totalLinks.ToString();
                this.Update();
            }
        }

好的...现在让我们启动应用程序:开始按钮!

private void btnStart_Click(object sender, EventArgs e)

这是按下开始按钮时引发的事件。让我们为该事件编写一些代码

private void btnStart_Click(object sender, EventArgs e)
        {
            //clear (if exist) previews data(s)
            txtBad.Clear();
            txtGood.Clear();
            lblStatusCurrentPos.Text = "Starting...";
            

            if (txtMustContain.Text.Trim() == "")
            {
                //TODO: CheckPageLoad()
                Thread t = new Thread(new ThreadStart(CheckPageLoad));
                t.IsBackground = true;
                t.Start();
                return;
            }

            if (chkCaseSensitive.Checked)
            {
                //TODO: DoCheckCaseSensitive()
                Thread t = new Thread(new ThreadStart(DoCheckCaseSensitive));
                t.IsBackground = true;
                t.Start();
            }
            else
            {
                //TODO: DoCheck()
                Thread t = new Thread(new ThreadStart(DoCheck));
                t.IsBackground = true;
                t.Start();
            }
        }

如您所见,我在一个单独的线程中运行访问 Web 的函数,因为我不想在进程运行时冻结主窗口。

这是一个非常简单的应用程序,没有错误检查。可以通过添加更多线程或错误检查来改进它。

历史

  • 2007 年 1 月 10 日:初始发布
© . All rights reserved.