7

我有以下 XML 文件:

<user-login-permission>true</user-login-permission>
        <total-matched-record-number>15000</total-matched-record-number>
        <total-returned-record-number>15000</total-returned-record-number>
        <active-user-records>
            <active-user-record>
                <active-user-name>username</active-user-name>
                <authentication-realm>realm</authentication-realm>
                <user-roles>Role</user-roles>
                <user-sign-in-time>date</user-sign-in-time>
                <events>0</events>
                <agent-type>text</agent-type>
                <login-node>node</login-node>
             </active-user-record> 

有许多记录我试图从标签中获取值并使用以下代码将它们保存在不同的文本文件中:

soup = BeautifulSoup(open("path/to/xmlfile"), features="xml") 


with open('path/to/outputfile', 'a') as f:
    for i in range(len(soup.findall('active-user-name'))):
        f.write ('%s\t%s\t%s\t%s\n' % (soup.findall('active-user-name')[i].text, soup.findall('authentication-realm')[i].text, soup.findall('user-roles')[i].text, soup.findall('login-node')[i].text))

我收到错误 TypeError : 'NoneType' object not callable Python with BeautifulSoup XML for line : for i in range(len(soup.findall('active-user-name'))):

知道是什么原因造成的吗?

谢谢!

4

3 回答 3

8

有许多问题需要解决,第一个是您提供的 XML 文件不是有效的 XML - 需要根元素。

尝试像这样的 XML:

<root>
    <user-login-permission>true</user-login-permission>
    <total-matched-record-number>15000</total-matched-record-number>
    <total-returned-record-number>15000</total-returned-record-number>
    <active-user-records>

        <active-user-record>
            <active-user-name>username</active-user-name>
            <authentication-realm>realm</authentication-realm>
            <user-roles>Role</user-roles>
            <user-sign-in-time>date</user-sign-in-time>
            <events>0</events>
            <agent-type>text</agent-type>
            <login-node>node</login-node>
        </active-user-record>

    </active-user-records>
</root>

现在进入蟒蛇。首先没有findall方法,它是findAllor find_allfindAll并且find_all是等效的,如此处所述

接下来,我建议更改您的代码,这样您就不会find_all经常使用该方法 - 使用该方法find将提高效率,尤其是对于大型 XML 文件。此外,下面的代码更易于阅读和调试:

from bs4 import BeautifulSoup

xml_file = open('./path_to_file.xml', 'r')

soup = BeautifulSoup(xml_file, "xml") 

with open('./path_to_output_f.txt', 'a') as f:
    for s in soup.findAll('active-user-record'):
        username = s.find('active-user-name').text
        auth = s.find('authentication-realm').text
        role = s.find('user-roles').text
        node = s.find('login-node').text
        f.write("{}\t{}\t{}\t{}\n".format(username, auth, role, node))

希望这可以帮助。如果您需要任何进一步的帮助,请告诉我!

于 2013-08-02T12:10:34.617 回答
2

解决方案很简单:不要使用findallmethod - use find_all

为什么?因为根本没有findall方法,所以有findAllfind_all,它们是等价的。有关更多信息,请参阅文档

虽然,我同意,错误信息令人困惑。

希望有帮助。

于 2013-08-01T18:03:29.443 回答
0

我对这个问题的解决方法是将 BeautifulSoup 实例强制转换为类型字符串。您可以执行以下操作: https ://groups.google.com/forum/#!topic/comp.lang.python/ymrea29fMFI

您使用以下 pythonic:来自 python 手册

str([对象])

返回一个字符串,其中包含一个对象的可很好打印的表示。对于字符串,这将返回字符串本身。与 repr(object) 的区别在于 str(object) 并不总是试图返回一个 eval() 可接受的字符串;它的目标是返回一个可打印的字符串。如果没有给出参数,则返回空字符串,

于 2014-04-20T23:24:41.373 回答