代码之家  ›  专栏  ›  技术社区  ›  Chris Curvey

BeautifulSoup用户的html5lib/lxml示例?

  •  1
  • Chris Curvey  · 技术社区  · 14 年前

    import cStringIO
    
    f = cStringIO.StringIO()
    f.write("""
      <html>
        <body>
          <table>
           <tr>
              <td>one</td>
              <td>1</td>
           </tr>
           <tr>
              <td>two</td>
              <td>2</td
           </tr>
          </table>
        </body>
      </html>
      """)
    f.seek(0)
    
    import html5lib
    from html5lib import treebuilders
    from lxml import etree  # why?
    
    parser = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("lxml"))
    etree_document = parser.parse(f)
    
    root = etree_document.getroot()
    
    root.find(".//tr")
    

    etree.tostring(root) 我把所有的数据都拿回来了,但是我所有的标签都有 html (例如。 <html:table> ). 但是 root.find(".//html:tr") 抛出一个键错误。

    有人能让我回到正轨吗?

    5 回复  |  直到 14 年前
        1
  •  5
  •   Tim McNamara    14 年前

    一般来说,使用 lxml.html

    >>> import lxml.html as l
    >>> doc = """
    ...    <html><body>
    ...    <table>
    ...      <tr>
    ...        <td>one</td>
    ...        <td>1</td>
    ...      </tr>
    ...      <tr>
    ...        <td>two</td>
    ...        <td>2</td
    ...      </tr>
    ...    </table>
    ...    </body></html>"""
    >>> doc = l.document_fromstring(doc)
    >>> doc.finall('.//tr')
    [<Element tr at ...>, <Element tr at ...>] #doctest: +ELLIPSIS
    

    仅供参考, lxml.html文件

    >>> doc.cssselect('tr')
    [<Element tr at ...>, <Element tr at ...>] #doctest: +ELLIPSIS
    
        2
  •  6
  •   gsnedders    9 年前

    etree_document = html5lib.parse(t, treebuilder="lxml", namespaceHTMLElements=False)

        3
  •  3
  •   llasram    14 年前

    似乎使用“lxml”html5lib TreeBuilder find() 方法执行以下操作:

    root.find('.//{http://www.w3.org/1999/xhtml}tr')
    

    root.xpath('.//html:tr', namespaces={'html': 'http://www.w3.org/1999/xhtml'})
    

    这个 lxml documentation

        4
  •  1
  •   ETB    9 年前

    首先,您需要html5lib,还必须安装lxml。虽然html5lib已经准备好使用lxml(以及其他一些库),但这两个库并没有打包在一起。[对于Windows用户来说,尽管我不喜欢对Win依赖项大惊小怪,因为我通常通过在项目所在的同一目录中制作副本来获取库,但我强烈建议使用pip;非常简单;我认为您需要管理员访问权限。]

    然后你需要这样写:

    import urllib2
    from bs4 import BeautifulSoup
    import html5lib
    from html5lib import sanitizer
    from html5lib import treebuilders
    from lxml import etree
    
    url = 'http://...'
    
    content = urllib2.urlopen(url)
    parser = html5lib.HTMLParser(tokenizer=sanitizer.HTMLSanitizer,
                                 tree=treebuilders.getTreeBuilder("lxml"),
                                 namespaceHTMLElements=False)
    htmlData = parser.parse(content)
    htmlStr = etree.tostring(htmlData)
    
    soup = BeautifulSoup(htmlStr, "lxml")
    

    那就好好享受你的靓汤吧!

    注意解析器上的namespaceHTMLElements=false选项。这一点很重要,因为lxml是针对XML的,而不仅仅是HTML。因此,它会将它提供的所有标记标记为属于HTML名称空间。标签看起来像(例如)

    <html:li>
    

    而美团也不会很好的运作。

        5
  •  0
  •   ars    14 年前

    尝试:

    root.find('.//{http://www.w3.org/1999/xhtml}tr')
    

    必须指定名称空间而不是名称空间前缀( html:tr