【问题标题】:Remotely Scrape Page and Get most Relevant title or Description for Images with XPath使用 XPath 远程抓取页面并获取图像的最相关标题或描述
【发布时间】:2012-05-26 22:12:51
【问题描述】:

我正在做的事情基本上与 Tweet 按钮或 Facebook Share/Like 按钮所做的事情相同,那就是抓取一个页面和最相关的标题以获取一段数据。我能想到的最好的例子是当你在一个有很多文章的网站的首页上,然后你点击了 Facebook 的 Like 按钮。然后,它将获取与(最近的)Like 按钮相关的帖子的正确信息。有些网站有 Open Graph 标签,但有些没有,它仍然有效。

由于这是远程完成的,我只能控制我想要定位的数据。在这种情况下,数据是图像。我不是只检索页面的<title>,而是希望以某种方式从每个图像的起点反向遍历dom,并找到最近的“标题”。问题是并非所有标题都出现在图像之前。但是,在这种情况下,图像出现在标题之后的机会似乎相当高。话虽如此,我希望它能在几乎所有网站上正常运行。

想法:

  • 找到图像的“容器”,然后使用第一块文本。
  • 在包含特定类(“description”、“title”)或元素(h1、h2、h3、h4)的元素中查找文本块。

标题备份:

  • 使用开放图标签
  • 仅使用<title>
  • 仅使用 ALT 标记
  • 使用 META 标签

总结:提取图像不是问题,关键是如何为它们获取相关标题。

问题:您将如何为每张图片获取相关标题?也许使用 DomDocument 或 XPath?

【问题讨论】:

  • 老实说,在您使用 PHP 抓取它之后,如果您可以通过 REST 调用将其交给小型 Java Web 服务器,您可以使用 JSOUP 轻松访问所有这些元素和属性。 JSOUP 类似于 Java 中的 jQuery,并且使用几乎相同的语法。我希望它可用于 PHP,因为它会让您的问题在几秒钟内消失!
  • 有几个库可以处理从页面中提取的内容,尽管我不知道有哪个库可以直接处理图像。但你可能会得到一些想法和方向,或者能够使用它们。这是一个:code.google.com/p/boilerpipe/wiki/Components
  • 感谢您的想法。我已经更新了我的问题,以针对获取每个图像的相关标题或描述背后的更多“逻辑”,而不是如何获取图像本身。
  • @stwhite 我曾经做过一个图片搜索引擎,虽然逻辑不一样,但我做的是索引(除了 ALT、TITLE 等)——dom 中合理距离内的文本该图像的(我想要页面中各种图像的不同文本)。它工作得相当好,我不记得确切的启发式方法,但一般的想法是,文本块越接近图像,它就越相关。
  • @Not_a_Golfer 这正是我的想法。本质上是给它与图像针点的关系打分。你还记得你是否对某些标签(h1、h2、h3、h4、h5、p)或标签上的类进行加权?

标签: php facebook xpath html-parsing scrape


【解决方案1】:

您的方法似乎已经足够好了,我只会给某些标签/属性一个权重,并使用 XPath 查询循环遍历它们,直到我找到退出的东西并且它不是无效的。比如:

i = 0

while (//img[i][@src])
  if (//img[i][@alt])
    return alt
  else if (//img[i][@description])
    return description
  else if (//img[i]/../p[0])
    return p
  else
    return (//title)

  i++

一个简单的 XPath 示例(函数ported from my framework):

function ph_DOM($html, $xpath = null)
{
    if (is_object($html) === true)
    {
        if (isset($xpath) === true)
        {
            $html = $html->xpath($xpath);
        }

        return $html;
    }

    else if (is_string($html) === true)
    {
        $dom = new DOMDocument();

        if (libxml_use_internal_errors(true) === true)
        {
            libxml_clear_errors();
        }

        if ($dom->loadHTML(ph()->Text->Unicode->mb_html_entities($html)) === true)
        {
            return ph_DOM(simplexml_import_dom($dom), $xpath);
        }
    }

    return false;
}

以及实际用法:

$html = file_get_contents('http://en.wikipedia.org/wiki/Photography');

print_r(ph_DOM($html, '//img')); // gets all images
print_r(ph_DOM($html, '//img[@src]')); // gets all images that have a src
print_r(ph_DOM($html, '//img[@src]/..')); // gets all images that have a src and their parent element
print_r(ph_DOM($html, '//img[@src]/../..')); // and so on...
print_r(ph_DOM($html, '//title')); // get the title of the page

【讨论】:

  • 我一直在阅读有关 XPath 的文章,实际上已经开始测试一些选项,但您能对此进行扩展吗?找到节点之间的距离似乎是个好主意,但是我还没有想出解决方案。
  • @stwhite:实际上这不是我的想法,您只需从最高级别的特异性(img 标签)开始,然后逐步向上,直到找到您想要考虑的东西作为描述性的。
  • 我知道这不是您最初的想法,但是您对如何获取找到的节点之间的距离有任何想法吗?例如,找到当前图像到前一个 H1 的位置与从图像到前一个 h2 的距离。这似乎会给出一个更可能是“更好”标题的分数。从本质上讲,这实际上是关于哪个先出现或哪个更接近图像。
  • @stwhite:数一下/..的数量?实际上,我认为描述可以在图像之前之后,您可能想看看w3schools.com/xpath/xpath_syntax.aspw3schools.com/xpath/xpath_axes.asp,即precedingfollowing
  • 我知道前面和后面,并编写了一个用于检索一系列元素的系统,但仅计算 '/..' 的问题并不能说明与父级的相对索引位置也可能包含 h1,h2。我实际上是在尝试找到最低共同祖先来帮助索引:community.topcoder.com/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
相关资源
最近更新 更多