I'm kinda new JSON and python and i wish to use the keys and values of JSON to compare it.
I'm getting the JSON from a webpage using requests lib.
Recently, I've done this:
import requests;
URL = 'https://.../update.php';
PARAMS = { 'platform':'0', 'authcode':'code', 'app':'60' };
request = requests.get( url=URL, params=PARAMS );
data = request.json( );
I used this loop to get the keys and values from that json:
for key, value in data.items( ):
print( key, value );
it return JSON part like this:
rescode 0
desc success
config {
"app":"14",
"os":"2",
"version":"6458",
"lang":"zh-CN",
"minimum":"5",
"versionName":"3.16.0-6458",
"md5":"",
"explain":"",
"DiffUpddate":[ ]
}
But in Firefox using pretty print i get different result look like this:
{
"rescode": 0,
"desc": "success",
"config": "{
\n\t\"app\":\"14\",
\n\t\"os\":\"2\",
\n\t\"version\":\"6458\",
\n\t\"lang\":\"zh-CN\",
\n\t\"minimum\":\"5\",
\n\t\"versionName\":\"3.16.0-6458\",
\n\t\"md5\":\"\",
\n\t\"explain\":\"\",
\n\t\"DiffUpddate\":[\n\t\t\n\t]\n
}"
}
What I'm planing to do is:
if data['config']['version'] == '6458':
print('TRUE!');
But everytime i get this error:
TypeError: string indices must be integers
You need to parse the config
json.loads(data['config'])['version']
Or edit the PHP to return an associative array rather than a string for the config object
Related
I Need to Exact Value from Json response
how can I get a specific json value python ???
this is my Json string
I need to extract Id value
"window.__store__ ="{
"listingReducer":{
"selectedListing":{
"id":2234588,
"has_video":0,
"refresh":1625551240,
"category":6,
"ketchen":1,
"lift":1,
"livings":1,
"maid":null,
"meter_price":null,
"playground":null,
"location":{
"lat":26.378031,
"lng":50.124866
},
"views":6075,
},3
}
}
this my python code :
import json
from selenium import webdriver
jsonScript =driver.find_element_by_xpath("/html/body/script[6]")
jsonText = jsonScript.get_attribute('innerHTML')
.
.
.
json_str = json.dumps(jsonText)
resp = json.loads(json_str)
#print (resp)
print(resp[0]['listingReducer']['selectedListing']['id'])
.
.
.
And this is the Error
TypeError: string indices must be integers
Your string is not in JSON format.
I have managed to convert it into JSON by removing irrelevant content (that doesn't follow JSON encoding).
This code will get you the ID from the JSON string.
import json
s = '''
{
"listingReducer":{
"selectedListing":{
"id":2234588,
"has_video":0,
"refresh":1625551240,
"category":6,
"ketchen":1,
"lift":1,
"livings":1,
"maid":null,
"meter_price":null,
"playground":null,
"location":{
"lat":26.378031,
"lng":50.124866
},
"views":6075
}
}
}
'''
d = json.loads(s)
print(f"ID: {d['listingReducer']['selectedListing']['id']}")
Output:
ID: 2234588
I am able to parse json ressponse when there are multiple "nodes" of what I am looking for, but when only one node is returned by the API, I am getting the message "string indices must be integers".
Here is my code in which I am pass in the dictionary after converting it from a string using json.loads():
import requests, requests.auth
import json
import os
def parseSchedule(dict):
i = 0
for item in dict['reservations']['reservation']:
print(item['event_start_dt'])
i += 1
I've simplified the json response to show that this works:
{
"reservations": {
"reservation": [{
"event_start_dt": "2019-11-27T12:40:00-08:00"
}, {
"event_start_dt": "2019-11-27T16:10:00-08:00"
}]
}
}
While this throws the error "string indices must be integers":
{
"reservations": {
"reservation": {
"event_start_dt": "2019-11-26T08:30:00-08:00"
}
}
}
I have researched the .items() in which I attempt the key and value but have been unsuccessful thus far.
You can do it with something like this:
#If it is a list:
if str(type(dict["reservations"]["reservation"])) == "<class 'list'>":
for i in range(len(dict["reservations"]["reservation"])):
print(dict["reservations"]["reservation"][i]["event_start_dt"])
else: #If it is not a list
print(dict['reservations']['reservation']['event_start_dt'])
I've recently started learning how to use python and i'm having some trouble with a graphQL api call.
I'm trying to set up a loop to grab all the information using pagination, and my first request is working just fine.
values = """
{"query" : "{organizations(ids:) {pipes {id name phases {id name cards_count cards(first:30){pageInfo{endCursor hasNextPage} edges {node {id title current_phase{name} assignees {name} due_date createdAt finished_at fields{name value filled_at updated_at} } } } } }}}"}
"""
but the second call using the end cursor as a variable isn't working for me. I assume that it's because i'm not understanding how to properly escape the string of the variable. But for the life of me I'm unable to understand how it should be done.
Here's what I've got for it so far...
values = """
{"query" : "{phase(id: """ + phaseID+ """ ){id name cards_count cards(first:30, after:"""\" + pointer + "\"""){pageInfo{endCursor hasNextPage} edges {node {id title assignees {name} due_date createdAt finished_at fields{name value datetime_value updated_at phase_field { id label } } } } } } }"}
"""
the second one as it loops just returns a 400 bad request.
Any help would be greatly appreciated.
As a general rule you should avoid building up queries using string manipulation like this.
In the GraphQL query itself, GraphQL allows variables that can be placeholders in the query for values you will plug in later. You need to declare the variables at the top of the query, and then can reference them anywhere inside the query. The query itself, without the JSON wrapper, would look something like
query = """
query MoreCards($phase: ID!, $cursor: String) {
phase(id: $phase) {
id, name, cards_count
cards(first: 30, after: $cursor) {
... CardConnectionData
}
}
}
"""
To actually supply the variable values, they get passed as an ordinary dictionary
variables = {
"phase": phaseID,
"cursor": pointer
}
The actual request body is a straightforward JSON structure. You can construct this as a dictionary too:
body = {
"query": query,
"variables": variables
}
Now you can use the standard json module to format it to a string
print(json.dumps(body))
or pass it along to something like the requests package that can directly accept the object and encode it for you.
I had a similar situation where I had to aggregate data through paginating from a GraphQL endpoint. Trying the above solution didn't work for me that well.
to start my header config for graphql was like this:
headers = {
"Authorization":f"Bearer {token}",
"Content-Type":"application/graphql"
}
for my query string, I used the triple quote with a variable placeholder:
user_query =
"""
{
user(
limit:100,
page:$page,
sort:[{field:"email",order:"ASC"}]
){
list{
email,
count
}
}
"""
Basically, I had my loop here for the pages:
for page in range(1, 9):
formatted_query = user_query.replace("$page",f'{page}')
response = requests.post(api_url, data=formatted_query,
headers=headers)
status_code, json = response.status_code, response.json()
I'm trying to access certain fields of information in JSON dict. My code is set up as the following:
Views.py
def viewIssues(request):
r = requests.get(bucket_url)
issue_payload = r.json()
issue = json.loads(str(issue_payload))
context = {
"issue_title": issue['issues']['title'],
"issue_content": issue['issues']['content'],
"title": "View Issues",
}
return render(request, "view_issues.html", context)
str(issue_payload) gives me this:
{
'search':None,
'count':1,
'filter':{
},
'issues':[
{
'priority':'major',
'comment_count':0,
'utc_created_on':'2016-11-12 01:48:16+00:00',
'utc_last_updated':'2016-11-12 01:48:16+00:00',
'status':'new',
'title':'example issue',
'reported_by':{
'is_staff':False,
'display_name':'display name',
'is_team':False,
'resource_uri':'/1.0/users/username',
'avatar':'https://bitbucket.org/account/username/avatar/32/?ts=1479493904',
'first_name':'firstname',
'username':'username',
'last_name':'lastname'
},
'is_spam':False,
'content':'blah blah',
'metadata':{
'milestone':None,
'component':None,
'version':None,
'kind':'bug'
},
'local_id':1,
'created_on':'2016-11-12T02:48:16.052',
'resource_uri':'/1.0/repositories/username/supportal2016test/issues/1',
'follower_count':1
}
]
}
However when I try to use the json.loads and indices ['issues']['title'] and ['issues']['title'] I get an error:
JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
I'm wondering if it's because the converted payload has quotations on each field (i.e. 'issues'). Any help would be much appreciated.
The .json() call already parses the JSON result and returns a Python structure in this case a dictionary. Then your call
issue = json.loads(str(issue_payload))
forces the dictionary into a string and tries to parse it again. But the dictionary string representation contains ' around strings and not " as required in JSON.
To cut the long story short: issue_payload is what you want already.
I'm using urllib.request.urlopen to get a JSON response that looks like this:
{
"batchcomplete": "",
"query": {
"pages": {
"76972": {
"pageid": 76972,
"ns": 0,
"title": "Title",
"thumbnail": {
"original": "https://linktofile.com"
}
}
}
}
The relevant code to get the response:
response = urllib.request.urlopen("https://example.com?title="+object.title)
data = response.read()
encoding = response.info().get_content_charset('utf-8')
json_object = json.loads(data.decode(encoding))
I'm trying to retrieve the value of "original", but I'm having a hard time getting there.
I can do print(json_object['query']['pages'] but once I do print(json_object['query']['pages'][0] I run into a KeyError: 0.
How would I be able to, with python retrieve the value of original?
Do this instead:
my_content = json_object['query']['pages']['76972']['thumbnail']['original']
The reason is, you need to mention index as [0] only when you have list as the object. But in your case, every item is of dict type. You need to specify key instead of index
If number is dynamic, you may do:
page_content = json_object['query']['pages']
for content in page_content.values():
my_content = content['thumbnail']['original']
where my_content is the required information.
Doing [0] is looking for that key - which doesn't exist. Assuming you don't always know what the key of the page is, Try this:
pages = json_object['query']['pages']
for key, value in pages.items(): # this is python3
original = value['thumbnail']['original']
Otherwise you can simply grab it by the key if you do know (what appears to be) the pageid:
json_object['query']['pages']['76972']['thumbnail']['original']
You can iterate over keys:
for page_no in json_object['query']['pages']:
page_data = json_object['query']['pages'][page_no]