2

我希望在 C# 窗口窗体中开发一个 Web 刮板。我要完成的工作如下:

  1. 从用户那里获取 URL。
  2. 在 WINForms 的 IE UI 控件(嵌入式浏览器)中加载网页。
  3. 允许用户选择文本(连续、小(不超过 50 个字符))。从加载的网页。
  4. 当用户希望保存位置(HTML DOM 位置)时,必须将其保存到数据库中,以便用户可以在后续访问期间使用该位置来获取该位置的数据。

假设加载的网站是一个价格列表网站,并且报价不断变化,想法是保持 DOM 层次结构,以便我下次可以遍历它。

如果所有 HTML 元素都有其 id 属性,我将能够做到这一点。在 id 为 null 的情况下,我无法做到这一点。

有人可以对此提出一个有效的想法(如果可能的话,一个最少的代码片段)。?

即使您可以共享一些在线资源,这也会有所帮助。

谢谢,

维杰

4

2 回答 2

2

一种方法是将一堆标签/样式/id 构建到您要选择的元素。

从你想要的元素,向上遍历到最近的 id 元素。这样,您将摆脱大部分顶部标题等。然后构建一个要查找的序列。

例子:

<html>
  <body>
    <!-- lots of html -->
    <div id="main">
       <div>
          <span>
             <div class="pricearea">
                <table> <!-- with price data -->

例如,您可以在数据库中存储以下序列:[id=main],div,span,div,tablediv[class=pricearea],table

使用样式/类也可以用来创建你的路径。您可以选择查找标签、标签的属性或组合。您希望使用尽可能少的元素使其尽可能准确,以使其健壮。

如果布局很少更改,这将让您每次都导航到相同的位置。

我还建议您使用HTML Agility Pack或类似的东西来解析 DOM,因为 IE 控件很慢。

屏幕抓取很有趣,但很难对所有页面都做到 100%。祝你好运!

于 2010-01-23T08:57:20.437 回答
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
            }
于 2010-02-09T04:48:35.080 回答