【问题标题】:BeautifulSoup first element incorrectBeautifulSoup 第一个元素不正确
【发布时间】:2016-08-05 03:32:42
【问题描述】:

有一个有趣的问题。

注意:升级 lxml 和 bs4 到最新版本,同样的问题。

我正在解析英文维基百科。我使用wikiextractor.py 将我的转储分解为几个xml 文档,每个文档包含大约100 篇文章,分隔成<doc> 标记。每篇文章中都有锚标签,我试图将其捕获并存储在关系字段中。

但是,我遇到了一个奇怪的问题:

collection = BeautifulSoup(file, 'lxml')
entry = collection.find_all('doc')[0].find_all('a')
#this returns ALL anchor tags in the entire xml file
#but...
entry = collection.find_all('doc')[1].find_all('a')
#returns only the anchor tags for that specific entry.

xml格式一致(附在gisthere

在元素 0 上调用 entry['title'] 会返回 "The Offspring"(正确),但在元素 0 上调用 entry.text 会返回整个文件。

我是否缺少一些 xml 标头或其他内容?

【问题讨论】:

    标签: python xml beautifulsoup


    【解决方案1】:

    使用完整文件,如果您在 xml 中搜索 <div style="float:left;">,您将看到没有导致问题的结束标记。

    用坏线:

    In [2]: from bs4 import BeautifulSoup    
    In [3]: collection = BeautifulSoup(open("foo.xml").read(),"lxml")   
    In [4]: e1 = collection.find('doc').find_all('a')    
    In [5]: e2 = collection.find_all('doc')[1].find_all('a')    
    In [6]: len(e1)
    6411    
    In [7]: len(e2)
    43    
    In [8]: len(collection.find_all("a"))
    6411    
    In [9]: len(collection.find('doc').text)
    819562    
    In [10]:len(collection.find_all('doc')[1].text)
    3908    
    In [11]: len(collection.text)
    819562
    

    已删除坏行:

    In [28]: from bs4 import BeautifulSoup    
    In [29]: collection = BeautifulSoup(open("foo.xml").read(),"lxml")    
    In [30]: e1 = collection.find('doc').find_all('a')    
    In [31]: e2 = collection.find_all('doc')[1].find_all('a')    
    In [32]: len(e1)
    Out[32]: 260    
    In [33]: len(e2)
    Out[33]: 43    
    In [34]: len(collection.find_all("a"))
    Out[34]: 6411   
    In [35]: len(collection.find('doc').text
    Out[35]: 22882    
    In [36]: len(collection.find_all('doc')[1].text)
    Out[36]: 3908    
    In [37]: len(collection.text)
    Out[37]: 819564
    

    对于损坏的 html,您可以将 html.parser 与 bs4 一起使用,这更加宽容:

    In [57]: from bs4 import BeautifulSoup
    
    In [58]: collection = BeautifulSoup(open("foo.xml").read(),"html.parser")    
    In [59]: e1 = collection.find('doc').find_all('a')    
    In [60]: e2 = collection.find_all('doc')[1].find_all('a')    
    In [61]: (len(e1))
    Out[61]: 260    
    In [62]: (len(e2))
    Out[62]: 43    
    In [63]: (len(collection.find_all("a")))
    Out[63]: 6411    
    In [64]: (len(collection.find('doc').text))
    Out[64]: 22881    
    In [65]: (len(collection.find_all('doc')[1].text))
    Out[65]: 3910   
    In [66]: (len(collection.text))
    Out[66]: 819582
    

    或者使用lxml.html.soupparser结合lxml和bs4:

    In [69]: from lxml.html.soupparser import parse    
    In [70]: xml = parse(open("foo.xml"))    
    In [71]: e3 = xml.xpath("//doc[1]//a")   
    In [72]: e4 = xml.xpath("//doc[2]//a")    
    In [73]: (len(e3))
    Out[73]: 260    
    In [74]: (len(e4))
    Out[74]: 43    
    In [75]: (len(xml.xpath("//a")))
    Out[75]: 6411
    

    【讨论】:

    • 有趣。我只将文档的一部分发布到要点中。这是完整的事情:你介意再检查一次吗? gist.github.com/ianseyer/e754cf3d3df34757025f295b1f264d75
    • @ian,问题实际上出在 xml 上
    • 你是在诱导,还是发现其中有错误?
    • @ian,查看编辑删除该行并运行您的代码
    • 天哪。非常感谢。 bs4 中有没有办法忽略所有样式标签?或者,鉴于我有成百上千的此类文件,您会推荐什么?
    猜你喜欢
    • 2013-12-30
    • 1970-01-01
    • 2015-01-09
    • 2021-09-24
    • 2022-11-28
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多