使用BeautifulSoup解析格式错误的属性

时间:2015-12-17 21:20:01

标签: python html beautifulsoup

我正在尝试提取包含无效的未转义引号的属性:

<meta content="mal"formed">

使用BeautifulSoup时:

soup.find('meta')['content']

正如预期的那样,结果是mal

有没有办法让BeautifulSoup将未转义的引用视为属性的一部分,结果将是mal"formed

2 个答案:

答案 0 :(得分:0)

以下是我试图解决的HTML问题:

  • different BeautifulSoup parsers - html.parserhtml5liblxml
  • lxml.html with and without recover=True

    from lxml.html import HTMLParser, fromstring, tostring
    
    data = """<meta content="mal"formed">"""
    
    parser = HTMLParser(recover=True)
    print tostring(fromstring(data, parser=parser))
    

    打印:

    <html><head><meta content="mal" formed></head></html>
    
  • 通过seleniumFirefoxChrome开火并向他们提供损坏的元标记:

    from selenium import webdriver
    
    data = """<meta content="mal"formed">"""
    
    driver = webdriver.Chrome()  # or webdriver.Firefox
    driver.get("about:blank")
    
    driver.execute_script("document.head.innerHTML = '{html}';".format(html=data))
    data = driver.page_source
    driver.close()
    
    print data
    

    打印:

    <html xmlns="http://www.w3.org/1999/xhtml"><head><meta content="mal" formed"="" /></head><body></body></html>
    

不同的工具以不同的方式解释HTML,但没有工具提供所需的输出。

我想,根据您对数据的了解程度,在这种情况下,使用正则表达式对其进行预处理可能是一个实用的解决方案。

答案 1 :(得分:0)

使用正则表达式进行一些试验和错误之后,这是我迄今为止最好的解决方案:

html = re.sub('(content="[^"=]+)"([^"=]+")', r'\1&quot;\2', html)
soup = BeautifulSoup(html)    
soup.find('meta')['content']

说明:一开始我试图只在所需的元素上运行正则表达式。但是在执行str(element)时,BeautifulSoup不会返回原始html,而是重新格式化的html,它已经不包含属性的formed(无效)部分。

所以我的解决方案是基于在整个HTML上搜索这种确切类型的格式错误的属性,并使用正则表达式修复它。当然,这对我的案例非常具体。

非常感谢更好(并且希望不那么强硬)的解决方案。