我想要做的是将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);
}
}
}
}
答案 0 :(得分:7)
string.Contains()
效果很好。该错误告诉您对象为null
,并且您无法取消引用null
对象。所以在这一行:
if (element_text.Contains("."))
显然element_text
是null
。你应该将它包装在一个空检查中,也许就像这样简单:
if (!string.IsNullOrWhiteSpace(element_text))
if (element_text.Contains("."))
(或者,对于旧版本的.NET,请改用string.IsNullOrEmpty()
。)
page_elements
可能包含很多的HTML元素,并非所有HTML元素都具有InnerText
值。那些没有的将是null
。您可以在此处进行额外的过滤以缩小搜索范围,包括使用更成熟的DOM解析器(如问题评论中所述)。