Regarding Keyerror while using Python json module - python

would be helped if the mistake is pointed.
Here Iam trying to create a code for displaying the name of the city state and country by taking Pincode as input, Thanks in advance
import urllib, json
from urllib.request import urlopen
from tkinter import *
global pincode
root=Tk()
frame=Frame(root,width=250,height=250)
frame.grid()
class cal:
def __init__(self):
self.string=StringVar()
entry=Entry(frame,textvariable=self.string)
entry.grid(row=1,column=2,columnspan=6)
but=Button(root,text="submit",command=self.pin)
but.grid()
def pin(self):
pincode=self.string.get()
url = "https://www.whizapi.com/api/v2/util/ui/in/indian-city-by-postal-code?pin="+pincode+"&project-app-key=fnb1agfepp41y49jz6a39upx"
response = urllib.request.urlopen(url)
data = json.loads(response.read().decode('utf8'))
fi=open("neme.txt","w")
fi.write(str(data))
state=data['State']
city=data['City']
area=data['area']
name=Label(frame,text="State:"+state+"City:"+city+"area:"+area)
name.grid(row=3,column=0)
cal()
mainloop()
error being
Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1541, in __call__
return self.func(*args)
File "/home/yuvi/Documents/LiClipse Workspace/GUI/src/Pn_code.py", line 24, in pin
state=data['State']
KeyError: 'State'

Ok. Error tells you that you don't have key named "State" in you dict under data variable. So maybe there isn't also in incomming json.
If in response you get:
{"ResponseCode":0,"ResponseMessage":"OK","ResponseDateTime":‌​"9/3/2016 2:41:25 PM GMT","Data":[{"Pincode":"560103","Address":"nagar","City":"B‌​analore","State":"na‌​taka","Country":"Ind‌​ia"}]}
then you cannot get "State" by using:
data["State"]
you have to do it using:
data["Data"][0]["State"]
and the rest:
data["Data"][0]["City"]
data["Data"][0]["Country"]
Why in this way? Because you have to get nested keys, first key is "Data", using data["Data"] you recieve a list, and because it's one element list, you have to get first item of the list: data["Data"][0]. And at the end under data["Data"][0] you get dict of keys where you can find State, City, Country.

Related

Convert json query to insert a variable and re-convert it to json query

