【问题标题】:Using BeautifulSoup with multiple tags with the same name将 BeautifulSoup 与多个具有相同名称的标签一起使用
【发布时间】:2017-02-09 22:26:15
【问题描述】:

我有下面的html

<g class="1581 sqw_sv5" style="cursor: pointer;">
 <path d="M397.696,126.554C397.696,126.554,404.57504,140.2417375,404.57504,140.2417375" stroke="#ffffff" style="stroke-width: 3.6; stroke-opacity: 0.5; stroke-linecap: round; fill-opacity: 0;">
 </path>
 <path d="M397.696,126.554C397.696,126.554,404.57504,140.2417375,404.57504,140.2417375" stroke="#f95a0b" style="stroke-width: 1.2; stroke-linecap: round; fill-opacity: 0;">
 </path>

我需要获取第二个path中'stroke'的值。我当前的代码只是从第一个 path 中提取值。

我正在使用

shots = soup.find_all('g')
for shot in shots:
    print(shot.path['stroke'])

返回#ffffff。我需要它返回#f95a0b

【问题讨论】:

  • 总是第二条路径吗?

标签: python beautifulsoup


【解决方案1】:

你需要先用find_all找到所有路径的,然后提取最后一个:

h = """<g class="1581 sqw_sv5" style="cursor: pointer;">
 <path d="M397.696,126.554C397.696,126.554,404.57504,140.2417375,404.57504,140.2417375" stroke="#ffffff" style="stroke-width: 3.6; stroke-opacity: 0.5; stroke-linecap: round; fill-opacity: 0;">
 </path>
 <path d="M397.696,126.554C397.696,126.554,404.57504,140.2417375,404.57504,140.2417375" stroke="#f95a0b" style="stroke-width: 1.2; stroke-linecap: round; fill-opacity: 0;">
 </path>"""
soup = BeautifulSoup(h)
shots = soup.find_all('g')
for shot in shots:
    print(shot.find_all("path", stroke=True)[-1]["stroke"]

使用shot.path['stroke'] 等同于使用shot.find("path")['stroke'],它只会返回第一个路径。

或者使用 nth-of-type 也可以根据 html 的结构工作:

soup = BeautifulSoup(h)
shots = soup.find_all('g')
for shot in shots:
    print(shot.select_one("path:nth-of-type(2)")["stroke"])

【讨论】:

    【解决方案2】:

    这是我对您的问题的解决方案。我对我的回答的问题是它可能过于具体。这只有在style 的值始终为"stroke-width: 1.2; stroke-linecap: round; fill-opacity: 0;" 并且整个文档中只有一个这样的path 元素时才有效。

    此解决方案背后的想法是通过查找包含所需属性的所需元素的独特之处来快速缩小元素范围。

    `
    from bs4 import BeautifulSoup
    
    html = """"<g class="1581 sqw_sv5" style="cursor: pointer;">
     <path d="M397.696,126.554C397.696,126.554,404.57504,140.2417375,404.57504,140.2417375" stroke="#ffffff" style="stroke-width: 3.6; stroke-opacity: 0.5; stroke-linecap: round; fill-opacity: 0;">
     </path>
     <path d="M397.696,126.554C397.696,126.554,404.57504,140.2417375,404.57504,140.2417375" stroke="#f95a0b" style="stroke-width: 1.2; stroke-linecap: round; fill-opacity: 0;">
     </path>"""
    
    soup = BeautifulSoup(html, "html.parser")
    # get the desired 'path' element using the 'style' that identifies it
    desired_element =  soup.find("path", {"style" : "stroke-width: 1.2; stroke-linecap: round; fill-opacity: 0;"})
    # get the attribute value from the extracted element
    desired_attribute = desired_element["stroke"]
    print (desired_attribute)
    # prints #f95a0b
    `
    

    如果这种方法行不通,那么您可能必须使用 BeautifulSoups 的 next_siblingfindNext 方法。基本上查找您当前正在使用代码完成的第一个路径元素,然后从那里“跳转”到包含您需要的内容的下一个路径元素。

    查找下一个:Beautifulsoup - nextSibling

    next_sibling:https://www.crummy.com/software/BeautifulSoup/bs4/doc/#next-sibling-and-previous-sibling

    【讨论】:

    • 谢谢。我无法使用您的第一个建议,但 next_sibling 效果很好。
    猜你喜欢
    • 2011-07-07
    • 2011-09-25
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多