使用XPath从BBC网站爬网

时间:2015-01-28 07:36:16

标签: java dom xpath web-crawler

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

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']"));

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

我已成功抓取路透社的一些网页,因此功能getXPathValue应该是正确的。

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

1 个答案:

答案 0 :(得分:0)

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

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

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

//root

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


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

注册XHTML名称空间

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

忽略名称空间

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

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

此处*是任何(或没有)命名空间中任何元素的通配符,local-name()返回元素或属性名称的本地部分。在XML中,有限定名称,如下所示:

prefix:root

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

另请注意,我有小写&#34; div&#34;。 HTML可能不区分大小写,但XHTML,以及扩展,XML和扩展,XPath不是。