python: получение данных пакета npm из конечной точки couchdb - PullRequest
0 голосов
/ 03 июля 2019

Я хочу получить метаданные пакета npm. Я нашел эту конечную точку, которая дает мне все необходимые метаданные.

Я сделал следующий скрипт для получения этих данных. Мой план состоит в том, чтобы выбрать некоторые конкретные ключи и добавить эти данные в некоторую базу данных (я также могу сохранить их в файле json, но данные огромны). Я сделал следующий скрипт для извлечения данных:

import requests
import json
import sys

db = 'https://replicate.npmjs.com';

r = requests.get('https://replicate.npmjs.com/_all_docs', headers={"include_docs" : "true"})

for line in r.iter_lines():
    # filter out keep-alive new lines
    if line:
        print(line)
        decoded_line = line.decode('utf-8')
        print(json.loads(decoded_line))

Обратите внимание, я даже не включаю all-docs, но он зацикливается. Я думаю, что это потому, что данные огромны.

Взгляд на заголовок вывода из - https://replicate.npmjs.com/_all_docs

дает мне следующий вывод:

{"total_rows":1017703,"offset":0,"rows":[
{"id":"0","key":"0","value":{"rev":"1-5fbff37e48e1dd03ce6e7ffd17b98998"}},
{"id":"0-","key":"0-","value":{"rev":"1-420c8f16ec6584c7387b19ef401765a4"}},
{"id":"0----","key":"0----","value":{"rev":"1-55f4221814913f0e8f861b1aa42b02e4"}},
{"id":"0-1-project","key":"0-1-project","value":{"rev":"1-3cc19950252463c69a5e717d9f8f0f39"}},
{"id":"0-100","key":"0-100","value":{"rev":"1-c4f41a37883e1289f469d5de2a7b505a"}},
{"id":"0-24","key":"0-24","value":{"rev":"1-e595ec3444bc1039f10c062dd86912a2"}},
{"id":"0-60","key":"0-60","value":{"rev":"2-32c17752acfe363fa1be7dbd38212b0a"}},
{"id":"0-9","key":"0-9","value":{"rev":"1-898c1d89f7064e58f052ff492e94c753"}},
{"id":"0-_-0","key":"0-_-0","value":{"rev":"1-d47c142e9460c815c19c4ed3355d648d"}},
{"id":"0.","key":"0.","value":{"rev":"1-11c33605f2e3fd88b5416106fcdbb435"}},
{"id":"0.0","key":"0.0","value":{"rev":"1-5e541d4358c255cbcdba501f45a66e82"}},
{"id":"0.0.1","key":"0.0.1","value":{"rev":"1-ce856c27d0e16438a5849a97f8e9671d"}},
{"id":"0.0.168","key":"0.0.168","value":{"rev":"1-96ab3047e57ca1573405d0c89dd7f3f2"}},
{"id":"0.0.250","key":"0.0.250","value":{"rev":"1-c07ad0ffb7e2dc51bfeae2838b8d8bd6"}}, 

Обратите внимание, что все документы начинаются со второй строки (то есть все документы являются частью значений ключа "lines"). Теперь мой вопрос заключается в том, как получить только значения ключа «строки» (то есть все документы). Я нашел этот репозиторий для аналогичной цели, но не могу использовать / конвертировать его, так как я абсолютный новичок в JavaScript.

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Если среди аргументов get() нет stream=True, то все данные будут загружены в память до того, как цикл даже начнется.

Тогда естьпроблема в том, что по крайней мере сами строки не являются допустимыми JSON.Для этого вам понадобится инкрементальный синтаксический анализатор JSON, например ijson.ijson, в свою очередь, хочет подобный файлу объект, который нелегко получить из requests.Response, поэтому я буду использовать urllib из стандартной библиотеки Python здесь:

#!/usr/bin/env python3
from urllib.request import urlopen

import ijson


def main():
    with urlopen('https://replicate.npmjs.com/_all_docs') as json_file:
        for row in ijson.items(json_file, 'rows.item'):
            print(row)


if __name__ == '__main__':
    main()
0 голосов
/ 03 июля 2019

Есть ли причина, по которой вы не расшифровываете json до итерации по строкам?

Можете ли вы попробовать это:

import requests
import json
import sys

db = 'https://replicate.npmjs.com';

r = requests.get('https://replicate.npmjs.com/_all_docs', headers={"include_docs" : "true"})

decoded_r = r.decode('utf-8')
data = json.loads(decoded_r)

for row in data.rows:
    print(row.key)
...