不能使用String.Contains();

时间:2014-01-03 15:47:25

标签: c# .net

我想要做的是将alexa.com上列出的前500个网站存储到.txt文件中。
以下是该计划的运作方式。

当我的.net浏览器访问alexa的一个页面时,它会将所有链接存储到一个html集合中 然后,我使用循环来查明链接的文本是否包含“。” 如果是,则将url存储到.txt文件中。

问题是,String.Contains();不起作用,我也会存储无用的信息 为什么String.Contains();不起作用?

错误消息:未将对象引用设置为对象的实例。

重要部分

Robot.cs

public HtmlElementCollection page_elements
{
    get;
    set;
}

public void exec_task()
{
    var url_to_txtfile = new StreamWriter("urls.txt", true);

    foreach (HtmlElement element in page_elements)
    {
        string element_text = element.InnerText;
        if (element_text.Contains(".")) // Object reference not set to an instance of an object.
            url_to_txtfile.WriteLine(element_text);
    }

    url_to_txtfile.Close();

    next_page();
}

Form1.cs的

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    Bot.page_elements = webBrowser1.Document.GetElementsByTagName("a");
    Bot.pages_visited++;

    if (Bot.pages_visited <= Bot.pages_to_visit)
    {
        Bot.exec_task();
        webBrowser1.Url = new Uri(Bot.url);
    }

}

源代码

Robot.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AlexaBot
{
    class Robot
    {

        public Robot(string link, byte pages, byte items)
        {
            url = link;

            pages_to_visit = pages;
            link_per_page = items;

            pages_visited = -1;
        }

        public byte pages_to_visit
        {
            get;
            set;
        }

        private byte link_per_page
        {
            get;
            set;
        }

        public sbyte pages_visited
        {
            get;
            set;
        }

        public string url
        {
            get;
            set;
        }

        public HtmlElementCollection page_elements
        {
            get;
            set;
        }

        public void exec_task()
        {
            var url_to_txtfile = new StreamWriter("urls.txt", true);

            foreach (HtmlElement element in page_elements)
            {
                string element_text = element.InnerText;
                if (element_text.Contains("."))
                    url_to_txtfile.WriteLine(element_text);
            }

            url_to_txtfile.Close();

            next_page();
        }

        private void next_page()
        {
            if (pages_visited < 11)
                url = url.Remove(url.Length - 1) + pages_visited.ToString();
            else
                url = url.Remove(url.Length - 2) + pages_visited.ToString();
        }
    }
}

Form1.cs的

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

namespace AlexaBot
{
    public partial class Form1 : Form
    {
        Robot Bot;

        public Form1()
        {
            InitializeComponent();
            Bot = new Robot("http://www.alexa.com/topsites/global;0", 20, 25);
            webBrowser1.Url = new Uri(Bot.url);
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            Bot.page_elements = webBrowser1.Document.GetElementsByTagName("a");
            Bot.pages_visited++;

            if (Bot.pages_visited <= Bot.pages_to_visit)
            {
                Bot.exec_task();
                webBrowser1.Url = new Uri(Bot.url);
            }

        }
    }
}

1 个答案:

答案 0 :(得分:7)

string.Contains()效果很好。该错误告诉您对象为null,并且您无法取消引用null对象。所以在这一行:

if (element_text.Contains("."))

显然element_textnull。你应该将它包装在一个空检查中,也许就像这样简单:

if (!string.IsNullOrWhiteSpace(element_text))
    if (element_text.Contains("."))

(或者,对于旧版本的.NET,请改用string.IsNullOrEmpty()。)

page_elements可能包含很多的HTML元素,并非所有HTML元素都具有InnerText值。那些没有的将是null。您可以在此处进行额外的过滤以缩小搜索范围,包括使用更成熟的DOM解析器(如问题评论中所述)。