我希望用C#窗体开发一个Web scraper。我想要完成的工作如下:
假设加载的网站是一个价格网站,并且引用的费率不断变化,我们的想法是坚持DOM层次结构,这样我下次就可以遍历它。
如果所有HTML元素都有自己的id属性,我就能做到这一点。在id为null的情况下,我无法完成此操作。
有人可以建议一个有效的想法(如果可能的话,这是一个最低限度的代码片段。)
即使您可以共享一些在线资源,它也会有所帮助。
感谢,
维杰
答案 0 :(得分:2)
一种方法是在您要选择的元素下构建一堆标签/样式/ id。
从您想要的元素,遍历到最近的id元素。通过这种方式,您将摆脱大多数顶部标题等。然后构建一个序列来查找。
示例:
<html>
<body>
<!-- lots of html -->
<div id="main">
<div>
<span>
<div class="pricearea">
<table> <!-- with price data -->
对于exmaple,您将在数据库中存储以下序列: [id = main],div,span,div,table 或者 div [class = pricearea],table < /强>
使用样式/类也可用于创建路径。您可以选择标记,标记属性或组合。您希望尽可能使用尽可能少的元素使其更加稳定。
如果布局很少更改,则每次都可以导航到同一位置。
我还建议您使用HTML Agility Pack或类似的东西进行DOM解析,因为IE控件很慢。
屏幕抓取很有趣,但很难为所有页面获得100%的抓取效果。祝你好运!
答案 1 :(得分:0)
经过一番谷歌搜索后,我遇到了一个相当简单的解决方案。下面附带的是示例代码段。
if (webBrowser.Document != null)
{
IHTMLDocument2 HtmlDoc = (IHTMLDocument2)webBrowser.Document.DomDocument;// loads the HTML DOM
IHTMLSelectionObject selection = HtmlDoc.selection;// Fetches the currently selected HTML Element.
IHTMLTxtRange range = (IHTMLTxtRange)selection.createRange();
IHTMLElement parentElement = range.parentElement();// Identifies the parent element
targetSourceIndex = parentElement.sourceIndex;
//dataLocation = range.parentElement().id;
MessageBox.Show(range.text);//range.parentElement().sourceIndex
}
我在Winforms应用程序中使用了嵌入式Web浏览器,它加载了当前网页的HTML DOM。
IHTMLElement 实例公开了一个名为“SourceIndex”的属性,该属性为每个html元素分配一个唯一ID。
可以将此SourceIndex存储到数据库并查询该位置的内容。使用以下代码。
if (webBrowser.Document != null)
{
IHTMLDocument2 HtmlDoc = (IHTMLDocument2)webBrowser.Document.DomDocument;
IHTMLElement targetElement = null;
foreach (IHTMLElement domElement in HtmlDoc.all)
{
if (domElement.sourceIndex == int.Parse(node.InnerText))// fetching the persisted data from the XML file.
{
targetElement = domElement;
break;
}
}
MessageBox.Show(targetElement.innerText); //range.parentElement().sourceIndex
}