【问题标题】:more elegant xpath solution?更优雅的 xpath 解决方案?
【发布时间】:2018-04-28 04:41:36
【问题描述】:

我正在抓取一个论坛并尝试检索有关帖子的统计信息,特别是帖子获得的查看次数和回复次数。

我正在解析的页面源如下所示:

<ul class="ipsDataItem_stats">
<li>
    <span class="ipsDataItem_stats_number">61</span>
    <span class="ipsDataItem_stats_type"> replies</span>
</li>
<li class="ipsType_light">
    <span class="ipsDataItem_stats_number">6,106</span>
    <span class="ipsDataItem_stats_type"> views</span>
</li>           

我已经编写了一些代码来提取我正在寻找的内容,但我想知道你们 xpath 专家会如何处理这个问题。

Stats = node.find_elements_by_xpath('.//ul[@class="ipsDataItem_stats"]')
Replies = (Stats[0].find_elements_by_xpath('.//span[@class="ipsDataItem_stats_number"]'))[0].text
Views = (Stats[0].find_elements_by_xpath('.//span[@class="ipsDataItem_stats_number"]'))[1].text

我的解决方案依赖于按特定顺序排列的统计数据,我想知道是否有更准确的方法来实现相同的结果。

例如伪代码:

Replies = node.find_elements_by_xpath({get span text where class = "ipsDataItem_stats" and sibling span class = "ipsDataItem_stats_type" and text = "replies"})

【问题讨论】:

  • more accuratemore elegant 到底是什么意思?这些 xpath 表达式有什么问题?
  • 当网站呈现页面并翻转 li 元素以使浏览量第一而回复第二时会发生什么?或者他们添加了一个额外的统计数据,因此 Stats[0] 需要成为 Stats[1] 或 Stats[2] 等。我正在寻找一种方法来更准确地获取我所追求的元素,而不依赖它们在列表。
  • 因此,如果您查看我的伪代码,这将是一种使用 1 个 xpath 查询填充回复的方法,我只是不知道如何构造该查询。

标签: python-2.7 selenium xpath


【解决方案1】:

您可以查看描述统计信息的标签。一般的 xpath 看起来像这样:

'//ul[@class="ipsDataItem_stats"][<FILL HERE RECORDS POSITION>]//li[contains(., "<FILL HERE RECORDS LABEL>")]/span[@class="ipsDataItem_stats_number"]'

对于回复和视图,我们得到以下 xpath:

FirstRecordsRepliesXpath = '//ul[@class="ipsDataItem_stats"][0]//li[contains(., "replies")]/span[@class="ipsDataItem_stats_number"]'
FirstRecordsViewsXpath = '//ul[@class="ipsDataItem_stats"][0]//li[contains(., "views")]/span[@class="ipsDataItem_stats_number"]'

这样您就不需要知道有关订单的任何信息。但是你需要知道标签,这应该没问题。

【讨论】:

    【解决方案2】:

    我会通过两步管道来解决这个问题。第一步是使用 XSLT 转换为更清晰的 XML 格式,第二步是查询该清晰的 XML。此片段的清理后的 XML 可能如下所示:

    <ipsDataItem_stats>
      <replies>61</replies>
      <views>6106</views>
    </ipsDataItem_stats>
    

    这种方法的好处是清理阶段是完全可重用的,并且独立于您要运行的实际查询;编写完成后,任何后续查询都非常容易编写。

    【讨论】:

    • 开始深入研究 xslt 文档,但我在网上找到的大多数示例都是使用此库生成 xml。如何使用这个库重新格式化这样的输出?
    • 不要试图通过在线查找示例来学习 XSLT(或任何其他语言)。这是一种非常低效的学习策略。您会尝试通过寻找人们驾驶的视频片段来学习驾驶吗?给自己买一本好书,然后蜷缩在床上。
    【解决方案3】:

    我正在寻找一种方法来更准确地获取我的元素 在不依赖他们在列表中的位置之后。

    元素可以通过它们的类名相互区分

    <span class="ipsDataItem_stats_number">61</span>
    <span class="ipsDataItem_stats_type"> replies</span>
    

    所以对第一个元素使用下面的 xpath 表达式:

    .//span[ contains( @class, 'stats_number')]
    

    对于第二个元素

    .//span[ contains( @class, 'stats_type')]
    

    这样表达式会抵抗元素顺序的变化。

    【讨论】:

    • 有 2 个 span 元素包含 class= "stats_number"。那么这不只是返回一个列表,我仍然需要根据列表顺序引用这些值吗?
    • 是的,它提供了所有匹配元素的列表。只需遍历列表即可访问各个元素。
    • .//span[ contains( @class, 'stats_number')]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    相关资源
    最近更新 更多