我创建了一个简单的网络抓取工具,但我想添加递归功能,以便打开的每个页面都可以获取此页面中的网址,但我不知道我该怎么做,我还要包括线程使它更快 这是我的代码
namespace Crawler
{
public partial class Form1 : Form
{
String Rstring;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
WebRequest myWebRequest;
WebResponse myWebResponse;
String URL = textBox1.Text;
myWebRequest = WebRequest.Create(URL);
myWebResponse = myWebRequest.GetResponse();//Returns a response from an Internet resource
Stream streamResponse = myWebResponse.GetResponseStream();//return the data stream from the internet
//and save it in the stream
StreamReader sreader = new StreamReader(streamResponse);//reads the data stream
Rstring = sreader.ReadToEnd();//reads it to the end
String Links = GetContent(Rstring);//gets the links only
textBox2.Text = Rstring;
textBox3.Text = Links;
streamResponse.Close();
sreader.Close();
myWebResponse.Close();
}
private String GetContent(String Rstring)
{
String sString="";
HTMLDocument d = new HTMLDocument();
IHTMLDocument2 doc = (IHTMLDocument2)d;
doc.write(Rstring);
IHTMLElementCollection L = doc.links;
foreach (IHTMLElement links in L)
{
sString += links.getAttribute("href", 0);
sString += "/n";
}
return sString;
}
答案 0 :(得分:8)
我修复了你的GetContent方法,如下所示:从抓取的网页获取新链接:
public ISet<string> GetNewLinks(string content)
{
Regex regexLink = new Regex("(?<=<a\\s*?href=(?:'|\"))[^'\"]*?(?=(?:'|\"))");
ISet<string> newLinks = new HashSet<string>();
foreach (var match in regexLink.Matches(content))
{
if (!newLinks.Contains(match.ToString()))
newLinks.Add(match.ToString());
}
return newLinks;
}
<强>更新强>
修正:正则表达式应该是regexLink。感谢@shashlearner指出这一点(我的错误)。
答案 1 :(得分:7)
我使用Reactive Extension创建了类似的东西。
https://github.com/Misterhex/WebCrawler
我希望它可以帮到你。
Crawler crawler = new Crawler();
IObservable observable = crawler.Crawl(new Uri("http://www.codinghorror.com/"));
observable.Subscribe(onNext: Console.WriteLine,
onCompleted: () => Console.WriteLine("Crawling completed"));
答案 2 :(得分:2)
以下内容包括答案/建议。
我相信您应该使用dataGridView
代替textBox
,因为当您在GUI中查看它时,更容易看到找到的链接(网址)。
你可以改变:
textBox3.Text = Links;
到
dataGridView.DataSource = Links;
现在提出问题,你没有包括:
using System. "'s"
使用了哪些,因为如果我能够得到它们,我将不胜感激。
答案 3 :(得分:0)
从设计的角度来看,我写了几个webcrawler。基本上,您希望使用堆栈数据结构实现深度优先搜索。您也可以使用广度优先搜索,但您可能会遇到堆栈内存问题。祝你好运。