【问题标题】:Find out which div is containing the "main content" with crawler用爬虫找出哪个 div 包含“主要内容”
【发布时间】:2015-01-13 07:15:06
【问题描述】:

我们有一个每周抓取数十万页的抓取工具。目前要从爬取的 HTML 中获取数据,我们手动查看 HTML 并看到“好的,数据 A 在 <div class=".info-list"> 内,数据 B 在 <h1> 内”,然后我们使用解析器解析数据来自那些 div 的。

我想这对于大多数人来说是解析爬取的 HTML 最常用的方法,但这意味着我们必须知道我们爬取的所有页面和域的 HTML 结构。所以它的可扩展性不是很好。

如果我们能弄清楚“主要内容”是什么div,这样我们就可以忽略“相关产品”或“相关文章”或“主菜单”等其他内容,我们可以轻松解析以与我们现在相同的方式获取数据,但不必指定每个数据的确切 div 名称和位置。

那么...我们如何确定哪个是页面的“主 div”?

我很确定 Google 会这样做。他们肯定知道页面上元素的位置,以及某些内容是否位于“主要内容”或页脚中。他们怎么会知道呢?

我可以看到的大规模执行此操作的方法是:

  • 渲染页面并寻找最大的 div 并从那里开始。但是渲染数百万或数十万页并不是真正的廉价和高效。

  • 尝试从每个 div 的内容中找出它。例如,其中包含最多链接的 div 可能是菜单。其中包含最多文本的 div 可能是主要内容。但是如果内容是这样的,这会变得非常棘手:

    <body>
        <div class="maincontent">
            <div class="post-header">
                <h1>Header of post</h1>
            </div>
            <div class="short-description">
                Hello World!
            </div>
            <div class="long-description">
                Hello New World!
            </div>
        </div>
    </body>
    

    显然我们想要识别为“主要内容”的 div 是&lt;div class="maincontent"&gt;。但是,如果我们寻找具有“最多文本”的 div。应该是.long-description

这开始成为一个相当长的问题。但我的观点是,很难确定网站的哪个部分是“主要内容”。我正在请任何聪明的人帮助我想出一种体面的方法来找出哪些 div 或哪些 div 可能包含页面中最重要的内容。

编辑:我想渲染它的一种方法不是渲染每一页。但是要渲染域。例如。如果域结构是http://example.com/post/1-post-name/,我可以保存它的渲染,下次我找到http://example.com/post/2-post-name/ 的页面时,我知道它可能与第一个具有相同的 HTML 模板,并且“最大的 div”是可能是一样的。

那么做这个服务器端的技术是什么?我的意思是渲染它并保存所有元素的大小和位置。我想这似乎是一种相当不错的大规模实施方式。

【问题讨论】:

    标签: html parsing web-crawler


    【解决方案1】:

    我会尝试多种方法。例如,从显而易见的开始 - 是否有 id="content"class="main_content" ?用它!寻找大内容块常见的 id 和类,如果它们存在,则使用它们。如果不是,则继续进行不太确定的测试。

    接下来尝试缩小范围。有&lt;header&gt;&lt;nav&gt; 标签吗?忽略它和它上面的一切。忽略 &lt;footer&gt; 或 class="sidebar"

    制定一些规则,让它们运行,然后手动预期返回的内容,并在您拉得过多或遗漏事物时寻找模式。调整你的规则并在此基础上编写新的规则。

    到那时,您甚至可以让那些通过所有测试的人进入一个简短列表,您可以在其中手动检查它们并创建特定于域的规则,您可以在其中指出您想要使用的确切 div。通过一些人工干预,您仍然可以非常高效,并且直观地查看 50 个站点中的 8 个站点仍然很划算。

    【讨论】:

    • 查看我对渲染的帖子的编辑,并将渲染缓存到具有相同 html 模板的其他页面。你怎么看?我们已经按照您的建议制定了特定于域的规则。这就是我们想要摆脱的。你是对的,你可以得到“好的结果”,我们已经得到了很好的结果。但我们正在寻求改进,以更快地扩展。
    • 我不喜欢渲染的想法,我的直觉是它会比它的价值更麻烦。如果我让这个过程自动化,我的答案就是我会怎么做。您知道计算机应该解析并检查我所说的内容,对吗?当您的任何自动化测试都不适用于页面时,人工查看它只是一种后备。
    • 当然,但是如果您想抓取 1000 多个具有不同 HTML 结构的域,您不想执行“硬编码规则”来解析内容,因为如果他们只进行一次更改,一切都会中断.我们正在寻找一种无需任何人工输入或协助即可处理任何领域的自动化流程。 Google 在数十亿页上执行此操作,我们希望在数十万页上执行此操作。寻找一种在任何页面或域上查找正确内容的自动化方式。无需人工输入。
    • 恐怕你误解了我的方法。我现在正在从事两个自动化项目,我知道您不想占用人工时间。您不会只使用一种适用于所有情况的规则或正则表达式。看看 adblock 是如何工作的,并考虑为什么在阻止新广告时会有一个滑块。
    【解决方案2】:

    我还没有找到一个很好的方法来确定哪个 div 是“主要内容”,但是我找到了PhantomJS,它可以让你在服务器端呈现你正在抓取的页面,并且能够使用 Javascript 和jQuery 获取您正在抓取的页面上元素的大小和位置。

    因此,通过使用 PhantomJS,您绝对可以得到哪个 div 是“最大的”,哪个 div 在顶部或底部或中心,这对于解决找出页面上哪个 div 是“主要内容”。

    【讨论】:

    • 您好,我正在使用类似的脚本。我只是弄清楚如何检测 (更大的 Div) 。我使用 simple_html_dom 来查找页面中的所有 div。在循环内部,我会将每个 div 值添加到关联数组 foreach($e=$html-&gt;find('div') as $div){ $diva["div-$i"]=$div-&gt;plaintext; 循环完成后,我将比较并从上部 div 中删除底部 div 文本。 $diva["div-$0"]=str_replace($diva["div-4"],'',$diva["div-$0"]); 等等。所以结果将是每个 Div 的唯一内容,其中没有 Div 。这解决了您正在寻找的问题#1。
    猜你喜欢
    • 2011-12-13
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 2012-01-07
    • 2018-04-09
    • 1970-01-01
    相关资源
    最近更新 更多