Good day. I work with VK API, there is a JSON string with which I need to pull out some values.

In PHP, this was done easily:

$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 } 

Trying to do by analogy on Python:

 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) 

I get the error:

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

The maximum I can do is get all the available fields:

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

How do I write to the variable a = data['response']['attachment']['photo']['src_big'] ?

Thanks in advance!

    2 answers 2

    The php code contains a foreach loop that you forgot in Python code:

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

    Thanks for the answer! Did as you said, eventually got a TypeError error: 'int' object is not subscriptable

    TypeError indicates that item is an integer in this case — php code must also break in this case: $item['attachment'] returns NULL for types that are not supported for indexing .

    In Python, it is not customary to ignore errors silently, unless they are clearly suppressed. From The Zen of Python :

    Errors should never pass silently.
    Unless explicitly silenced.

    You can use try / except to ignore TypeError or use it in the body of a loop:

     if isinstance(item, int): continue 

    The code goes to the next loop if item is a number.

    If print(data['response']) shows or the vk api documentation for your request guarantees some specific structure of the returned data, then you can write the code more precisely.

    For example, if you are only interested in the second element from the returned list, then you do not need to use the for-cycle:

     item = data['response'][1] photo = item['attachment']['photo']['src_big'] print(photo) 
    • Thanks for the answer! Did as you said, eventually got a TypeError error TypeError: 'int' object is not subscriptable - Vladimir V.
    • @ VladimirV. The code does the same as php. Type each item and compare it with what you get in php. If there is too much data, then use item, item ['attachment'], item ['attachment'] ['photo'] successively until you see the difference. - jfs
    • That's just the point, as soon as I start writing item ['attachment'], item ['attachment'] ['photo'] I get the same TypeError error TypeError: 'int' object is not subscriptable If I leave just photo = item then the list is displayed simply json - Vladimir V.
    • @ VladimirV. What line leads to an error? item [a] or item [a] [b]? Show item. What output php in this case gives? What is the difference? By the way, print (item) does not print json (it displays a textual representation of Python objects, which may be similar, but different — for example, Python uses single quotes in such cases). - jfs
    • Whatever item [a], item [a] [b], item [a] [b] [c] I didn’t try to output, the error will be cursed at the same Item TypeError: 'int' object is not subscriptable Yes, when displaying just an item, a python displays a textual representation of a python object with single quotes. in PHP when I request item['attachment']['photo']['src_big'] I get a simple link http:\\site.ru\img.jpg - Vladimir V.

    I answer my own question. At random, I managed to achieve the desired result. The truth is, I don’t fully understand why in the for loop I managed to output the values ​​via vapi and not through vphoto as it should be according to logic.

    But in general, the code is working, it may be useful in the same way as I, for beginners in 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']) 

    PS you could of course use the vk pip install vk library, but without it everything works

    • Perfection is meaningless for-loop here to use, if you only vapi [0] ... type. I updated the answer - jfs