Python BeautifulSoup用户的html5lib/lxml示例?
我试着让自己从BeautifulSoup中戒掉,我喜欢它,但它似乎(积极地)没有得到支持。我试图使用html5lib和lxml,但我似乎不知道如何使用“find”和“findall”操作符 通过查看html5lib的文档,我为一个测试程序想到了以下内容:Python BeautifulSoup用户的html5lib/lxml示例?,python,beautifulsoup,lxml,html5lib,Python,Beautifulsoup,Lxml,Html5lib,我试着让自己从BeautifulSoup中戒掉,我喜欢它,但它似乎(积极地)没有得到支持。我试图使用html5lib和lxml,但我似乎不知道如何使用“find”和“findall”操作符 通过查看html5lib的文档,我为一个测试程序想到了以下内容: import cStringIO f = cStringIO.StringIO() f.write(""" <html> <body> <table> <tr&g
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")
导入cStringIO
f=cStringIO.StringIO()
f、 写(“”)
一
1.
二
2试试:
您必须指定名称空间而不是名称空间前缀(html:tr
)。有关更多信息,请参阅lxml文档,特别是以下部分:
试试:
您必须指定名称空间而不是名称空间前缀(html:tr
)。有关更多信息,请参阅lxml文档,特别是以下部分:
似乎使用“lxml”html5libTreeBuilder
会导致html5lib在XHTML名称空间中构建树——这是有意义的,因为lxml是一个XML库,而XHTML是将HTML表示为XML的方式。您可以将lxml的qname语法与find()
方法结合使用来执行以下操作:
root.find('.//{http://www.w3.org/1999/xhtml}tr')
root.xpath('.//html:tr', namespaces={'html': 'http://www.w3.org/1999/xhtml'})
或者,您可以使用lxml的完整XPath函数执行以下操作:
root.find('.//{http://www.w3.org/1999/xhtml}tr')
root.xpath('.//html:tr', namespaces={'html': 'http://www.w3.org/1999/xhtml'})
有更多关于如何使用XML名称空间的信息。似乎使用“lxml”html5libTreeBuilder
会导致html5lib在XHTML名称空间中构建树——这很有意义,因为lxml是一个XML库,而XHTML是将HTML表示为XML的方式。您可以将lxml的qname语法与find()一起使用
执行以下操作的方法:
root.find('.//{http://www.w3.org/1999/xhtml}tr')
root.xpath('.//html:tr', namespaces={'html': 'http://www.w3.org/1999/xhtml'})
>>> 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的完整XPath函数执行以下操作:
root.find('.//{http://www.w3.org/1999/xhtml}tr')
root.xpath('.//html:tr', namespaces={'html': 'http://www.w3.org/1999/xhtml'})
有更多关于如何使用XML名称空间的信息。通常,对html使用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
通常,对html使用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
您可以使用以下命令关闭名称空间:
etree\u document=html5lib.parse(t,treebuilder=“lxml”,namespacehtmlements=False)
您可以使用以下命令关闭名称空间:
etree\u document=html5lib.parse(t,treebuilder=“lxml”,namespacehtmlements=False)
我意识到这是一个老问题,但我来到这里是为了寻找在其他任何地方都找不到的信息。我试图用BeautifulSoup刮取一些东西,但它被一些大块的html阻塞了。默认的html解析器显然没有其他可用的解析器那么松散。通常首选的解析器是lxml、 我相信这会产生与浏览器预期相同的解析。BeautifulSoup允许您指定lxml作为源解析器,但使用它需要一些工作
首先,您需要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")
那就享受你的靓汤吧
请注意解析器上的NamespaceHtmleElements=false选项。这很重要,因为lxml用于XML而不仅仅是HTML。因此,它会将提供的所有标记标记为属于HTML命名空间。这些标记看起来像(例如)
而BeautifulSoup将无法正常工作。我意识到这是一个老问题,但我来到这里是为了寻找在其他任何地方都找不到的信息。我曾试图用BeautifulSoup刮取一些东西,但它被一些大块的html阻塞了。默认的html解析器显然没有其他可用的解析器那么松散。一个经常首选的解析器是lxml,我相信它可以产生与浏览器预期相同的解析。BeautifulSoup允许您指定lxml作为源解析器,但使用它需要一些工作
首先,您需要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")
那就享受你的靓汤吧
请注意解析器上的NamespaceHtmleElements=false选项。这很重要,因为lxml用于XML而不仅仅是HTML。因此,它会将提供的所有标记标记为属于HTML命名空间。这些标记看起来像(例如)
而BeautifulSoup将无法正常工作。BeautifulSoup并非完全不受支持。作者在这里解释了问题:BeautifulSoup并非完全不受支持。作者在这里解释了问题:太好了!现在我只需要在lxml中找到解析文件的方法(而不必将文件读入字符串)我已经准备好了。啊,在找到parse-a-file时,我很高兴看到你成功了!事实上,它比那个例子更简单:lxml.html.parse
可以使用URL、文件名或类似文件的对象作为参数。但有一个问题是函数返回一个树,而不是根元素。使用lxml.html.parse(file.get_root())
获取根节点。太好了!现在我只需要在lxml中找到解析文件的方法(而不必将文件读入字符串),我已经准备好了。啊,在Am g找到了解析文件