繁体   English   中英

从c#中解析为html的电子邮件中获取特定的href值或链接

[英]Get specific href values or link from email which is parsed as html in c#

我正在C#服务中处理电子邮件。 我需要提取存在于其中的某些链接以添加到数据库。 我正在使用HtmlagilityPack。 div和p标签在解析的电子邮件中可以互换。 我必须从电子邮件中提取标签“ Scheduler Link”,“ Data Path”和“ Link”下方的链接。 清理后,样本数据如下:

<html>
 <body>
   ......//contains some other tags which i dont need, may include hrefs but 
         //i dont need them 
   <div align="justify" style="margin:0;"></div>
   <div align="justify" style="margin:0;"></div>
   <div align="justify" style="margin:0;">Scheduler link :</div>
   <div align="justify" style="margin:0;"></div>
   <div style="margin:0;"><a href="https://something.com/requests/26428"> 
   https://something.com/requests/26428</a>
   </div>
   <div style="margin:0;"></div>
   <div style="margin:0;"></div>
   <div style="margin:0;"></div>
   <div align="justify" style="margin:0;">Data path :</div>
   <div align="left" style="text-align:justify;margin:0;"><a  
   href="file:///\\mycompany.com\ABC\OPQ1234\jui\tui245.5t_2rtfg_tyui"> 
   \\mycompany.com\ABC\OPQ1234\jui\tui245.5t_2rtfg_tyui</a>
   </div>
   <div align="left" style="text-align:justify;margin:0;"><a  
   href="file:///\\mycompany.com\ABC\OPQ1234\tui245.5t_2rtfg_tyui"> 
   \\mycompany.com\ABC\OPQ1234\tui245.5t_2rtfg_tyui</a>
   </div>
   <div align="justify" style="margin:0;"></div>
   <div align="justify" style="margin:0;">Link :</div>
   <div align="justify" style="margin:0;"><a 
   href="https://Thisisanotherlink.abcdef/sites/this/498592/rkjfb/3874y">
   This is some text</a></div>
   <div align="justify" style="margin:0 0 5pt 0;">This is another text</div>

   ......//contains some other tags which i dont need 
 </body>
</html>

我正在使用正则表达式查找“​​ Scheduler Link”,“ Data Path”和“ Link”的div标签,如下所示:

HtmlNode schedulerLink = doc.DocumentNode.SelectSingleNode("//*[text()[contains(.,'" + Regex.Match(body, _keyValuePairs["scheduler"]).Value.ToString() + "')]]");
HtmlNode dataPath = doc.DocumentNode.SelectSingleNode("//*[text()[contains(.,'" + Regex.Match(body, _keyValuePairs["datapath"]).Value.ToString() + "')]]");
HtmlNode link = doc.DocumentNode.SelectSingleNode("//*[text()[contains(.,'" + Regex.Match(body, _keyValuePairs["link"]).Value.ToString() + "')]]");

div标签将返回各自的节点。 每封电子邮件中与这三个电子邮件相对应的链接数量各不相同,标签的顺序也各不相同。 我需要捕获列表中每个链接。 我正在使用以下代码:

 foreach (HtmlNode link in schedulerLink.Descendants())
        {
        string hrefValue = link.GetAttributeValue("href", string.Empty);     

            if (!(link.InnerText.Contains("\r\n")))
            {
                if (link.InnerText.Contains("/"))
                {
                    schedulersList.Add(link.InnerText.Trim());
                }
            }
        }

子孙有时没有返回正确数量的节点。 另外,由于后代通常返回下面显示的所有节点,因此如何获得针对3个不同列表中的3个标记的特定链接。

您在问题中提到了不同的href时,

