2010-05-05 5 views
2

Я потребляю (через urllib/urllib2) API, который возвращает результаты XML. API всегда возвращает total_hit_count для моего запроса, но только позволяет мне получать результаты в пакетах, скажем, 100 или 1000. API предусматривает, что мне нужно указать start_pos и end_pos для его смещения, чтобы пройти через результаты.Запросы разбивки на страницы API

Скажем, запрос 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) 

ps Я долгое время пользовался StackOverflow, особенно вопросами Python, но это мой первый вопрос. Вы, ребята, просто великолепны.

ответ

1

я предлагаю использовать

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

, а затем не беспокоиться о том, превышает ли endhits_per_page если API вы используете действительно не заботится, запрашиваете ли вы что-то из диапазона; большинство из них обработает этот случай изящно.

P.S. Проверьте httplib2 в качестве замены для urllib/urllib2 комбо.

+0

Кусочек жареного золота, спасибо. Я сделал свою шляпу. Теперь, как я «практически» избавил свою шляпу от вашего превосходного вклада? – craigs

+0

Upvote был хорошим началом ;-) –

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 

В основном просто псевдо код, но он может оказаться весьма полезным, если вам нужно сделать это много раз за счет упрощения логики требуется, чтобы получить детали, как это только возвращает список, который вполне естественно в питона.

Сохраните еще один дубликат кода.

Смежные вопросы