I am kinda frustrated. I copied the following Metabase query string from the network tab in the browser:
query = "{\"database\":17,\"query\":{\"source-table\":963,\"filter\":[\"and\",[\"=\",[\"field\",17580,null],\"XXXXXX_XXXXXX\"],[\"=\",[\"field\",17599,null],\"**chl-43d813dd-05a7-45b8-a5b0-8eb960289aa5**\"]],\"fields\":[[\"field\",17579,null],[\"field\",17569,null],[\"field\",17572,null],[\"field\",17586,null],[\"field\",17592,{\"temporal-unit\":\"default\"}],[\"field\",17611,null],[\"field\",17582,null],[\"field\",17597,null],[\"field\",17603,null],[\"field\",17607,null],[\"field\",17576,null],[\"field\",17588,null],[\"field\",17596,null],[\"field\",17608,null],[\"field\",17587,{\"temporal-unit\":\"default\"}],[\"field\",17578,{\"temporal-unit\":\"default\"}],[\"field\",17602,null],[\"field\",17606,null],[\"field\",17605,{\"temporal-unit\":\"default\"}],[\"field\",17601,null],[\"field\",17590,null],[\"field\",17580,null],[\"field\",17598,{\"temporal-unit\":\"default\"}],[\"field\",17577,null],[\"field\",164910,null],[\"field\",46951,null],[\"field\",46952,{\"temporal-unit\":\"default\"}]]},\"type\":\"query\",\"middleware\":{\"js-int-to-string?\":true,\"add-default-userland-constraints?\":true}}"
As the next step I wanted to convert it to a String to replace the bold reference with a variable.
The String looks like this:
query = '{"database\":17,\"query\":{\"source-table\":963,\"filter\":[\"and\",[\"=\",[\"field\",17580,null],\"XXXXXXXX-XXXXXXXX\"],[\"=\",[\"field\",17599,null],\"'+channelRef+'\"]],\"fields\":[[\"field\",17579,null],[\"field\",17569,null],[\"field\",17572,null],[\"field\",17586,null],[\"field\",17592,{\"temporal-unit\":\"default\"}],[\"field\",17611,null],[\"field\",17582,null],[\"field\",17597,null],[\"field\",17603,null],[\"field\",17607,null],[\"field\",17576,null],[\"field\",17588,null],[\"field\",17596,null],[\"field\",17608,null],[\"field\",17587,{\"temporal-unit\":\"default\"}],[\"field\",17578,{\"temporal-unit\":\"default\"}],[\"field\",17602,null],[\"field\",17606,null],[\"field\",17605,{\"temporal-unit\":\"default\"}],[\"field\",17601,null],[\"field\",17590,null],[\"field\",17580,null],[\"field\",17598,{\"temporal-unit\":\"default\"}],[\"field\",17577,null],[\"field\",164910,null],[\"field\",46951,null],[\"field\",46952,{\"temporal-unit\":\"default\"}]]},\"type\":\"query\",\"middleware\":{\"js-int-to-string?\":true,\"add-default-userland-constraints?\":true}}'
With
q = json.dumps(query)
the result looks exactly as I want to:
q = "{\"database\":17,\"query\":{\"source-table\":963,\"filter\":[\"and\",[\"=\",[\"field\",17580,null],\"XXXXXXXX-XXXXXXXX\"],[\"=\",[\"field\",17599,null],\"**chl-caabef81-f081-4532-9b6e-ac20b3d4c6cf**\"]],\"fields\":[[\"field\",17579,null],[\"field\",17569,null],[\"field\",17572,null],[\"field\",17586,null],[\"field\",17592,{\"temporal-unit\":\"default\"}],[\"field\",17611,null],[\"field\",17582,null],[\"field\",17597,null],[\"field\",17603,null],[\"field\",17607,null],[\"field\",17576,null],[\"field\",17588,null],[\"field\",17596,null],[\"field\",17608,null],[\"field\",17587,{\"temporal-unit\":\"default\"}],[\"field\",17578,{\"temporal-unit\":\"default\"}],[\"field\",17602,null],[\"field\",17606,null],[\"field\",17605,{\"temporal-unit\":\"default\"}],[\"field\",17601,null],[\"field\",17590,null],[\"field\",17580,null],[\"field\",17598,{\"temporal-unit\":\"default\"}],[\"field\",17577,null],[\"field\",164910,null],[\"field\",46951,null],[\"field\",46952,{\"temporal-unit\":\"default\"}]]},\"type\":\"query\",\"middleware\":{\"js-int-to-string?\":true,\"add-default-userland-constraints?\":true}}"
But when I use this query string to send an API request, I get the following error message(s):
{"via":[{"type":"java.lang.ClassCastException"}],"trace":[],"message":null}
Traceback (most recent call last):
File "c:\Users\XXXX\Documents\XXXXXXXX\Test.py", line 308, in
main()
File "c:\Users\XXXX\Documents\XXXXXXXX\Test.py", line 114, in main some_function(XXXX, window, selected_path)
File "c:\Users\XXXX\Documents\XXXXXXXX\Test.py", line 290, in some_function
dataframe = DataFrame(result)
File "C:\Users\XXXX\AppData\Roaming\Python\Python310\site-packages\pandas\core\frame.py", line 756, in init
raise ValueError("DataFrame constructor not properly called!")
ValueError: DataFrame constructor not properly called!
Does have anyone have an idea?
Thank you very much in advance!
You can use the built-in json module:
import json
query = "{\"database\":17,\"query\":{\"source-table\":963,\"filter\":[\"and\",[\"=\",[\"field\",17580,null],\"XXXXXX_XXXXXX\"],[\"=\",[\"field\",17599,null],\"**chl-43d813dd-05a7-45b8-a5b0-8eb960289aa5**\"]],\"fields\":[[\"field\",17579,null],[\"field\",17569,null],[\"field\",17572,null],[\"field\",17586,null],[\"field\",17592,{\"temporal-unit\":\"default\"}],[\"field\",17611,null],[\"field\",17582,null],[\"field\",17597,null],[\"field\",17603,null],[\"field\",17607,null],[\"field\",17576,null],[\"field\",17588,null],[\"field\",17596,null],[\"field\",17608,null],[\"field\",17587,{\"temporal-unit\":\"default\"}],[\"field\",17578,{\"temporal-unit\":\"default\"}],[\"field\",17602,null],[\"field\",17606,null],[\"field\",17605,{\"temporal-unit\":\"default\"}],[\"field\",17601,null],[\"field\",17590,null],[\"field\",17580,null],[\"field\",17598,{\"temporal-unit\":\"default\"}],[\"field\",17577,null],[\"field\",164910,null],[\"field\",46951,null],[\"field\",46952,{\"temporal-unit\":\"default\"}]]},\"type\":\"query\",\"middleware\":{\"js-int-to-string?\":true,\"add-default-userland-constraints?\":true}}"
my_json = json.loads(query)
# make edit's (works like a dict)
query = json.dumps(my_json)
I don't see a bold reference in your JSON string, but this is all handled with the json library:
import json
query = "YOUR QUERY STRING"
object = json.dumps(query)
# Make your changes to your dict object here
new_query = json.loads(object)

