【问题标题】:web crawling from BBC website using XPath使用 XPath 从 BBC 网站抓取网页
【发布时间】:2015-01-28 07:36:15
【问题描述】:

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

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

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

我已经成功爬取了一些reuters的页面,所以函数getXPathValue应该是正确的。

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

【问题讨论】:

  • 请出示您的代码,并用正确的编程语言标记问题。
  • 尝试//DIV[@class='story-body']/p/text()获取div的内容。

标签: java dom xpath web-crawler


【解决方案1】:

问题在于您正在爬取 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() 返回元素或属性名称的本地部分。在 XML 中,有 限定名称 看起来像:

prefix:root

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

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

【讨论】:

  • 我正在使用 nutch 进行网络爬取。所以我也使用 java 来开发 nutch 插件。请在第一个解决方案上启发我。同样对于您的第二个解决方案,本地名称的含义是什么?还有“*”的意思。谢谢!
  • @hao 您绝对必须分享您的代码,并重新标记问题。但在此之前,请尝试第二种解决方案,让我知道它是否有效。我将编辑我的答案并进一步解释。
  • 谢谢我在java代码中添加了供大家参考
  • @hao 其他可能的问题是:您要查找的内容是由 javascript 生成的,或者内容实际上不在该 div 中。试试//*[local-name() = 'div' and @class='story-body']//*[local-name() = 'p']
  • 对不起,它不起作用。但感谢您的努力!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
相关资源
最近更新 更多