使用 XPath 从 BBC 网站抓取网页

web crawling from BBC website using XPath

这是我尝试抓取的典型网页示例

http://www.bbc.com/news/business-31013604

如果你检查网页的元素。主要文章在

<div class="story-body">

但是,当我尝试使用

获取主要内容时
         MongoClient mongoClient = new MongoClient("127.0.0.1", 27017);
        DB db = mongoClient.getDB("nutch");
        DBCollection coll = db.getCollection("crawl_data");
        BasicDBObject bo = new BasicDBObject("url", url).append("fetch_time", new Date());

        bo.append("article_text", getXPathValue(doc,"//DIV[@class='story-body']"));

我无法获取文章内容。在数据库中,它在该字段中显示为空。

我已经成功地从路透社抓取了一些页面,所以函数getXPathValue 应该是正确的。

我使用 http 请求获取页面。不知道是不是这里的问题。

问题是您正在抓取 XHTML 页面(或至少是 XHTML 命名空间中的文档)。 HTML 和 XHTML 之间最显着的区别是 XHTML 文档有一个 default 命名空间:

<root xmlns="www.example-of-default-namespace.com"/>

不考虑名称空间的 XPath 表达式,例如

//root

永远找不到这个元素,因为它在命名空间中。


您的 XHTML 文档也是如此。有两种方法可以解决这个问题。

注册 XHTML 命名空间

第一个也是更合适的解决方案是 注册声明 代码中的 XHTML 命名空间,然后在 XPath 表达式中使用前缀。由于您没有显示任何代码,我很难对此发表评论,我们甚至都不知道编程语言。

忽略命名空间

其次,您可以通过将 XPath 表达式修改为

来忽略任何命名空间
//*[local-name() = 'div' and @class='story-body']

此处 * 是任何(或没有)名称空间中任何元素的通配符,local-name() returns 是元素或属性名称的本地部分。在 XML 中,有 个符合条件的名称 看起来像:

prefix:root

这个限定名的第一部分是前缀,第二部分是这个元素的本地名称。所以,local-name(prefix:root) 的结果是 root.

另请注意,我已将 "div" 小写。 HTML 可能不区分大小写,但 XHTML 和 XML 以及 XPath 不区分大小写。