一种方法是通过以下操作:

   var html = @"<html> <body> <div align='justify' style='margin:0;'></div> <div align='justify' style='margin:0;'></div> <div align='justify' style='margin:0;'>Scheduler link :</div> <div align='justify' style='margin:0;'></div> <div style='margin:0;'><a href='https://something.com/requests/26428'> https://something.com/requests/26428</a> </div> <div style='margin:0;'></div> <div style='margin:0;'></div> <div style='margin:0;'></div> <div align='justify' style='margin:0;'>Data path :</div> <div align='left' style='text-align:justify;margin:0;'><a href='file:///\\mycompany.com\ABC\OPQ1234\jui\tui245.5t_2rtfg_tyui'> \\mycompany.com\ABC\OPQ1234\jui\tui245.5t_2rtfg_tyui</a> </div> <div align='left' style='text-align:justify;margin:0;'><a href='file:///\\mycompany.com\ABC\OPQ1234\tui245.5t_2rtfg_tyui'> \\mycompany.com\ABC\OPQ1234\tui245.5t_2rtfg_tyui</a> </div> <div align='justify' style='margin:0;'></div> <div align='justify' style='margin:0;'>Link :</div> <div align='justify' style='margin:0;'><a href='https://Thisisanotherlink.abcdef/sites/this/498592/rkjfb/3874y'> This is some text</a></div> <div align='justify' style='margin:0 0 5pt 0;'>This is another text</div> </body></html>";
        var document = new HtmlDocument();
        document.LoadHtml(html);

        var schedulerNodes = document.DocumentNode.SelectNodes("//a[contains(@href, \"something\")]");
        var dataPathNodes = document.DocumentNode.SelectNodes("//a[contains(@href, \"mycompany\")]");
        var linkNodes = document.DocumentNode.SelectNodes("//a[contains(@href, \"Thisisanotherlink\")]");

        foreach (var item in schedulerNodes)
        {
            Debug.WriteLine(item.GetAttributeValue("href", ""));
            Debug.WriteLine(item.InnerText);
        }
        foreach (var item in dataPathNodes)
        {
            Debug.WriteLine(item.GetAttributeValue("href", ""));
            Debug.WriteLine(item.InnerText);
        }
        foreach (var item in linkNodes)
        {
            Debug.WriteLine(item.GetAttributeValue("href", ""));
            Debug.WriteLine(item.InnerText);
        }

希望有帮助!

编辑::

    var result = document.DocumentNode.SelectNodes("//div//text()[normalize-space()] | //a");
// select all textnodes and a tags
            string sch = "Scheduler link :";
            string dataLink = "Data path :";
            string linkpath = "Link :";
            foreach (var item in result)
            {
                if (item.InnerText.Trim().Contains(sch))
                {
                        var processResult = result.SkipWhile(x => !x.InnerText.Trim().Equals(sch)).Skip(1);
// skip the result till we reache to Scheduler.
                        Debug.WriteLine("====================Scheduler link=========================");
                        foreach (var subitem in processResult)
                        {
                            Debug.WriteLine(subitem.GetAttributeValue("href", ""));
// if href then add to list TODO
                            if (subitem.InnerText.Contains(dataLink)) // break when data link appears.
                            {
                                break;
                            }
                        }
                    }
                    if (item.InnerText.Trim().Contains(dataLink))
                    {
                        var processResult = result.SkipWhile(x => !x.InnerText.Trim().Equals(dataLink)).Skip(1);
                        Debug.WriteLine("====================Data link=========================");

                        foreach (var subitem in processResult)
                        {
                            Debug.WriteLine(subitem.GetAttributeValue("href", ""));
                            if (subitem.InnerText.Contains(dataLink))
                            {
                                break;
                            }
                        }
                    }
                    if (item.InnerText.Trim().Contains("Link :"))
                    {
                        var processResult = result.SkipWhile(x => !x.InnerText.Trim().Equals(linkpath)).Skip(1);
                        Debug.WriteLine("====================Link=========================");
                        foreach (var subitem in processResult)
                        {
                            var hrefValue = subitem.GetAttributeValue("href", "");
                            Debug.WriteLine(hrefValue);
                            if (subitem.InnerText.Contains(dataLink))
                            {
                                break;
                            }
                        }
                    }
                }

我在代码注释中提到了逻辑。

希望能有所帮助

如果我理解正确,则希望在特定字符串(例如scheduler link之后捕获第一个href属性的内容。 我不了解HtmlagilityPack,但是我的方法是只使用正则表达式搜索电子邮件正文,如下所示:

Scheduler link(?:\s|\S)*?href="([^"]+)

每次在邮件中出现“计划程序链接”后,此正则表达式应捕获第一个href属性的内容。

您可以在这里尝试: Regex101

要查找其他类型的链接,只需将Scheduler link部分替换为相应的字符串。

我希望这是有帮助的。

有关正则表达式的其他信息:

  • Scheduler link从字面上匹配字符串
  • (?:\\s|\\S)*?href="与任何字符匹配的非捕获组,直到首次出现文字字符串href="
  • ([^"]+)捕获所有尽管带有"字符

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM