HtmlAgilityPack 遇到这种情况怎么办?

橘子皮... 2015-09-06 02:36:38
<table width="770" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="even" width="640" valign="middle">
<span style="line-height: 20px;">10年≤年限<50年</span>
</td>
</tr>
</table>


【需要达到的效果】
提取出
“10年≤年限<50年”

用mshtml很容易就提出来了,可是HtmlAgilityPack 提不出来也就算了,还更改了内容返回。。。咋办?
mshtml又不知道在c#里怎么调用,求指点正确姿势..
...全文
295 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
winnowc 2015-09-08
  • 打赏
  • 举报
回复
那样反射现在没有什么意义了,C# 这边本来就可以添加 COM 的引用,可以自动帮你生成好需要的接口,也有 dynamic 关键字支持 late-bind。给工程添加引用的时候有一栏 COM ,里面找 Microsoft HTML Object Library,添加后就可以new HTMLDocument()了。如果用了dynamic,体验和 VB 是一样的,比如我之前的例子可以改成:

var html = File.ReadAllText("e:\\test.htm");
dynamic doc = new HTMLDocument();
doc.write(html);
var b = doc.body.getElementsByTagName("span");
Console.WriteLine(b[0].innerText);
既然你熟悉用 VB,不熟悉 C# 调用 COM,那干脆用 VB 写个程序干这个事情,给 C# 这边调用也行。
ajianchina 2015-09-08
  • 打赏
  • 举报
回复
刚刚已经回复了你前面的一个帖子,之所以过了几天还回复你的这个帖子,其实还是因为你所提出的这个问题,类似于<span>10年≤年限<50年</span>这样的数值提取有误,想来想去,我觉得如果以xml的解析思路来取值的话就不会存在这以问题,因为xml需要的是一个闭合的节点,那么将html转xhtml就可绕开这些问题,再通过解析xml的方式来取值就容易多了。 方法我在你另一个帖子里也说了,你可以回过去再看一下,基本上就是这一思路。
橘子皮... 2015-09-07
  • 打赏
  • 举报
回复
我想用http://www.cnblogs.com/phytan/archive/2007/07/11/814175.html 它的方法反射出mshtml来 然后写个调用返回mshtml.documentclass ,然后我就可以用我在vb里比较熟悉的getelementbyid getelementsbytagname getelementsbyname classname Row Cell 这些解析命令来分析了,恳请有闲工夫的大牛帮我写个函数输入参数string html就可以返回mshtml.documentclass ,让我可以直接 .body.getelementbyid 这些书写。。。
橘子皮... 2015-09-07
  • 打赏
  • 举报
回复
var html = File.ReadAllText("D:\\test.txt",Encoding.GetEncoding("GBK")); HtmlAgilityPack.HtmlDocument zzz = new HtmlAgilityPack.HtmlDocument(); zzz.LoadHtml(html); Console.WriteLine(zzz.DocumentNode.SelectNodes("//span")[0].OuterHtml ); 连OuterHtml 返回都是错的,除了放弃不用,完全没的办法处理 真心没mshtml容错好
橘子皮... 2015-09-07
  • 打赏
  • 举报
回复
引用 7 楼 github_22161131 的回复:
LZ 的那个问题是因为“10年≤年限<50年” 这里面 50 前面的 '<',如果当 xml 对待,这是个标签的开始。HtmlAgilityPack 会认错,而浏览器的兼容性更好(或者说 html 本来就不是 xhtml)。 mshtml 不用 createobject 这样吧,引用COM 组件 Microsoft HTML Object Library 就是 mshtml ,应该是 .net 4.0 以后它可以自动把需要的接口嵌入你的程序。我大概试了下:

