【问题标题】:Can't find html sub-elements from inside an element无法从元素内部找到 html 子元素
【发布时间】:2021-10-19 18:16:29
【问题描述】:

我在抓取包含大量子元素的网站方面有些缺乏经验,我正在尝试了解循环遍历具有您希望将数据隐藏在更多子元素级别中的元素的最佳方法。

这是一个 HTML 示例

<div class="s-item__info clearfix">
      <h3 class="s-item__title">The Music Tree Activities Book: Part 1 (Music Tree (Summy)) by Clark, Frances, </h3>
   </a>
   <div class="s-item__subtitle"><span class="SECONDARY_INFO">Pre-Owned</span></div>
   <div class="s-item__reviews">
   </div>
   <div class="s-item__details clearfix">
      <div class="s-item__detail s-item__detail--primary"><span class="s-item__price">$3.99</span></div>
      <span class="s-item__detail s-item__detail--secondary">
      </span>
      <div class="s-item__detail s-item__detail--primary"><span class="s-item__purchase-options-with-icon" aria-label="">Buy It Now</span></div>
      <div class="s-item__detail s-item__detail--primary"><span class="s-item__shipping s-item__logisticsCost">Free shipping</span></div>
      <div class="s-item__detail s-item__detail--primary"><span class="s-item__free-returns s-item__freeReturnsNoFee">Free returns</span></div>
      <div class="s-item__detail s-item__detail--primary"></div>
   </div>
</div>

有多个项目,所以我首先将所有项目都放在一个列表中,我可以通过迭代找到每个标题,但在获取价格时遇到了问题。示例代码

for item in driver.find_elements_by_class_name("s-item__info"):
    title = item.find_element_by_xpath('.//h3')
    print(title.text)
    details = item.find_element_by_xpath('.//span[@class="s-item__price"]')
    print(details.text)

这会获取商品的标题,但找不到价格。如果我在“s-item_info”元素之外查看并仅使用驱动程序,我可以使用下面的代码获取所有价格,但想知道为什么它无法在 info 元素中找到它,我认为细节将是一个子元素和 . // 会浏览那些。

driver.find_elements_by_class_name("s-item__price")

也试过

find_element_by_xpath('.//div[@class="s-item__detail"]//span[@class="s-item__price"]')

我可以获取我需要的数据,但想了解为什么我在尝试遍历每个项目时无法获得价格。谢谢

【问题讨论】:

  • 你能分享一个指向那个页面的链接吗?另外,顺便说一句,//div[@class="s-item__detail"] 将不起作用,因为那里有一个额外的类名,你应该改用//div[contains(@class,"s-item__detail")]
  • Ebay ebay.com/sch/184644/… 感谢您的回复。我最近也尝试过包含但没有运气。

标签: python html selenium xpath


【解决方案1】:

看看这是否有效

for item in driver.find_elements_by_class_name("s-item__info"):
    title = item.find_element_by_xpath('.//h3')
    print(title.text)
    details = item.find_element_by_xpath('.//following::div[contains(@class,'s-item__details')]//span[@class='s-item__price']')
    print(details.text)

【讨论】:

  • 有趣,这似乎有效。我猜测以下:: 做我认为 .// 应该自己做的事情。如果您能够解释它究竟做了什么以及它与 .// 有何不同,那将不胜感激。快速的谷歌搜索让我想到以下::寻找项目的兄弟姐妹,但我会认为“div class= item__details”是项目的孩子。感谢您的帮助
  • 我说“following::”查看从当前节点(即 . //)。所以 's-item__price' 和 s-item__price' 是兄弟姐妹?再次感谢。
【解决方案2】:

好的,这里有几个问题:

  1. s-item__info 不是该元素上唯一的类名,您应该使用 改为//div[contains(@class,'s-item__info')]

  2. 与此类名称匹配的第一个元素不是有效的搜索结果。
    使您的代码工作的简单方法可以是:

for item in driver.find_elements_by_xpath("//div[contains(@class,'s-item__info')]"):
    title = item.find_elements_by_xpath('.//h3')
    if(title):
        print(title[0].text)
    details = item.find_elements_by_xpath('.//span[@class="s-item__price"]')
    if(details):
        print(details[0].text)

如果存在则打印数据,否则只打印空字符串

【讨论】:

  • 1.谢谢,我现在理解得更好了 2。这会返回超出范围的列表索引,这表明它是空的,我相信
  • 查看更新后的答案。现在它应该可以工作了。
猜你喜欢
  • 1970-01-01
  • 2015-07-29
  • 2021-08-15
  • 1970-01-01
  • 2016-02-20
  • 2022-12-09
  • 1970-01-01
  • 2022-07-05
  • 2011-08-14
相关资源
最近更新 更多