C#如何循环浏览列表、更新相同的列表并继续循环?
我正在写一个webscraper,它获取特定的URL并将它们添加到列表中C#如何循环浏览列表、更新相同的列表并继续循环?,c#,loops,for-loop,web-scraping,html-agility-pack,C#,Loops,For Loop,Web Scraping,Html Agility Pack,我正在写一个webscraper,它获取特定的URL并将它们添加到列表中 using HtmlAgilityPack; List<string> mylist = new List<string>(); var firstUrl = "http://example.com"; HtmlWeb web = new HtmlWeb(); HtmlDocument document = web.Load(firstUrl); HtmlNodeCollection nodes
using HtmlAgilityPack;
List<string> mylist = new List<string>();
var firstUrl = "http://example.com";
HtmlWeb web = new HtmlWeb();
HtmlDocument document = web.Load(firstUrl);
HtmlNodeCollection nodes = document.DocumentNode.SelectNodes("//div[contains(@class,'Name')]/a");
foreach (HtmlNode htmlNode in (IEnumerable<HtmlNode>)nodes)
{
if (!mylist.Contains(htmlNode.InnerText))
{
mylist.Add(htmlNode.InnerText);
}
}
使用HtmlAgilityPack;
List mylist=新列表();
var firstUrl=”http://example.com";
HtmlWeb web=新的HtmlWeb();
HtmlDocument document=web.Load(firstUrl);
HtmlNodeCollection nodes=document.DocumentNode.SelectNodes(//div[contains(@class,'Name'))]/a);
foreach(HtmlNode HtmlNode in(IEnumerable)节点)
{
如果(!mylist.Contains(htmlNode.InnerText))
{
添加(htmlNode.InnerText);
}
}
在这一点上,我想做的是通过“mylist”循环,做完全相同的事情,基本上永远继续下去。代码应该获取新解析的URL并将其添加到列表中。最简单的方法是什么
我尝试在上面的循环之后创建一个for循环。但它似乎没有更新名单。它将永远只在列表中已经存在的相同项目上循环(因为我将始终小于mylist.Count)
for(int i=0;i
谢谢
队列
适合您的要求
Queue<string> mylist = new Queue<string>();
Queue mylist=new Queue();
第一关:
using HtmlAgilityPack;
Queue<string> mylist = new Queue<string>();
var firstUrl = "http://example.com";
HtmlWeb web = new HtmlWeb();
HtmlDocument document = web.Load(firstUrl);
HtmlNodeCollection nodes = document.DocumentNode.SelectNodes("//div[contains(@class,'Name')]/a");
foreach (HtmlNode htmlNode in (IEnumerable<HtmlNode>)nodes)
{
if (!mylist.Contains(htmlNode.InnerText))
{
mylist.Enqueue(htmlNode.InnerText);
}
}
使用HtmlAgilityPack;
Queue mylist=new Queue();
var firstUrl=”http://example.com";
HtmlWeb web=新的HtmlWeb();
HtmlDocument document=web.Load(firstUrl);
HtmlNodeCollection nodes=document.DocumentNode.SelectNodes(//div[contains(@class,'Name'))]/a);
foreach(HtmlNode HtmlNode in(IEnumerable)节点)
{
如果(!mylist.Contains(htmlNode.InnerText))
{
Enqueue(htmlNode.InnerText);
}
}
现在是第二关
while (mylist.Count > 0)
{
var url = mylist..Dequeue();
//the items in mylist are added to the url
var urls = "http://example.com" + url;
HtmlWeb web = new HtmlWeb();
HtmlDocument document = web.Load(urls);
HtmlNodeCollection nodes = document.DocumentNode.SelectNodes("//div[contains(@class,'Name')]/a");
foreach (HtmlNode htmlNode in (IEnumerable<HtmlNode>)nodes)
{
if (!mylist.Contains(htmlNode.InnerText))
{
mylist.Enqueue(htmlNode.InnerText);
}
}
}
while(mylist.Count>0)
{
var url=mylist..Dequeue();
//mylist中的项目将添加到url
变量URL=”http://example.com“+url;
HtmlWeb web=新的HtmlWeb();
HtmlDocument document=web.Load(URL);
HtmlNodeCollection nodes=document.DocumentNode.SelectNodes(//div[contains(@class,'Name'))]/a);
foreach(HtmlNode HtmlNode in(IEnumerable)节点)
{
如果(!mylist.Contains(htmlNode.InnerText))
{
Enqueue(htmlNode.InnerText);
}
}
}
一种可能的(危险的?)实现,使用递归将在使用URL时生成URL:
public IEnumerable<string> Scrap(string url)
{
var web = new HtmlWeb();
var seenUrls = new HashSet<string>();
return ScrapImpl(web, seenUrls, url);
}
private IEnumerable<string> ScrapImpl(HtmlWeb web, HashSet<string> seenUrls, string baseUrl)
{
var document = web.Load(baseUrl);
foreach (var node in document.DocumentNode.SelectNodes("//div[contains(@class,'Name')]/a"))
{
yield return node.InnerText;
if (seenUrls.Add(node.InnerText))
{
foreach (var childUrl in ScrapImpl(web, seenUrls, baseUrl + node.InnerText))
{
yield return childUrl;
}
}
}
}
转到NuGet“System.Interactive”,然后执行以下操作:
var found = new HashSet<string>();
var urls =
EnumerableEx
.Expand(
new[] { "http://example.com" },
url =>
{
var web = new HtmlWeb();
var document = web.Load(url);
var nodes = document.DocumentNode.SelectNodes("//div[contains(@class,'Name')]/a");
return
nodes
.Cast<HtmlNode>()
.Select(x => x.InnerText)
.Where(x => !found.Contains(x))
.Do(x => found.Add(x))
.Select(x => "http://example.com" + x);
});
var found=new HashSet();
变量URL=
可枚举水平
.扩大(
新[]{”http://example.com" },
url=>
{
var web=新的HtmlWeb();
var document=web.Load(url);
var nodes=document.DocumentNode.SelectNodes(//div[contains(@class,'Name'))]/a);
返回
节点
.Cast()
.选择(x=>x.InnerText)
.Where(x=>!found.Contains(x))
.Do(x=>found.Add(x))
.选择(x=>”http://example.com“+x);
});
这听起来像是实现递归的一个很好的用例,我将从这一点开始阅读。递归不久将堆栈溢出,因此它听起来绝对不像递归;)他想要一个排队者用,TPDataflow
,和一个转换块来构建它,这个转换块本身带有一个CancelationToken
,比使用async
和wait
的htmlweb更好的东西,这样可以更好地利用你的资源,还有一个大的讨厌的字典,这样你就不会在圈子里浪费时间了!剩下要做的就是。。。。everything@TheGeneral哦,是的,很公平!
var urls = Scrap("http://example.com"); //nothing is done yet
foreach(var url in urls) //http://example.com starts beeing scraped at this point
{
...
}
var found = new HashSet<string>();
var urls =
EnumerableEx
.Expand(
new[] { "http://example.com" },
url =>
{
var web = new HtmlWeb();
var document = web.Load(url);
var nodes = document.DocumentNode.SelectNodes("//div[contains(@class,'Name')]/a");
return
nodes
.Cast<HtmlNode>()
.Select(x => x.InnerText)
.Where(x => !found.Contains(x))
.Do(x => found.Add(x))
.Select(x => "http://example.com" + x);
});