Get Value Of API Dictionary

I'm using a service with an API key and I want to print my balance.
from requests_html import HTMLSession
session = HTMLSession()
r = session.post('https://api.anycaptcha.com/getBalance', data = {'clientKey': API})
Everything works. When I do print(r.text) the following dictionary gets print:
{"errorId":0,"errorCode":"SUCCESS","balance":20.0}
However, I just want to get the value of "balance" (20.0). But I couldn't figure out how.
What I tried:
print(r.text['balance'])
# Output:
Traceback (most recent call last):
File "X/test.py", line 7, in <module>
print(r.text['balance'])
TypeError: string indices must be integers
Try this, as r.text is a string with your dict
import json
d = json.loads(r.text)
#Now you can access dict
d["balance"]

Trouble executing my class crawler

I'm completely newbie to python when it comes to scrape any web data using class. So, apology in advance for any serious mistake. I've written a script to parse the text using a tag from wikipedia web site. I tried to write the code accurately from my level best but for some reason when i execute the code it throws error. The code and the error I'm having are given below for your kind consideration.
The script:
import requests
from lxml.html import fromstring
class TextParser(object):
def __init__(self):
self.link = 'https://en.wikipedia.org/wiki/Main_Page'
self.storage = None
def fetch_url(self):
self.storage = requests.get(self.link).text
def get_text(self):
root = fromstring(self.storage)
for post in root.cssselect('a'):
print(post.text)
item = TextParser()
item.get_text()
The error:
Traceback (most recent call last):
File "C:\Users\mth\AppData\Local\Programs\Python\Python35-32\testmatch.py", line 38, in <module>
item.get_text()
File "C:\Users\mth\AppData\Local\Programs\Python\Python35-32\testmatch.py", line 33, in get_text
root = fromstring(self.storage)
File "C:\Users\mth\AppData\Local\Programs\Python\Python35-32\lib\site-packages\lxml\html\__init__.py", line 875, in fromstring
is_full_html = _looks_like_full_html_unicode(html)
TypeError: expected string or bytes-like object
You're executing the following two lines
item = TextParser()
item.get_text()
When you initialize TextParser, self.storage is equal to None. When you execute the function get_text() it's still equal to None. So that's why you get that error.
However, if you change it to the following. self.storage should get populated with a string rather than being none.
item = TextParser()
item.fetch_url()
item.get_text()
If you want to call the function get_text without calling fetch_url you can do it this way.
def get_text(self):
self.fetch_url()
root = fromstring(self.storage)
for post in root.cssselect('a'):
print(post.text)

