Accessing data from a json array in python - python

One of my responses looks like,
{
"password": [
"Ensure that this field has atleast 5 and atmost 50 characters"
]
}
And I am trying to fetch the string inside password.How I can get it.
Below is the code which I am trying
key = json.loads(response['password'])
print(key[0]),
But it says 'string indices must be integers, not str'

The error message is correct.
key = json.loads(response['password'])
print(key[0]),
The format of json is string. You need to convert the string of a json object to python dict before you can access it.
i.e.: loads(string) before info[key]
key = json.loads(response)['password']
print(key[0])

Usually the json will be a string and you will try and deserialise it into a object graph (which in python are typically are made up of maps and arrays).
so assuming your response is actually a string (eg that was retrieved from a HTTP request/endpoint) then you deserialise it with json.loads (the function is basically load from string), then you've got a map with a 'password' key, that is an array, so grab the first element from it.
import json
resp = '{ "password": [ "Ensure that this field has atleast 5 and atmost 50 characters" ] }'
print json.loads(resp)['password'][0]

Related

Can't Get Python To Parse JSON From Site

I'm trying to get my Python script to parse some data (the price) from a specific json file on a site, but I am unable to get it working.
It can extract the whole page fine, but it cannot extract certain data just by itself.
Here is the JSON I am trying to extract data from:
[{
"id": 1696146,
"name": "Genos",
"photo_url": "https://hobbydb-production.s3.amazonaws.com/processed_uploads/collectible_photo/collectible_photo/image/324461/1556082253-24867-7610/Genos_Vinyl_Art_Toys_60fb245b-1af9-4ad1-a5a2-c90d3e8291a6_medium.jpg",
"preorder": false,
"price": "$40.00",
"price_after_discount": "$40.00",
"seller_username": "BatmanPajamas",
"url": "https://www.hobbydb.com/marketplaces/2/cart/1696146"
}]
Here is the code I have got that allows me to get the entire json:
import urllib.request, json
withurllib.request.urlopen("https://www.hobbydb.com/api/collectibles/for_sale_search?limit=5&original_site_id=10748&market_id=2") as url:
data = json.loads(url.read().decode())
print(data)
I have tried various pieces of code, but everytime I get:
TypeError: list indices must be integers or slices, not str
Any ideas how I can parse the price from this JSON?
The outer brackets ([]) indicate the response returns a list of items. So, you need to loop over the indices of the list, then you can access what you're trying to access. Here's how I do it with requests
import requests
resp = requests.get("https://www.hobbydb.com/api/collectibles/for_sale_search?limit=5&original_site_id=10748&market_id=2")
#requests has built-in support for json, so no need to import json module
for product in resp.json():
print(product["price"])
To iterate over json array:
for item in data:
for keys in item.keys():
print(item[keys])
to display only price
for item in data:
print(item['price'])
I think the problem you are having is because this JSON object starts with an array (which will be a list once we load it as a Python object). First, you need to use the json library from the standard lib. Then, you have to access the object using the list index, then the dict keys.
Try this:
import urllib.request, json
with urllib.request.urlopen("https://www.hobbydb.com/api/collectibles/for_sale_search?limit=5&original_site_id=10748&market_id=2") as url:
data = json.loads(url.read().decode())
print(data)
toy = data[0]
price = toy['price']
Also, keep in mind that the with keyword creates a context for parsing the JSON data, so once your script moves on to code outside of this context, you won't be able to access your price variable any longer, so you might want to assign or set that value to to another variable created outside of that context.

Insert JSON object as an argument in Python (Escape the Quote)

