我正在写一个小程序,在不同的网站上搜索某些单词。如果特定单词不存在或不再可用,我想显示一条错误消息。
我想保持代码相对紧凑,因此将数组用于URL和单词。
不幸的是,你似乎只能搜索单个字符串:
string checkWord = doc[0].DocumentNode.SelectSingleNode("//*[text()[contains(., 'Word1')]]").InnerText;
// (= no error)
但是我想让整个命令处于一个循环中,并使用所有单词的数组而不是'Word1',以便使每个网站都自动搜索相应的单词:不幸的是,你似乎只能搜索单个字符串:
string checkWord = doc[i].DocumentNode.SelectSingleNode("//*[text()[contains(.,
word[i])]]").InnerText;
// (= error)
有谁知道我如何在字符串而不是特定文本中输入变量(数组)?
我希望我能够以一种可以理解的方式来解释我的问题,并且有人可以帮助我:)
附言 整个脚本如下所示:
HtmlWeb web = new HtmlWeb();
string[] words = new string[] {"word1", "word2", "word3"};
HtmlDocument[] doc = new HtmlDocument[] {web.Load("www.url1.com"), web.Load("www.url2.com"), web.Load("www.url3.com"),};
for (int i = 0; i < doc.Length; i++)
{
try()
{
string checkWord = doc[i].DocumentNode.SelectSingleNode("//*[text()[contains(.,
words[i])]]").InnerText;
}
catch(Exception)
{
Console.WriteLine("Word {0} is not avaiable", i);
continue;
}
}
仅使用它SelectNodes("//text()")
来获取所有文本节点,然后在C#中返回LINQ语句来执行包含操作,可能会更容易。
例如,此代码将返回已加载页面上存在的所有单词:
string[] words = new string[] { "jesse", "jessehouwing", "word3" };
var web = new HtmlWeb();
HtmlDocument[] doc = new HtmlDocument[] { web.Load("https://jessehouwing.net") };
for (int i = 0; i < doc.Length; i++)
{
var check = doc[i].DocumentNode.SelectNodes("//text()")
.SelectMany(node => words.Where(word => node.InnerText.Contains(word, StringComparison.CurrentCultureIgnoreCase)))
.Distinct();
}
结果:
可以通过以下方式进行简化,以减少对空值进行过滤的需要。
doc[i].DocumentNode.SelectNodes("//text()").SelectMany(node => words.Where(word => node.InnerText.Contains(word, StringComparison.CurrentCultureIgnoreCase))).Distinct();
PS:请记住,HTML Agility包会加载Web服务器返回的确切内容,而不执行任何Javascript。如果您的目标网站在浏览器中动态加载其内容,则HTML Agility包将无法满足您的预期。在这种情况下,您需要使用无头浏览器来加载页面并呈现其内容。例如:nuget.org/packages/PuppeteerSharp