【问题标题】:python lxml: syntax for selectively deleting inline style attributes?python lxml:选择性删除内联样式属性的语法?
【发布时间】:2015-12-13 14:13:39
【问题描述】:

我正在使用带有 lxml.html 库的 python 3.4。

我正在尝试从我使用 css 选择器定位的 html 元素中删除 border-bottom 内联样式。

这是一个显示示例 td 元素和我的选择器的代码片段:

html_snippet = lxml.html.fromstring("""<td valign="bottom" colspan="10" align="center" style="background-color:azure; border-bottom:1px solid #000000"><font style="font-family:Times New Roman" size="2">Estimated Future Payouts</font> \n            <br/><font style="font-family:Times New Roman" size="2">Under Non-Equity Incentive</font> \n            <br/><font style="font-family:Times New Roman" size="2">Plan Awards</font> \n        </td>""")
selection = html_snippet.cssselect('td[style*="border-bottom"]')
selection.attrib['style']
>>>>'background-color: azure;border-bottom:1px solid #000000'

访问内联样式属性的正确方法是什么,以便我可以从我的选择器定位的任何元素中删除 border-bottom 属性?

【问题讨论】:

    标签: python css html-parsing lxml lxml.html


    【解决方案1】:

    您可以通过将style 属性值拆分为; 来处理它,创建CSS 属性名称-> 值映射,从映射中删除border-bottom 并通过连接元素再次重建style 属性带有; 的地图。示例实现:

    style = selection.attrib['style']
    properties = dict([item.split(":") for item in style.split("; ")])
    
    del properties['border-bottom']
    
    selection.attrib['style'] = "; ".join([key + ":" + value for key, value in properties.items()])
    
    print(lxml.html.tostring(selection))
    

    我很确定您可以轻松破解此解决方案。


    或者,这是一个相当“疯狂”的选项 - 将数据转储到“html”文件中,通过selenium在浏览器中打开文件,通过javascript删除属性并在之后打印出元素的HTML表示:

    import os
    from selenium import webdriver   
    
    data = """
    <td valign="bottom" colspan="10" align="center" style="background-color:azure; border-bottom:1px solid #000000"><font style="font-family:Times New Roman" size="2">Estimated Future Payouts</font> \n            <br/><font style="font-family:Times New Roman" size="2">Under Non-Equity Incentive</font> \n            <br/><font style="font-family:Times New Roman" size="2">Plan Awards</font> \n        </td>
    """
    with open("index.html", "w") as f:
        f.write("<body><table><tr>%s</tr></table></body>" % data)
    
    driver = webdriver.Chrome()
    driver.get("file://" + os.path.abspath("index.html"))
    
    td = driver.find_element_by_tag_name("td")
    driver.execute_script("arguments[0].style['border-bottom'] = '';", td)
    
    print(td.get_attribute("outerHTML"))
    
    driver.close()
    

    打印:

    <td valign="bottom" colspan="10" align="center" style="background-color: rgb(240, 255, 255);"><font
            style="font-family:Times New Roman" size="2">Estimated Future Payouts</font>
        <br><font style="font-family:Times New Roman" size="2">Under Non-Equity Incentive</font>
        <br><font style="font-family:Times New Roman" size="2">Plan Awards</font>
    </td>
    

    【讨论】:

    • 谢谢!对于其他人,请注意 alecxe 的第一个答案中的 dict items 方法是 python 2 .iteritems 而不是 python 3 .items
    • @deseosuho 哎呀,是的,已修复。谢谢!
    【解决方案2】:

    有一个包可以解决这个问题,尽管在这种情况下有点矫枉过正。

    import cssutils
    sheet = cssutils.parseStyle('background-color: azure;border-bottom:1px solid #000000')
    sheet.removeProperty('border-bottom')  # returns '1px solid #000'
    print(sheet.cssText)
    

    输出background-color: azure

    【讨论】:

    • 不错的发现!我认为这是目前最简单的选择。
    猜你喜欢
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    相关资源
    最近更新 更多