【问题标题】:How do I pull data from XML document from between XML tags in Django/Python?如何从 Django/Python 中的 XML 标记之间从 XML 文档中提取数据?
【发布时间】:2011-09-14 17:16:19
【问题描述】:

我在views.py 文件中加载了一个外部 xml 文件

def test(request):

    url = urllib2.urlopen("http://someurl.com?xml")
    dom = minidom.parse(url)

    groups = dom.getElementsByTagName("group")

    deal_holder = []

    #    Iterate over each DOM group element:
    for group in groups:
        # Iterate over each child node
        for groupChild in group.childNodes:
            deal_holder.append(groupChild)

    return render_to_response('folder/test.html', {'deal_holder':deal_holder})

这是加载的 XML 文件的样子:

<page>
    <site>
        <siteid>25550</siteid>
        <sitename>
            <![CDATA[ Some Text Here ]]>
        </sitename>
        <sitelink>
            http://somelinkehere.com
        </sitelink>
        <timezone>
            <![CDATA[ Pacific Time ]]>
        </timezone>
    </site>
    <groups>
        <enablefeaturedgroup>OFF</enablefeaturedgroup>
        <group>
            <groupid>467246</groupid>
            <groupname>
                <![CDATA[ Today's Deal ]]>
            </groupname>
            <groupdescription>
                <![CDATA[ ]]>
            </groupdescription>
            </group>
            <group>
            <groupid>467247</groupid>
            <groupname>
                <![CDATA[ Past Deals ]]>
            </groupname>
            <groupdescription>
                <![CDATA[ ]]>
            </groupdescription>
        </group>
    </groups>
</page>

问题是我看到的所有示例都使用类似于我正在使用的东西,除了它们通常具有如下所示的 XML 标记:&lt;weather:forecast day="Wed" date="14 Sep 2011" low="56" high="72" text="AM Clouds/PM Sun" code="30"/&gt; 并且能够从诸如 @ 之类的东西中检索信息987654325@,date="14 Sep 2011"low="56"等...但我要检索的信息实际上是在&lt;siteid&gt;25550&lt;/siteid&gt;等标签之间

任何建议或信息将不胜感激。

【问题讨论】:

    标签: python xml django django-views web-scraping


    【解决方案1】:

    使用 minidom 与 javascript 非常相似。

    from xml.dom import minidom
    from StringIO import StringIO
    a = """<page>
        <site>
            <siteid>25550</siteid>
            <sitename>
                <![CDATA[ Some Text Here ]]>
            </sitename>
            <sitelink>
                http://somelinkehere.com
            </sitelink>
            <timezone>
                <![CDATA[ Pacific Time ]]>
            </timezone>
        </site>
        <groups>
            <enablefeaturedgroup>OFF</enablefeaturedgroup>
            <group>
                <groupid>467246</groupid>
                <groupname>
                    <![CDATA[ Today's Deal ]]>
                </groupname>
                <groupdescription>
                    <![CDATA[ ]]>
                </groupdescription>
                </group>
                <group>
                <groupid>467247</groupid>
                <groupname>
                    <![CDATA[ Past Deals ]]>
                </groupname>
                <groupdescription>
                    <![CDATA[ ]]>
                </groupdescription>
            </group>
        </groups>
    </page>
    """
    tree = minidom.parse(StringIO(a))
    groups = tree.getElementsByTagName("group")
    

    如果您使用 urllib,则不需要使用 StringIO,因为 minidomparse 方法需要一个类似文件的对象(urllib.urlopen 仅返回该对象)。

    我建议不要将此列表传递给 django 模板系统。你应该进一步解析它。

    #    Iterate over each DOM group element:
    group_dictionaries = []
    for group in groups:
        group_dict = {}
        # Iterate over each child node
        # instead of for loop maybe print groupChildNodes[0] for groupid
        # print groupChildNodes[1] for groupname
        for groupChild in group.ChildNodes:
            # do something with each node
            group_dict[groupChild.tagName] = groupChild.data
        group_dictionaries.append(group_dict)
    
      Now in the template:
      {% for group in group_dictionaries %}
          {{ group.groupid }}
          {{ group.groupname }}
          etc.
      {% endfor %}
    

    您可以将它们的值保存在字典列表中。

    【讨论】:

    • 因为我使用的是 django,所以我这样做了data = dom.getElementsByTagName("group"),然后将data 变量传递给模板,在模板中我执行{{ data }},它输出1 - [&lt;DOM Element: group at 0x967b5cc&gt;, &lt;DOM Element: group at 0x9539f8c&gt;]。我如何能够从中检索任何数据,例如 groupidgroupname 谢谢!
    • 我更新了上面的代码,以反映我根据您的建议所做的一些更改。但问题是,在我的template 文件中,我添加了{{ deal_holder }},它输出[&lt;DOM Text node " "&gt;, &lt;DOM Element: groupid at 0x99cfd8c&gt;, &lt;DOM Text node " "&gt;, &lt;DOM Element: groupname at 0x8b220ec&gt;, &lt;DOM Text node " "&gt;, &lt;DOM Element: groupdescription at 0x992f1cc&gt;, &lt;DOM Text node " "&gt;, &lt;DOM Text node " "&gt;, &lt;DOM Element: groupid at 0x9a0d34c&gt;, etc...],所以我仍然无法获取信息。我对 python/django 很陌生,所以我可能会遗漏一些明显的东西。感谢您的帮助。
    • 查看我的编辑。发生这种情况是因为您的 deal_holder 变量包含一个列表,并且这是一个被打印的列表的表示。
    • 我现在收到Exception Value: Text instance has no attribute 'tagName'的错误
    【解决方案2】:

    使用lxml,您可以执行以下操作:

    import lxml.etree
    
    tree = lxml.etree.parse("http://someurl.com")
    sites = tree.xpath("//site")
    
    for site in sites:
        siteid = site.find("siteid").text
        print siteid
    

    【讨论】:

    • 你还有什么我的例子没有涵盖的事情吗?
    • 我无法导入 lxml.etree,我不确定是否可以将它安装在我的服务器上。另外,您介意从您的示例中删除实际的 URL 吗?我一定是错误地包含了它。谢谢!
    • 嗯,好的,已删除。如果您设法在您的服务器上安装了 lxml,请随时提出您的任何问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多