htmlAggilityPack 跨节点搜索文本字符串
htmlAggilityPack searching a text string across nodes
我希望能够搜索从 URL 抓取的 html 文档,并验证 URL 是否包含特定文本。
文本和 URL 均由用户提供,并且可以有所不同。
我用 httpWeb 请求
抓取 URL
string quote = txtQuote.Text;
string sourceURL = txtURL.Text;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sourceURL);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
if (response.CharacterSet == null)
{
readStream = new StreamReader(receiveStream);
}
else
{
readStream = new StreamReader(receiveStream,
Encoding.GetEncoding(response.CharacterSet));
}
string data = readStream.ReadToEnd();
response.Close();
readStream.Close();
我的数据库中还有一个 html 实体列表和各种可能的编码,我将其检索并传递给 DataTable,这样我就可以将任何编码更改为标准 html 实体,并且用标准的 space
替换不间断的 spaces
DataTable encodings = new DataTable();
string getEncodings = "select * from htmlentities";
SqlCommand cmdGetEncodings = new SqlCommand(getEncodings, dbcon);
encodings.Load(cmdGetEncodings.ExecuteReader());
dbcon.Close();
foreach (DataRow row in encodings.Rows)
{
string htmlentity = row[1].ToString();
string deccode = row[2].ToString();
string hexcode = row[3].ToString();
data = data.Replace(deccode, htmlentity);
data = data.Replace(hexcode, htmlentity);
data = data.Replace(“ ”, “ “);
}
然后我使用 htmlAgilityPack 将已删除和修改的 html 传递给新文档,并检索内部文本
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(数据);
HtmlNode root = doc.DocumentNode;
string innerText = root.InnerText;
现在我想知道,准确验证 quote 是否包含在 innerText 中的最佳方法是什么?我尝试过的一种方法是:
如果 (innerText.IndexOf(引用) != -1)
{
Label1.Text = “找到”;
}
别的 {
Label1.Text =“未找到”;
}
但这并不准确,它无法找到跨越节点的 innerText(例如,在多个 <p>
上)。引用示例和 URL return 未找到:
“他年轻时敏捷的掩护点已经减少到站在适当的位置,只阻止那些接近他的球,就像该死的直射他一样,”查理康诺利在他关于格蕾丝生活的优秀小说吉尔伯特中是这样写的. “在澳大利亚队的第一局比赛中,每当球从他身边飞过时,他就太在意人群的嘘声了。”比赛结束时,英格兰队因 Ranjitsinhji 的 93 球而战平,Grace 告诉 Jackson:“一切都结束了,Jacker,我不会再参加比赛了。”
然后是唐布拉德曼。这个故事如此有名,几乎不需要复述。 “我非常想做得好,”布拉德曼承认道。他被埃里克·霍利斯(Eric Hollies)打了第二个球,“一个完美的长度”,刚好碰到他的球棒的内边缘,然后击倒了保释金。如果他只有四分,他的平均分会是一百分。
URL: http://www.theguardian.com/sport/2016/feb/23/test-cricket-farewells-brendon-mccullum
但是,如果我只搜索第一段:
“他年轻时敏捷的掩护点已经减少到站在适当的位置,只阻止那些接近他的球,就像该死的直射他一样,”查理康诺利在他关于格蕾丝生活的优秀小说吉尔伯特中是这样写的. “在澳大利亚队的第一局比赛中,每当球从他身边飞过时,他就太在意人群的嘘声了。”比赛结束时,英格兰队因 Ranjitsinhji 的 93 球而战平,格蕾丝告诉杰克逊:“一切都结束了,杰克,我不会再上场了。”
它将return 找到。
有没有办法实现跨节点检查文本?
所以,如果您只打算抓取 http://www.theguardian.com
这是一个简单的解决方案,因为卫报的 html 代码非常简洁。
var hdoc = new HtmlDocument();
hdoc.LoadHtml(data); // or hdoc.Load(data) - depending on what you get from your request
var articleNodes = hdoc.DocumentNode.SelectNodes(@"//p"); // the 'p' nodes contains the article text
var quote = "my quote";
var article = string.Empty;
foreach (HtmlNode node in articleNodes)
{
article += node.InnerText + " "; // added a whitespace so we dont mess up the text.
}
if (article.Contains(quote))
{
return true;
}
else
{
return false;
}
现在,如果你打算为任何给定的 URL 做这个,那就有麻烦了。
由于您不知道 URL 的 html 格式 "best" - 我的意思是最简单且值得畏缩的解决方案如下:
var hdoc = new HtmlDocument();
hdoc.LoadHtml(data); // or hdoc.Load(data) - depending on what you get from your request
var articleNodes = hdoc.DocumentNode;
var quote = "my quote";
var text = string.Empty;
foreach (var node in articleNodes.InnerText)
{
text += node + " "; // added a whitespace so we dont mess up the text.
foreach (var htmlNode in articleNodes.ChildNodes)
{
text += htmlNode.InnerText + " ";
foreach (var childNode in htmlNode.ChildNodes)
{
text += childNode.InnerText + " ";
foreach (var childrensChildren in childNode.ChildNodes)
{
text += childrensChildren.InnerText + " ";
}
}
}
}
if (text.Contains(quote))
{
return true;
}
else
{
return false;
}
最终,由于不知道给定的 URL 的 html 代码,嵌套 foreach
语句可能会增加或减少。当然,在 运行 任何 foreach
语句之前,必须对节点进行一些空检查。
可能有更好的解决方案,这是我的 2 美分。
工作示例:
这 returns 是的,我将文章的一部分复制并粘贴到引用变量中,并检查我们的文章字符串是否包含它。
string urlAddress = "http://www.theguardian.com/sport/2016/feb/23/test-cricket-farewells-brendon-mccullum";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string data = string.Empty;
if (response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
if (response.CharacterSet == null)
{
readStream = new StreamReader(receiveStream);
}
else
{
readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
}
data = readStream.ReadToEnd();
response.Close();
readStream.Close();
}
var hdoc = new HtmlDocument();
hdoc.LoadHtml(data);
var articleNodes = hdoc.DocumentNode.SelectNodes(@"//p"); // the 'p' nodes contains the article text
var quote ="Sinatra couldn’t stand the song. His daughter Tina once said that her father thought it was “self-serving and self-indulgent”. By the end of the ’70s he was in the habit of introducing it by explaining how little he liked it. “I hate this song. I hate this song!” he said before performing it at Atlantic City in 1979. “I got it up to here, this goddamn song.” Of course when Sinatra died, pretty much every single TV and radio news show played him out with My Way, “the most obvious, ";
var article = string.Empty;
foreach (HtmlNode node in articleNodes)
{
article += node.InnerText + " "; // added a whitespace so we dont mess up the text.
}
bool containsQuote = false || article.Contains(quote); // bool is true if the quote is in the article.
我希望能够搜索从 URL 抓取的 html 文档,并验证 URL 是否包含特定文本。 文本和 URL 均由用户提供,并且可以有所不同。 我用 httpWeb 请求
抓取 URLstring quote = txtQuote.Text;
string sourceURL = txtURL.Text;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sourceURL);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
if (response.CharacterSet == null)
{
readStream = new StreamReader(receiveStream);
}
else
{
readStream = new StreamReader(receiveStream,
Encoding.GetEncoding(response.CharacterSet));
}
string data = readStream.ReadToEnd();
response.Close();
readStream.Close();
我的数据库中还有一个 html 实体列表和各种可能的编码,我将其检索并传递给 DataTable,这样我就可以将任何编码更改为标准 html 实体,并且用标准的 space
替换不间断的 spacesDataTable encodings = new DataTable();
string getEncodings = "select * from htmlentities";
SqlCommand cmdGetEncodings = new SqlCommand(getEncodings, dbcon);
encodings.Load(cmdGetEncodings.ExecuteReader());
dbcon.Close();
foreach (DataRow row in encodings.Rows)
{
string htmlentity = row[1].ToString();
string deccode = row[2].ToString();
string hexcode = row[3].ToString();
data = data.Replace(deccode, htmlentity);
data = data.Replace(hexcode, htmlentity);
data = data.Replace(“ ”, “ “);
}
然后我使用 htmlAgilityPack 将已删除和修改的 html 传递给新文档,并检索内部文本 HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(数据);
HtmlNode root = doc.DocumentNode;
string innerText = root.InnerText;
现在我想知道,准确验证 quote 是否包含在 innerText 中的最佳方法是什么?我尝试过的一种方法是: 如果 (innerText.IndexOf(引用) != -1) { Label1.Text = “找到”; } 别的 { Label1.Text =“未找到”; }
但这并不准确,它无法找到跨越节点的 innerText(例如,在多个 <p>
上)。引用示例和 URL return 未找到:
“他年轻时敏捷的掩护点已经减少到站在适当的位置,只阻止那些接近他的球,就像该死的直射他一样,”查理康诺利在他关于格蕾丝生活的优秀小说吉尔伯特中是这样写的. “在澳大利亚队的第一局比赛中,每当球从他身边飞过时,他就太在意人群的嘘声了。”比赛结束时,英格兰队因 Ranjitsinhji 的 93 球而战平,Grace 告诉 Jackson:“一切都结束了,Jacker,我不会再参加比赛了。”
然后是唐布拉德曼。这个故事如此有名,几乎不需要复述。 “我非常想做得好,”布拉德曼承认道。他被埃里克·霍利斯(Eric Hollies)打了第二个球,“一个完美的长度”,刚好碰到他的球棒的内边缘,然后击倒了保释金。如果他只有四分,他的平均分会是一百分。
URL: http://www.theguardian.com/sport/2016/feb/23/test-cricket-farewells-brendon-mccullum
但是,如果我只搜索第一段:
“他年轻时敏捷的掩护点已经减少到站在适当的位置,只阻止那些接近他的球,就像该死的直射他一样,”查理康诺利在他关于格蕾丝生活的优秀小说吉尔伯特中是这样写的. “在澳大利亚队的第一局比赛中,每当球从他身边飞过时,他就太在意人群的嘘声了。”比赛结束时,英格兰队因 Ranjitsinhji 的 93 球而战平,格蕾丝告诉杰克逊:“一切都结束了,杰克,我不会再上场了。”
它将return 找到。 有没有办法实现跨节点检查文本?
所以,如果您只打算抓取 http://www.theguardian.com
这是一个简单的解决方案,因为卫报的 html 代码非常简洁。
var hdoc = new HtmlDocument();
hdoc.LoadHtml(data); // or hdoc.Load(data) - depending on what you get from your request
var articleNodes = hdoc.DocumentNode.SelectNodes(@"//p"); // the 'p' nodes contains the article text
var quote = "my quote";
var article = string.Empty;
foreach (HtmlNode node in articleNodes)
{
article += node.InnerText + " "; // added a whitespace so we dont mess up the text.
}
if (article.Contains(quote))
{
return true;
}
else
{
return false;
}
现在,如果你打算为任何给定的 URL 做这个,那就有麻烦了。
由于您不知道 URL 的 html 格式 "best" - 我的意思是最简单且值得畏缩的解决方案如下:
var hdoc = new HtmlDocument();
hdoc.LoadHtml(data); // or hdoc.Load(data) - depending on what you get from your request
var articleNodes = hdoc.DocumentNode;
var quote = "my quote";
var text = string.Empty;
foreach (var node in articleNodes.InnerText)
{
text += node + " "; // added a whitespace so we dont mess up the text.
foreach (var htmlNode in articleNodes.ChildNodes)
{
text += htmlNode.InnerText + " ";
foreach (var childNode in htmlNode.ChildNodes)
{
text += childNode.InnerText + " ";
foreach (var childrensChildren in childNode.ChildNodes)
{
text += childrensChildren.InnerText + " ";
}
}
}
}
if (text.Contains(quote))
{
return true;
}
else
{
return false;
}
最终,由于不知道给定的 URL 的 html 代码,嵌套 foreach
语句可能会增加或减少。当然,在 运行 任何 foreach
语句之前,必须对节点进行一些空检查。
可能有更好的解决方案,这是我的 2 美分。
工作示例: 这 returns 是的,我将文章的一部分复制并粘贴到引用变量中,并检查我们的文章字符串是否包含它。
string urlAddress = "http://www.theguardian.com/sport/2016/feb/23/test-cricket-farewells-brendon-mccullum";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string data = string.Empty;
if (response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
if (response.CharacterSet == null)
{
readStream = new StreamReader(receiveStream);
}
else
{
readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
}
data = readStream.ReadToEnd();
response.Close();
readStream.Close();
}
var hdoc = new HtmlDocument();
hdoc.LoadHtml(data);
var articleNodes = hdoc.DocumentNode.SelectNodes(@"//p"); // the 'p' nodes contains the article text
var quote ="Sinatra couldn’t stand the song. His daughter Tina once said that her father thought it was “self-serving and self-indulgent”. By the end of the ’70s he was in the habit of introducing it by explaining how little he liked it. “I hate this song. I hate this song!” he said before performing it at Atlantic City in 1979. “I got it up to here, this goddamn song.” Of course when Sinatra died, pretty much every single TV and radio news show played him out with My Way, “the most obvious, ";
var article = string.Empty;
foreach (HtmlNode node in articleNodes)
{
article += node.InnerText + " "; // added a whitespace so we dont mess up the text.
}
bool containsQuote = false || article.Contains(quote); // bool is true if the quote is in the article.