将请求分页到API

时间:2010-05-05 00:34:01

标签: python api list-comprehension

我正在使用(通过urllib / urllib2)返回XML结果的API。 API总是为我的查询返回total_hit_count,但只允许我批量检索结果,比如100或1000.API规定我需要指定一个start_pos和end_pos来抵消这个,以便遍历结果。

假设urllib请求看起来像http://someservice?query='test'&start_pos=X&end_pos=Y

如果我发送带有http://someservice?query='test'&start_pos=1&end_pos=1等最低数据传输的初始“品尝者”查询,以便取回{猜测} total_hits = 1234的结果,我想制定一种方法最干净地要求批量生成1234个结果,再说100或1000或......

这是我到目前为止所提出的,它似乎有效,但我想知道你是否会以不同的方式做事或者我是否可以改进:

hits_per_page=100 # or 1000 or 200 or whatever, adjustable
total_hits = 1234 # retreived with BSoup from 'taster query'
base_url = "http://someservice?query='test'"
startdoc_positions = [n for n in range(1, total_hits, hits_per_page)]
enddoc_positions = [startdoc_position + hits_per_page - 1 for startdoc_position in startdoc_positions]
for start, end in zip(startdoc_positions, enddoc_positions):
    if end > total_hits:
        end = total_hits
    print "url to request is:\n ",
    print "%s&start_pos=%s&end_pos=%s" % (base_url, start, end)

P.S。我是StackOverflow的长期消费者,尤其是Python问题,但这是我发布的第一个问题。你们真是太棒了。

2 个答案:

答案 0 :(得分:1)

我建议使用

positions = ((n, n + hits_per_page - 1) for n in xrange(1, total_hits, hits_per_page))
for start, end in positions:

然后不用担心end是否超过hits_per_page,除非你使用的API真的关心你是否要求超出范围的东西;大多数人会优雅地处理这个案子。

P.S。查看httplib2代替urllib / urllib2组合。

答案 1 :(得分:1)

使用某种生成器来迭代列表可能会很有趣。

def getitems(base_url, per_page=100):
    content = ...urllib...
    total_hits = get_total_hits(content)
    sofar = 0
    while sofar < total_hits:
        items_from_next_query = ...urllib...
        for item in items_from_next_query:
            sofar += 1
            yield item

通常只是伪代码,但如果你需要通过简化获取项目所需的逻辑来多次执行此操作,它可能会非常有用,因为它只返回一个在python中非常自然的列表。

还可以保存相当多的重复代码。