Рекурсивный скребок для ссылок c # - PullRequest
3 голосов
/ 30 июля 2011

Я борюсь с этим целый день и не могу понять это.У меня есть функция, которая дает мне список всех ссылок на определенный URL.Это отлично работает.Однако я хочу сделать эту функцию рекурсивной, чтобы она искала ссылки, найденные при первом поиске, добавляла их в список и продолжала, чтобы она прошла через все мои страницы на сайте.Как я могу сделать это рекурсивным?

Мой код:

class Program
{
public static List<LinkItem> urls;
private static List<LinkItem> newUrls = new List<LinkItem>();

static void Main(string[] args)
{
  WebClient w = new WebClient();
  int count = 0;
  urls = new List<LinkItem>();
  newUrls = new List<LinkItem>();
  urls.Add(new LinkItem{Href = "http://www.smartphoto.be", Text = ""});

  while (urls.Count > 0)
  {
    foreach (var url in urls)
    {
      if (RemoteFileExists(url.Href))
      {
        string s = w.DownloadString(url.Href);
        newUrls.AddRange(LinkFinder.Find(s));
      }
    }
    urls = newUrls.Select(x => new LinkItem{Href = x.Href, Text=""}).ToList();
    count += newUrls.Count;
    newUrls.Clear();
    ReturnLinks();
  }

  Console.WriteLine();
  Console.Write("Found: " + count + " links.");
  Console.ReadLine();
}

private static void ReturnLinks()
{
  foreach (LinkItem i in urls)
  {
    Console.WriteLine(i.Href);
    //ReturnLinks();
  }
}

private static bool RemoteFileExists(string url)
{
  try
  {
    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    request.Method = "HEAD";
    //Getting the Web Response.
    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
    //Returns TURE if the Status code == 200
    return (response.StatusCode == HttpStatusCode.OK);
  }
  catch
  {
    return false;
  }
}
}

Код LinkFinder.Find можно найти здесь: http://www.dotnetperls.com/scraping-html

Кто-нибудь знает, как я могуили сделать эту функцию рекурсивной или я могу сделать функцию ReturnLinks рекурсивной?Я предпочитаю не трогать метод LinkFinder.Find, так как он отлично работает для одной ссылки, я просто должен вызывать его столько раз, сколько необходимо для расширения моего окончательного списка URL.

Ответы [ 2 ]

2 голосов
/ 30 июля 2011

Я предполагаю, что вы хотите загрузить каждую ссылку и найти ее внутри, и продолжать, пока у вас не закончатся ссылки?

Поскольку существует вероятность того, что глубина рекурсии может стать очень большой, я бы избежал рекурсии, это должно сработать, я думаю.

WebClient w = new WebClient();
int count = 0;    
urls = new List<string>();
newUrls = new List<LinkItem>();
urls.Add("http://www.google.be"); 

while (urls.Count > 0)
{
    foreach(var url in urls)
    {
        string s = w.DownloadString(url);
        newUrls.AddRange(LinkFinder.Find(s));
    }
    urls = newUrls.Select(x=>x.Href).ToList();
    count += newUrls.Count;
    newUrls.Clear();
    ReturnLinks();
}

Console.WriteLine();
Console.Write("Found: " + count + " links.");
Console.ReadLine();
1 голос
/ 30 июля 2011
static void Main()
{
    WebClient w = new WebClient();

    List<ListItem> allUrls = FindAll(w.DownloadString("http://www.google.be"));
}

private static List<ListItem> FindAll(string address)
{
    List<ListItem> list = new List<ListItem>();

    foreach (url in LinkFinder.Find(address))
    {
        list.AddRange(FindAll(url.Address)));//or url.ToString() or what ever the string that represents the address
    }

    return list;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...