2012-05-04 8 views
8

Stworzyłem prostego robota sieciowego, ale chcę dodać funkcję rekursji, aby każda strona, która jest otwarta, mogła uzyskać adresy URL na tej stronie, ale nie mam pojęcia, jak mogę to zrobić i chcę również zawierać wątki zrobić to szybciej tutaj jest mój kodProsty robot sieciowy w 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

Głosuj, aby zamknąć jako pytanie niedostatecznie uporządkowane. Rozważ wyszukanie "robota sieciowego w języku C#" i dopracowanie zapytania, aby było bardziej ukierunkowane. –

+0

Zdecydowanie nie chcesz używać rekurencji, ponieważ nie będziesz w stanie utrzymywać stanu Internetu na lokalnym stosie. Możesz użyć stosu, jak sugerował Tom, ale powinieneś odwrócić kolejność, w której dodajesz AbsoluteUris do być zaindeksowane, w przeciwnym razie rodzaj stosu sprawi, że będziesz indeksować od dołu strony i jeśli zamierzasz napisać przeszukiwacz, musisz mieć zachowanie pobierania pasujące do przeglądarki tak blisko, jak to możliwe. Kolejka to lepszy wybór. Kolejność PriorityQueue jest jeszcze lepsza. –

+0

kolejka priorytetowa https://svn.arachnode.net/svn/arachnodenet/trunk/Structures/PriorityQueue.cs login/hasło: Publiczny/Public –

Odpowiedz

8

Naprawiłem metodę getContent jak postępować, aby uzyskać nowe linki z indeksowanych stronie:

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

Updated

Naprawiono: regex powinno być regexLink. Dzięki @shashlearner za wskazanie tego (mój błąd).

+0

Unikanie problemu stosowania wyrażeń regularnych do analizowania HTML, ale to się nie zgadza. –

+1

Co to jest regexLink? – SLearner

+0

regex powinno być regexLink, dzięki @shashlearner za wskazanie tego –

2

Poniżej znajduje się odpowiedź/zalecenie.

Uważam, że powinieneś używać dataGridView zamiast textBox, ponieważ gdy patrzysz na to w GUI, łatwiej jest zobaczyć znalezione linki (URL).

Można zmienić:

textBox3.Text = Links; 

do

dataGridView.DataSource = Links; 

teraz pytanie, nie obejmowały:

using System. "'s" 

, które z nich zostały wykorzystane, ponieważ byłoby to doceniam, gdybym mógł je zdobyć, ponieważ nie mogę tego rozgryźć.

0

Z punktu widzenia projektowania napisałem kilka webcrawlerów. Zasadniczo chcesz zaimplementować Głębokie pierwsze wyszukiwanie przy użyciu struktury danych stosu. Możesz także użyć opcji Pierwsze wyszukiwanie również, ale prawdopodobnie pojawią się problemy z pamięcią stosu. Powodzenia.

+2

Uważam, że PO chce więcej szczegółów. –

7

Stworzyłem coś podobnego za pomocą Reactive Extension.

https://github.com/Misterhex/WebCrawler

mam nadzieję, że może pomóc.

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

Wow! To dość prosta składnia. Czy to wielowątkowe? W każdym razie bardzo łatwe do strawienia - Wygląda bardzo podobnie do javascript. – FredTheWebGuy