我希望在 C# 窗口窗体中开发一个 Web scraper。我想要完成的任务如下:

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

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

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

有人可以就此提出一个有效的想法(如果可能的话,提供最低限度的代码片段)。?

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

谢谢,

维杰

有帮助吗?

解决方案

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

从你想要的元素开始,向上遍历到最近的id元素。这样你就可以摆脱大部分顶部标题等。然后建立一个序列来寻找。

例子:

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

对于 example,您将在数据库中存储以下序列: [id=main],div,span,div,表格 也许 div[类=价格区域],表.

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

如果布局很少更改,这将使您每次导航到同一位置。

我还建议你也许使用 HTML 敏捷包 或者类似的 DOM 解析,因为 IE 控制很慢。

屏幕抓取很有趣,但很难 100% 覆盖所有页面。祝你好运!

其他提示

经过一番谷歌搜索后,我遇到了一个相当简单的解决方案。下面附上示例片段。

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 应用程序中,它加载当前网页的 HTML DOM。

IHTML元素 实例公开一个名为“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
            }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top