Разбиение запросов на API - PullRequest
2 голосов
/ 05 мая 2010

Я использую (через urllib / urllib2) API, который возвращает результаты XML. 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 ]

1 голос
/ 05 мая 2010

Может быть интересно использовать какой-то генератор для этого сценария, чтобы перебрать список.

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.

Кроме того, вы сэкономите немного дубликата кода.

1 голос
/ 05 мая 2010

Я бы предложил использовать

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 комбо.

...