Poloniex Api Trouble

So I'm accessing the poloniex API with python and this is my code:
from poloniex import Poloniex
import krakenex
import threading
import pprint
import urllib.request
import json
####POLONIEX####
#FUNCTIONS
polo = Poloniex()
def BTC_USDT_LAST_POLONIEX():
polo = Poloniex()
threading.Timer(1.0, BTC_USDT_LAST_POLONIEX).start() # called every minute
print("BTC Last Price = " + (polo('returnTicker')['USDT_BTC']['last']))
def POLONIEX_ASSET_LIST():
pprint.pprint(sorted(list(polo('returnTicker'))))
Everything is working so far and I want to avoid using urllib as its a pain to turn a http request into a list. I'm trying to access the order book but get the following error:
>>> polo('returnOrderBook')
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
polo('returnOrderBook')
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/poloniex/retry.py", line 15, in wrapped
return function(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/poloniex/__init__.py", line 183, in __call__
return self.parseJson(ret.text)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/poloniex/__init__.py", line 197, in parseJson
raise PoloniexError(jsonout['error'])
poloniex.PoloniexError: Please specify a currency pair.
I've tried specifying the currency pair but have no idea how to plug it in.
Rewrite your code and use requests module instead of urllib:
import requests
ret = requests.get('http://poloniex.com/public?command=returnOrderBook&currencyPair=BTC_BCN').json()
print ret
>>> {u'bids': [[u'0.00000034', 20629605.566027], [u'0.00000033', 43382683.465305], [u'0.00000032', 70007976.087993], [u'0.00000031', 49571221.248027], [u'0.00000030', 77520227.415484], [u'0.00000029', 46037827.046996], [u'0.00000028', 26267440.401662], [u'0.00000027', 22511987.85933], [u'0.00000026', 18885378.040015], [u'0.00000025', 13313109.292994], [u'0.00000024', 6243527.5236432], [u'0.00000023', 7504850.7832509], [u'0.00000022', 8443683.7997507], [u'0.00000021', 8996262.9826951], [u'0.00000020', 24601532.006268], [u'0.00000019', 26853346.478659], [u'0.00000018', 6027262.24889 etc....

Feedparser Python Error : KeyError : 'title'

I have seen a lot of KeyCount Errors online but none of them quite match the troubles that I'm having. I am using feed parser to try and create a one run application that accesses all the URLs in a text file and outputs all the entries in each URL. When I run this code :
import feedparser as f
with open('addresses.rtf', 'r') as addresses:
for line in addresses:
d = f.parse(line)
print d["feed"]["title"]
print ""
print d.feed.subtitle
print ""
for post in d.entries:
print post.title
print post.link
print ""
I get this error message :
Traceback (most recent call last):
File "/Users/Josh/Desktop/Feed Parser Python Project/init.py", line 7, in <module>
print d["feed"]["title"]
File "build/bdist.macosx-10.6-intel/egg/feedparser.py", line 375, in __getitem__
return dict.__getitem__(self, key)
KeyError: 'title'
My text file is just a .rtf file that has a URL on each line (3 lines).
If someone could give us a hand please let me know and if you need any extra info please don't hesitate to ask. Any help is welcome. Thank you!
It's hard to tell exactly what is wrong here, but in the general case, any KeyError is because the data you are trying to access is not exactly what you expected. It's best to throw your assumptions out the window and take a close look at the actual data that your code is working with.
For debugging, I would recommend taking a close look at what happens before the error. What is the value of line as you read the file? Is it correct? What is the value of d? Did the call to f.parse(line) result in a valid object?

Categories