使用 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 不区分大小写。
这是我尝试抓取的典型网页示例
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 不区分大小写。