我刚开始使用HtmlAgilityPack从网站上抓取一些文字。我已经进行了实验,发现在使用SelectNodes
方法时,某些网站在获取正确的XPath方面比其他网站更容易。我相信我做错了什么但无法理解。
例如,在Google Chrome中浏览DOM时,我可以复制XPath://*[@id="page"]/span/table[7]/tbody/tr[1]/td/span[2]/a
然后我会做类似的事情。
var search = doc.DocumentNode.SelectNodes("//[@id=\"page\"]//span//table//tr//td//span//a"
在search
中使用foreach loop
时,我得到一个空引用错误,并且确实调试器说search
为空。所以我假设XPath是错误的...(或者我正在做其他完全错误的事情)所以我的问题是我如何获得适当的XPath for HtmlAgilityPack来找到这些节点?
答案 0 :(得分:1)
按照您在上次评论中的要求进行跟进,只有在http get请求返回后才会完全呈现html。
几个javascript调用将html块插入到文档中。
您需要以下内容:loadCompanyProfileData('ContactInfo')
,它会生成如下所示的http get请求:
http://financials.morningstar.com/cmpind/company-profile/component.action?component=ContactInfo&t=XNAS:AAPL®ion=usa&culture=en-US&cur=&_=1465809033745
。
这将返回电子邮件,您可以使用以下代码提取该电子邮件: HtmlWeb w = new HtmlWeb(); var doc = w.Load(" http://financials.morningstar.com/cmpind/company-profile/component.action?component=ContactInfo&t=XNAS:AAPL®ion=usa&culture=en-US&cur=&_=1465809033745");
var emails = doc.DocumentNode.CssSelect("a")
.Where(a => a.GetAttributeValue("href")
.StartsWith("mailto:"))
.Select(a => a.GetAttributeValue("href")
.Replace("mailto:", string.Empty));
电子邮件最终包含1个元素,即investor_relations@apple.com。
你的问题是确定什么应该是" cur" loadCompanyProfileData javascript函数用于每个不同公司的参数。
我无法在代码中找到生成此参数的位置/方式。
另一种方法是执行浏览器模拟器(如selenium web driver port for c#),这样您就可以执行javascript代码 - 并为每个公司请求运行loadCompanyProfileData('ContactInfo')
的调用。
但是我也无法使用它,我的网络驱动器脚本执行似乎不起作用。