将`requests.get`对象解析为`pandas.DataFrame`的`xml`

0 投票
1 回答
1823 浏览
提问于 2025-04-18 10:28

我成功地用 requests.get(url)Zillow的获取区域子项API 创建了一个对象,使用的代码如下:

import requests

In [103]: socket = requests.get(''http://www.zillow.com/...neighborhood')

当我查看 socket 对象里的内容时,发现里面有很多信息,我只分享一部分开头的内容:

In [106]: socket.content
Out[106]: '<?xml version="1.0" encoding="utf-8"?><RegionChildren:regionchildren
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.zillow.com/static/xsd/RegionChildren.xsd 
http://www.zillowstatic.com/vstatic/479fdf9/static/xsd/RegionChildren.xsd"  
xmlns:RegionChildren="http://www.zillow.com/static/xsd/RegionChildren.xsd"><request>
<state>wa</state><city>seattle</city><childtype>neighborhood</childtype></request>
<message><text>Request successfully processed</text><code>0</code></message><response>
<region><id>16037</id><latitude>47.559364</latitude><longitude>-122.313752</longitude>
</region><subregiontype>neighborhood</subregiontype><list><count>107</count><region>
<id>250206</id><name>Capitol Hill</name><zindex currency="USD">398000</zindex>
<url>http://www.zillow.com/local-info/WA-Seattle/Capitol-Hill/r_250206/</url>...'

我去过 xml.etree.ElementTree 的教程页面,那里展示了如何解析一个 xml 文件。根据文档的说明,这似乎是解析字符串的正确方法:

import lxml.etree.ElementTree as ET

In [107]: root = ET.fromstring(socket.content)

然而,我还是无法使用教程中提供的后续步骤来访问任何标签元素(比如 <zindex><name><region><id> 等等),例如,我得到的结果是:

In [112]: root.tag
Out[112]: '{http://www.zillow.com/static/xsd/RegionChildren.xsd}regionchildren'

In [114]: for child in root:
          print child.tag, child.attrib
.....: 
request {}
message {}
response {}

我希望能够遍历所有不同的标签元素,把它们放进一个 dictpandas.DataFrame 中,但我无法完成第一步,实际访问这些元素。

1 个回答

1

最后,我通过使用BeautifulSoup成功得到了想要的结果。具体步骤如下:

第一步:

将数据加载到一个bs4对象中,具体的做法可以参考这里的解析库说明

[In] 10: soup = bs4.BeautifulSoup(socket.content, ['lxml', 'xml'])

第二步:

仔细查看一堆xml数据,以了解它的结构。

[In] 11: f = open('pretty_xml.xml', 'w')
[In] 12: f.writelines(soup.prettify())
[In] 13: f.close()

第三步:

开始提取数据

在更仔细地查看数据后,使用bs4.findChildren()功能将每个节点提取到列表的单元格中。例如:

[In] 14: soup_list = soup.findChildren()

然后(假设tags在每个列表元素中是相同的,或者大部分相似,就像我这种情况),使用textname属性创建一个(index, values)的配对,做类似这样的事情:

[In] 15: d = {}
[In] 16: for i, element in enumerate(soup_list):
...:        index = map(lambda x: x.name, element.findChildren())
...:        vals = map(lambda x: unicode(x.text), element.findChildren())
...:        d[i] = pandas.Series(vals, index = index)

这样你就可以准备好创建一个pandas.DataFrame,并传入Seriesdict

撰写回答