如何迭代地解析和保存作为一个字符串出现的 XML 响应?
How to iteratively parse and save XML responses that come in as one string?
我正在打API个电话,就是取ID,每次调用代表10000个ID,我一次只能取10000个。 我的目标是将每个 XML 调用保存到一个列表中,以自动计算平台中有多少人。
我 运行 遇到的问题有两个。
每次调用都是响应对象,当我附加到列表时响应对象作为单个字符串附加,所以我无法计算 ID 总数
要获取下一个 10000 个 ID 列表,我必须使用另一个 API 调用来获取有关每个 ID 的信息,并检索一条名为网站 ID 的信息并使用它来调用#1
中 API 的下一个 10000
我也想防止列表中出现任何重复的 ID,但我觉得这是最简单的任务。
这是我的代码:
1
- 呼叫配置文件 ID(每次呼叫带回 10000)
将响应对象 'r' 添加到列表 'lst'
导入请求
导入 xml.etree.ElementTree 等
将 pandas 导入为 pd
从 lxml 导入 etree
导入时间
lst = []
xml = '''
<?xml version="1.0" encoding="utf-8" ?>
<YourMembership>
<Version>2.25</Version>
<ApiKey>*****</ApiKey>
<CallID>009</CallID>
<SaPasscode>*****</SaPasscode>
<Call Method="Sa.People.All.GetIDs">
<Timestamp></Timestamp>
<WebsiteID></WebsiteID>
<Groups>
<Code></Code>
<Name></Name>
</Groups>
</Call>
</YourMembership>
'''
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post('https://api.yourmembership.com', data=xml, headers=headers)
lst.append(r.text)
API调用结果
<YourMembership_Response>
<Sa.People.All.GetIDs>
<People>
<ID>1234567</ID>
</People>
</Sa.People.All.GetIDs>
</YourMembership_Response>
2
我在#1 中从 API 调用中获取最后一个 ID 并手动输入该值
进入下面 'ID' 标签中的 API 调用。
xml_2 = '''
<?xml version="1.0" encoding="utf-8" ?>
<YourMembership>
<Version>2.25</Version>
<ApiKey>****</ApiKey>
<CallID>001</CallID>
<SaPasscode>****</SaPasscode>
<Call Method="Sa.People.Profile.Get">
<ID>1234567</ID>
</Call>
</YourMembership>
'''
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r_2 = requests.post('https://api.yourmembership.com', data=xml_2, headers=headers)
print (r_2.text)
API调用结果:
<YourMembership_Response>
<ErrCode>0</ErrCode>
<ExtendedErrorInfo></ExtendedErrorInfo>
<Sa.People.Profile.Get>
<ID>1234567</ID>
<WebsiteID>7654321</WebsiteID>
</YourMembership_Response>
我获取网站 ID 并在 API 从 #1(示例)调用并填充网站 ID 标记,获取下一个 10000,直到不再返回结果:
xml = '''
<?xml version="1.0" encoding="utf-8" ?>
<YourMembership>
<Version>2.25</Version>
<ApiKey>*****</ApiKey>
<CallID>009</CallID>
<SaPasscode>*****</SaPasscode>
<Call Method="Sa.People.All.GetIDs">
<Timestamp></Timestamp>
<WebsiteID>7654321</WebsiteID>
<Groups>
<Code></Code>
<Name></Name>
</Groups>
</Call>
</YourMembership>
'''
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post('https://api.yourmembership.com', data=xml, headers=headers)
lst.append(r.text)
希望我的问题有道理,并提前谢谢你。
我曾经开始构建一些东西来爬过 API,这听起来与您想要实现的目标相似。在我的情况下,一个不同之处是响应是 json 而不是 xml,但应该没什么大不了的。
在您的问题中看不到您确实在使用 xml 解析器的强大功能的证据。看看 docs。例如,您可以像这样轻松地从要附加到列表的那些项目中获取 ID 号:
xml_sample = """
<YourMembership_Response>
<Sa.People.All.GetIDs>
<People>
<ID>1234567</ID>
</People>
</Sa.People.All.GetIDs>
</YourMembership_Response>
"""
import xml.etree.ElementTree as ET
root = ET.fromstring(xml_sample)
print (root[0][0][0].text)
>>> '1234567'
实验一下,将它循环应用到列表中的每个元素,或者你可能会很幸运,整个响应对象将在不需要查看所有内容的情况下进行解析。
您现在应该能够以编程方式在下一段代码中输入该数字,而无需手动输入。
您的 XML 下一部分的网站 ID 似乎有一行无效 <Sa.People.Profile.Get>
一旦我将其取出,它就可以被解析:
xml_sample2 = """
<YourMembership_Response>
<ErrCode>0</ErrCode>
<ExtendedErrorInfo></ExtendedErrorInfo>
<ID>1234567</ID>
<WebsiteID>7654321</WebsiteID>
</YourMembership_Response>
"""
root2 = ET.fromstring(xml_sample2)
print (root2[3].text)
>>> '7654321'
所以不确定那里是否总是有无效行,或者如果您忘记粘贴某些内容,可以在应用 xtree 之前用正则表达式或其他内容删除该行。
建议您尝试 sqlite 来帮助您处理 1 和 2 之间的互动。我认为最多有 50 万行,否则您需要连接到适当的数据库。它将文件保存在您的目录中,并且与适当的数据库相比,设置时间和麻烦更少。也许,用 sqlite 测试这个概念,并在必要时迁移到 postgresql。
您可以将此已解析 xml 中您喜欢的用户 ID、网站 ID 中的任何有用元素存储到 table 中,然后再次将其拉出以用于不同的部分。如果您需要 pandas.read_sql and pandas.DataFrame.to_sql,从 sqlite 到 pandas 数据帧来回切换也不难 希望这有帮助..
我正在打API个电话,就是取ID,每次调用代表10000个ID,我一次只能取10000个。 我的目标是将每个 XML 调用保存到一个列表中,以自动计算平台中有多少人。
我 运行 遇到的问题有两个。
每次调用都是响应对象,当我附加到列表时响应对象作为单个字符串附加,所以我无法计算 ID 总数
要获取下一个 10000 个 ID 列表,我必须使用另一个 API 调用来获取有关每个 ID 的信息,并检索一条名为网站 ID 的信息并使用它来调用#1
中 API 的下一个 10000
我也想防止列表中出现任何重复的 ID,但我觉得这是最简单的任务。
这是我的代码:
1
- 呼叫配置文件 ID(每次呼叫带回 10000)
将响应对象 'r' 添加到列表 'lst'
导入请求 导入 xml.etree.ElementTree 等 将 pandas 导入为 pd 从 lxml 导入 etree 导入时间
lst = [] xml = ''' <?xml version="1.0" encoding="utf-8" ?> <YourMembership> <Version>2.25</Version> <ApiKey>*****</ApiKey> <CallID>009</CallID> <SaPasscode>*****</SaPasscode> <Call Method="Sa.People.All.GetIDs"> <Timestamp></Timestamp> <WebsiteID></WebsiteID> <Groups> <Code></Code> <Name></Name> </Groups> </Call> </YourMembership> ''' headers = {'Content-Type': 'application/x-www-form-urlencoded'} r = requests.post('https://api.yourmembership.com', data=xml, headers=headers) lst.append(r.text)
API调用结果
<YourMembership_Response>
<Sa.People.All.GetIDs>
<People>
<ID>1234567</ID>
</People>
</Sa.People.All.GetIDs>
</YourMembership_Response>
2
我在#1 中从 API 调用中获取最后一个 ID 并手动输入该值 进入下面 'ID' 标签中的 API 调用。
xml_2 = ''' <?xml version="1.0" encoding="utf-8" ?> <YourMembership> <Version>2.25</Version> <ApiKey>****</ApiKey> <CallID>001</CallID> <SaPasscode>****</SaPasscode> <Call Method="Sa.People.Profile.Get"> <ID>1234567</ID> </Call> </YourMembership> ''' headers = {'Content-Type': 'application/x-www-form-urlencoded'} r_2 = requests.post('https://api.yourmembership.com', data=xml_2, headers=headers) print (r_2.text)
API调用结果:
<YourMembership_Response>
<ErrCode>0</ErrCode>
<ExtendedErrorInfo></ExtendedErrorInfo>
<Sa.People.Profile.Get>
<ID>1234567</ID>
<WebsiteID>7654321</WebsiteID>
</YourMembership_Response>
我获取网站 ID 并在 API 从 #1(示例)调用并填充网站 ID 标记,获取下一个 10000,直到不再返回结果:
xml = '''
<?xml version="1.0" encoding="utf-8" ?>
<YourMembership>
<Version>2.25</Version>
<ApiKey>*****</ApiKey>
<CallID>009</CallID>
<SaPasscode>*****</SaPasscode>
<Call Method="Sa.People.All.GetIDs">
<Timestamp></Timestamp>
<WebsiteID>7654321</WebsiteID>
<Groups>
<Code></Code>
<Name></Name>
</Groups>
</Call>
</YourMembership>
'''
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post('https://api.yourmembership.com', data=xml, headers=headers)
lst.append(r.text)
希望我的问题有道理,并提前谢谢你。
我曾经开始构建一些东西来爬过 API,这听起来与您想要实现的目标相似。在我的情况下,一个不同之处是响应是 json 而不是 xml,但应该没什么大不了的。
在您的问题中看不到您确实在使用 xml 解析器的强大功能的证据。看看 docs。例如,您可以像这样轻松地从要附加到列表的那些项目中获取 ID 号:
xml_sample = """
<YourMembership_Response>
<Sa.People.All.GetIDs>
<People>
<ID>1234567</ID>
</People>
</Sa.People.All.GetIDs>
</YourMembership_Response>
"""
import xml.etree.ElementTree as ET
root = ET.fromstring(xml_sample)
print (root[0][0][0].text)
>>> '1234567'
实验一下,将它循环应用到列表中的每个元素,或者你可能会很幸运,整个响应对象将在不需要查看所有内容的情况下进行解析。
您现在应该能够以编程方式在下一段代码中输入该数字,而无需手动输入。
您的 XML 下一部分的网站 ID 似乎有一行无效 <Sa.People.Profile.Get>
一旦我将其取出,它就可以被解析:
xml_sample2 = """
<YourMembership_Response>
<ErrCode>0</ErrCode>
<ExtendedErrorInfo></ExtendedErrorInfo>
<ID>1234567</ID>
<WebsiteID>7654321</WebsiteID>
</YourMembership_Response>
"""
root2 = ET.fromstring(xml_sample2)
print (root2[3].text)
>>> '7654321'
所以不确定那里是否总是有无效行,或者如果您忘记粘贴某些内容,可以在应用 xtree 之前用正则表达式或其他内容删除该行。
建议您尝试 sqlite 来帮助您处理 1 和 2 之间的互动。我认为最多有 50 万行,否则您需要连接到适当的数据库。它将文件保存在您的目录中,并且与适当的数据库相比,设置时间和麻烦更少。也许,用 sqlite 测试这个概念,并在必要时迁移到 postgresql。
您可以将此已解析 xml 中您喜欢的用户 ID、网站 ID 中的任何有用元素存储到 table 中,然后再次将其拉出以用于不同的部分。如果您需要 pandas.read_sql and pandas.DataFrame.to_sql,从 sqlite 到 pandas 数据帧来回切换也不难 希望这有帮助..