Получение Json и Python (на примере PHP

501
15 января 2017, 18:42

Доброго времени суток. Работаю с VK API, имеется JSON строка с которой мне нужно вытащить кое какие значения.

В PHP это делалось легко:

  $url = file_get_contents("https://api.vk.com/method/groups.search?q=bla-bla&access_token=<TOKEN>");
    $data = json_decode($url,true);  
        foreach ($data['response'] as $item) {
    $photo = $item['attachment']['photo']['src_big'];
    echo $photo
    }

Пытаюсь сделать по аналогии на Питоне:

import urllib.request as urllib2
import json
url = "https://api.vk.com/method/wall.get?owner_id=-bla-bla&"
response = urllib2.urlopen(url)
data = json.loads(response.read())
a = data['response']['attachment']['photo']['src_big']
print(a)

Получаю ошибку:

a = data['response']['attachment']['photo']['src_big']
TypeError: list indices must be integers or slices, not str

Максимум что я могу сделать, так это получить все доступные поля:

.......
a = data['response']
for b in a:
    print(b)

Как мне записать в переменную a = data['response']['attachment']['photo']['src_big'] ?

Заранее благодарен!

Answer 1

php код содержит foreach цикл, который вы забыли в Питон коде:

with urlopen(url) as response:
    data = json.load(response)
    for item in data['response']:
        photo = item['attachment']['photo']['src_big']
        print(photo)

Спасибо за ответ! Сделал так как вы сказали, в итоге получил ошибку TypeError: 'int' object is not subscriptable

TypeError показывает, что item это целое число в этом случае—php код также обязан ломаться в этом случае: $item['attachment'] возвращает NULL для типов, которые индексацию не придерживают.

В Питоне не принято игнорировать ошибки молча, если они явно не подавлены. Из The Zen of Python:

Errors should never pass silently.
Unless explicitly silenced.

Вы можете использовать try/except, чтобы проигнорировать TypeError или использовать в теле цикла:

if isinstance(item, int):
    continue

Код переходит на следующий цикл если item число.

Если print(data['response']) показывает или документация vk api для вашего запроса гарантирует какую-то определённую структуру возвращаемых данных, то можно точнее код написать.

К примеру, если вас интересует только второй элемент из возвращаемого списка, то не нужно for-цикл использовать:

item = data['response'][1]
photo = item['attachment']['photo']['src_big']
print(photo)
Answer 2

Отвечаю сам на свой же вопрос. Методом тыка у меня получилось добиться желаемого результата. Правда не до конца понимаю почему в цикле for у меня получилось вывести значения через vapi а не через vphoto как должно быть по логике.

Но в целом код рабочий, может быть пригодится таким же как и я, новичкам в Python.

from urllib.request import urlopen
import json
url = "https://api.vk.com/method/wall.get?owner_id=-bla-bla"
data = urlopen(url)
decoded_response = data.read().decode()
final_data = json.loads(decoded_response)
vapi = final_data['response'][1:]
for vphoto in vapi:
    print(vapi[0]["attachment"]['photo']['src_big'])

P.S. можно конечно было использовать библиотеку vk pip install vk, но и без нее все работает

READ ALSO
Помогите с логикой в базе данных в phpMyAdmin

Помогите с логикой в базе данных в phpMyAdmin

Есть у таблицы student столбец id_family-это статус семьи(например:полная, неполная) Есть еще одна таблица family с столбцом name где записаны знач-(Полная,Неполная)...

254
1-C Bitrix не устанавливается Тайтл для вкладки

1-C Bitrix не устанавливается Тайтл для вкладки

Как установить тайтл на вкладке? перебробывал уже все способы не хочет ставиться и все : require($_SERVER["DOCUMENT_ROOT"]"/bitrix/header

331
Не получается совладать с session()

Не получается совладать с session()

Как можно написать logout выход с сессии в этом же коде?Чтобы при нажатии на картинку выходило из сессии типа unset и destroy (не используя подключения...

378
RestAPI в yii фрэймворк

RestAPI в yii фрэймворк

Решил изучить php фрэймворк - YiiСтолкнулся с проблемой минимальной настройки restAPI

348