2012-05-04 39 views
8

Tôi đã tạo một trình thu thập dữ liệu web đơn giản nhưng tôi muốn thêm chức năng đệ quy để mọi trang được mở tôi có thể nhận được các url trong trang này, nhưng tôi không biết làm cách nào tôi có thể làm điều đó và tôi cũng muốn bao gồm chủ đề để làm cho nó nhanh hơn ở đây nó là mã của tôiTrình thu thập dữ liệu web đơn giản trong C#

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

Bỏ phiếu để đóng câu hỏi không có phạm vi. Vui lòng xem xét tìm kiếm "trình thu thập dữ liệu web trong C#" và tinh chỉnh câu hỏi của bạn để được nhắm mục tiêu nhiều hơn. –

+0

Bạn chắc chắn không muốn sử dụng đệ quy vì bạn sẽ không thể giữ trạng thái của Internet trên ngăn xếp cục bộ. Bạn có thể sử dụng Ngăn xếp như Tom được đề xuất, nhưng bạn nên đảo ngược thứ tự mà bạn thêm AbsoluteUris vào được thu thập dữ liệu, nếu không thì bản chất của ngăn xếp sẽ khiến bạn thu thập dữ liệu từ cuối trang và nếu bạn định viết trình thu thập thông tin, bạn cần có hành vi truy xuất phù hợp với trình duyệt càng chặt chẽ càng tốt. Hàng đợi là một lựa chọn tốt hơn. Một PriorityQueue thậm chí còn tốt hơn. –

+0

PriorityQueue https://svn.arachnode.net/svn/arachnodenet/trunk/Structures/PriorityQueue.cs username/password: công cộng/Public –

Trả lời

8

tôi cố định phương pháp GetContent của bạn như sau để có được các liên kết mới từ trang bò:

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; 
} 

Cập nhật

Đã sửa lỗi: regex phải là regexLink. Cảm ơn @shashlearner vì đã chỉ ra điều này (my mistype).

+0

Tránh vấn đề sử dụng regexes cho phân tích cú pháp HTML nhưng không khớp được một chút. –

+1

RegexLink ở đây là gì? – SLearner

+0

regex nên là regexLink, nhờ @shashlearner để chỉ ra điều này –

2

Sau đây bao gồm câu trả lời/đề xuất.

Tôi tin rằng bạn nên sử dụng dataGridView thay vì textBox khi bạn xem nó trong GUI, việc tìm thấy liên kết (URL) dễ dàng hơn.

Bạn có thể thay đổi:

textBox3.Text = Links; 

để

dataGridView.DataSource = Links; 

Bây giờ cho các câu hỏi, bạn đã không bao gồm:

using System. "'s" 

nào đã được sử dụng, vì nó sẽ là đánh giá cao nếu tôi có thể nhận được chúng như không thể tìm ra.

0

Từ quan điểm thiết kế, tôi đã viết một vài webcrawlers. Về cơ bản, bạn muốn triển khai Depth First Search bằng cấu trúc dữ liệu Stack. Bạn cũng có thể sử dụng Breadth First Search, nhưng có thể bạn sẽ gặp phải vấn đề về bộ nhớ stack. Chúc may mắn.

+2

Tôi nghĩ rằng OP đang yêu cầu chi tiết hơn. –

7

tôi đã tạo một cái gì đó tương tự bằng cách sử dụng Reactive Extension.

https://github.com/Misterhex/WebCrawler

tôi hy vọng nó có thể giúp bạn.

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

Chà! Đó là một số cú pháp khá đơn giản. Đây có phải là đa luồng không? Dù trường hợp nào, rất dễ tiêu hóa- Trông rất giống javascript. – FredTheWebGuy

Các vấn đề liên quan