我正在进行API调用,即检索ID,每次调用代表10000个ID,我一次只能检索10000个。 我的目标是将每个XML调用保存到一个列表中,以自动计算平台中有多少人。
我遇到的问题有两个问题。
每个调用都作为响应对象,当我附加到列表时,响应对象追加为单个字符串,因此我无法计算ID的总数
要获取下一个10000个ID列表,我必须使用另一个API调用来获取有关每个ID的信息,并检索一条名为网站ID的信息,并使用该信息从#中调用下一个10000 1
我还想阻止列表中的任何重复ID,但我觉得这是最简单的任务。
这是我的代码:
将响应对象'r'追加到列表'lst'
中导入请求 将xml.etree.ElementTree导入为et 将pandas导入为pd 来自lxml import 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>
我从#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,并在填写了网站ID标签的#1(示例)的API调用中重新运行此代码,获取下一个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)
希望我的问题有道理,并提前感谢你。
答案 0 :(得分:1)
我曾经开始构建一些东西来爬行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'
实验,将它应用于循环中列表中的每个元素,或者您将很幸运,整个响应对象将解析而无需查看事物。
您现在应该能够以编程方式而不是在下一位代码中手动输入该数字。
您的网站ID下一部分的XML似乎在其中包含无效行<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 之间的互动。我认为它可以达到五十万行,否则你需要挂钩到一个合适的数据库。它将文件保存在您的目录中,并且与正确的数据库相比,设置时间和使用时间更少。也许,用sqlite测试这个概念,如果需要,可以迁移到postgresql。
您可以将您喜欢用户ID,网站ID的解析后的xml中的任何有用元素存储到表中,然后再将其拉出以用于其他部分。如果您需要使用pandas.read_sql和pandas.DataFrame.to_sql并希望这有帮助,也很难从sqlite到pandas数据帧来回转换..