I am trying to pass a JSON object as an argument to a python2 script, it works but the final json data has a single quote (') enclosing the object.
Below is my code
import json
import sys
print sys.argv[1]
data_str = sys.argv[1].decode('string-escape')
print data_str
# The above print's fine with no single quotes
json_data= {
"server-name": "servername",
"transaction-id": "transaction_id",
"user-id": "user_id",
"change-id": "change_id",
"consumer-name": "consumer_name",
"platform": "platform",
"cookbooks": [
{
"cookbook-name": "cookbook_name",
"cookbook-version": "cookbook_version",
"recipe-name": "receipie_name",
"attributes": {
}
}
]
}
json_data["cookbooks"][0]["attributes"] = data_str.decode('string-escape')
print json_data["cookbooks"]
Execution
C:\Python26\python.exe saver.py "{apple:newf,mango:newb}"
{apple:newf,mango:newb}
{apple:newf,mango:newb}
[{'cookbook-name': 'cookbook_name', 'cookbook-version': 'cookbook_version', 'recipe-name': 'receipie_name', 'attributes': '{apple:newf,mango:newb}'}]
From the above output the final json_data contains quotes in the attribute value
'attributes': '{apple:newf,mango:newb}' which is causing error in my GET call.
How to escape this single quote. ?
Forgive me if I'm wrong but I think you've got mixed up with converting the argument string type and decoding a json string.
The single quotes in your result means that the entire value is a string.
Firstly the argument you are passing in on the command line isn't valid JSON.
Try starting your program like this:
C:\Python26\python.exe saver.py "{\"apple\":\"newf\",\"mango\":\"newb\"}"
Then later decode the JSON contained in the string like this:
json_data["cookbooks"][0]["attributes"] = json.loads(data_str)
i.e. json.loads and not str.decode
at this point the variable "json_data" isn't holding JSON it's holding a dictionary
You would then have to encode the entire of json_data to pass it in some raw form of http GET unless you have some API doing it for you. Something like
encoded_json_data = json.dumps(json_data)
If you want to work with JSON then use the json module built in to your Python. Don't try to fudge the issue by treating it as Python string data when it isn't.
import json
then:
json_data["cookbooks"][0]["attributes"] = json.loads(sys.argv[1])
Then if you want to output your Python data structure as json:
print(json.dumps(json_data["cookbook"]))

How to make Chatfuel read JSON file stored in Zapier?

In my Chatfuel block I collect a {{user input}} and POST a JSON in a Zapier webhook. So far so good. After that, my local Pyhon reads this JSON from Zapier storage successfully
url = 'https://store.zapier.com/api/records?secret=password'
response = urllib.request.urlopen(url).read().decode('utf-8')
data = json.loads(response)
and analyze it generating another JSON as output:
json0={
"messages": [
{"text": analysis_output}]
}
Then Python3 posts this JSON in a GET webhook in Zapier:
import requests
r = requests.post('https://hooks.zapier.com/hooks/catch/2843360/8sx1xl/', json=json0)
r.status_code
Zapier Webhook successfully gets the JSON and sends it to Storage.
Key-Value pairs are set and then Chatfuel tries to read from storage:
GET https://store.zapier.com/api/records?secret=password2
But the JSON structure obtained is wrong, what was verified with this code:
url = 'https://store.zapier.com/api/records?secret=password2'
response = urllib.request.urlopen(url).read().decode('utf-8')
data = json.loads(response)
data
that returns:
{'messages': "text: Didn't know I could order several items"}
when the right one for Chatfuel to work should be:
{'messages': [{"text: Didn't know I could order several items"}]}
That is, there are two mais problems:
1) There is a missing " { [ " in the JSON
2) The JSON is appending new information to the existing one, instead of generating a brand new JSON, what cause the JSON to have 5 different parts.
I am looking for possible solutions for this issue.
David here, from the Zapier Platform team.
First off, you don't need quotes around your keys, we take care of that for you. Currently, your json will look like:
{ "'messages'": { "'text'": "<DATA FROM STEP 1>" } }
So the first change is to take out those.
Next, if you want to store an array, use the Push Value Onto List action instead. It takes a top-level key and stores your values in a key in that object called list. Given the following setup:
The resulting structure in JSON is
{ "demo": {"list": [ "5" ]} }
It seems like you want to store an extra level down; an array of json objects:
[ { "text": "this is text" } ]
That's not supported out of the box, as all list items are stored as strings. You can store json strings though, and parse them back into an object when you need to access them like an object!
Does that answer your question?

FInding certain data from key in json output python

I am trying to get a key code from a json output.
But i cannot seem to get it, I get errors left and right.
Here is my code.
import requests
import time
import threading
import json
def ThreadRequest():
scrape_url = "https://pastebin.com/api_scraping.php?limit=1"
json_data = requests.get(scrape_url)
python_obj = json.loads(json_data.text)
print python_obj["key"]
ThreadRequest()
I either get
TypeError: list indices must be integers, not str
ValueError: No JSON object could be decoded
TypeError: expected string or buffer
I have tried many ways, different ways, even parsing by using .split() function.
I cannot seem to get the understanding of how to parse in json.
Here is the API output
[
{
"scrape_url": "https://pastebin.com/api_scrape_item.php?i=rkFbtGSj",
"full_url": "https://pastebin.com/rkFbtGSj",
"date": "1516914453",
"key": "rkFbtGSj",
"size": "3031",
"expire": "0",
"title": "",
"syntax": "text",
"user": ""
}
]
The first thing is that the requests module has a built-in JSON parsing method so just use that rather than trying to use the raw text response. Change:
python_obj = json.loads(json_data.text)
To:
python_obj = json_data.json()
Second, the data that you're interested in is in a dictionary. However, that dictionary is contained within a list. Take the 0th index of that list to get access to the dictionary, then access that by key (in this case, also called "key").
my_value = python_obj[0]['key']

TypeError: list indices must be integers or slices, not str while parsing JSON

I am trying to print out at least one key value from the returned Json, as following this basic tutorial
response=None
booking_source = 'sourceBusinessName'
api_request ='http://api.com'
r = requests.get(api_request)
while response is None:
response = r.content.decode('utf-8')
data = json.loads(response)
print (data[booking_source])
return HttpResponse(data[booking_source])
But it returns TypeError: list indices must be integers or slices, not str
probably because I am giving an string instead of an integer to data when printing, but then what I am doing wrong here ?
With requests you can skip the decoding of the response and parsing it as JSON by using the response's json method:
r = requests.get(api_request)
data = r.json()
print data # so you can see what you're dealing with
At this point I suggest dumping out the value of data so that you can see the structure of the JSON data. Probably it is a JSON array (converted to a Python list) and you simply need to take the first element of that array before accessing the dictionary, but it's difficult to tell without seeing the actual data. You might like to add a sample of the data to your question.
Your JSON is an array at the top level, but you're trying to address it as if it were:
{
"sourceBusinessName": {
...
},
...
}

Categories

Resources