var html = File.ReadAllText("e:\\test.htm");
var a = new HTMLDocument();
((IHTMLDocument2)a).write(html);
var b = ((IHTMLElement2)a.body).getElementsByTagName("span").GetEnumerator();
while (b.MoveNext())
{
	Console.WriteLine(((IHTMLElement)b.Current).innerText);
}
输出是正确的。
谢谢,你至少对帖子的观察还是很仔细的! 至少你说的引用后直接var a = new HTMLDocument(); 这个我不知道在c#里如何,但是在vb里,和createobject在某些情形下有细微差别,前者没后者好用,不过还是谢谢你的回答!
橘子皮... 2015-09-06
  • 打赏
  • 举报
回复
引用 1 楼 github_22161131 的回复:
可以通过 winforms 的 WebBrowser 控件(需要引用 System.Windows.Forms)来间接使用 mshtml。例如:

var html = File.ReadAllText("e:\\test.htm");
string result = null;
var t = new Thread(() => {
	using (var wb = new WebBrowser())
	{
		wb.DocumentText = "hello, mshtml";
		var doc = wb.Document.OpenNew(true);
		doc.Write(html);
		result = doc.GetElementsByTagName("span")[0].InnerText;
	}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
Console.WriteLine(result);
Console 程序因为不是 STA 的所以要使用一个 STA 的新线程,如果本来就是 winforms 的程序那就不用了。
大侠,能研究看看,帮我把调用mshtml搞定么,用调用createobject的方法
winnowc 2015-09-06
  • 打赏
  • 举报
回复
可以通过 winforms 的 WebBrowser 控件(需要引用 System.Windows.Forms)来间接使用 mshtml。例如:

var html = File.ReadAllText("e:\\test.htm");
string result = null;
var t = new Thread(() => {
	using (var wb = new WebBrowser())
	{
		wb.DocumentText = "hello, mshtml";
		var doc = wb.Document.OpenNew(true);
		doc.Write(html);
		result = doc.GetElementsByTagName("span")[0].InnerText;
	}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
Console.WriteLine(result);
Console 程序因为不是 STA 的所以要使用一个 STA 的新线程,如果本来就是 winforms 的程序那就不用了。
winnowc 2015-09-06
  • 打赏
  • 举报
回复
LZ 的那个问题是因为“10年≤年限<50年” 这里面 50 前面的 '<',如果当 xml 对待,这是个标签的开始。HtmlAgilityPack 会认错,而浏览器的兼容性更好(或者说 html 本来就不是 xhtml)。 mshtml 不用 createobject 这样吧,引用COM 组件 Microsoft HTML Object Library 就是 mshtml ,应该是 .net 4.0 以后它可以自动把需要的接口嵌入你的程序。我大概试了下:

var html = File.ReadAllText("e:\\test.htm");
var a = new HTMLDocument();
((IHTMLDocument2)a).write(html);
var b = ((IHTMLElement2)a.body).getElementsByTagName("span").GetEnumerator();
while (b.MoveNext())
{
	Console.WriteLine(((IHTMLElement)b.Current).innerText);
}
输出是正确的。
newtee 2015-09-06
  • 打赏
  • 举报
回复
用xpath去下这个节点下的内容不就行了?
  • 打赏
  • 举报
回复
引用 楼主 wowfiowow 的回复:
<table width="770" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="even" width="640" valign="middle"> <span style="line-height: 20px;">10年≤年限<50年</span> </td> </tr> </table> 【需要达到的效果】 提取出 “10年≤年限<50年” 用mshtml很容易就提出来了,可是HtmlAgilityPack 提不出来也就算了,还更改了内容返回。。。咋办? mshtml又不知道在c#里怎么调用,求指点正确姿势..
什么叫“提不出来”呢?你的出错的代码贴在哪里了?看你贴不出来代码就猜到了你平常是如何写代码的。
  • 打赏
  • 举报
回复
正则当然可以搞定……但不一定正确
橘子皮... 2015-09-06
  • 打赏
  • 举报
回复
顶~~~~~~~遇到这种情况就必须正则啦?

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