I am trying to update my configuration.ini file's, [Financial Times: Financial-Services] section's last_entry_id with the following string: http://www.ft.com/cms/s/0/46858280-36f4-11e6-a780-b48ed7b6126f.html?ftcamp=published_links%2Frss%2Fcompanies_financial-services%2Ffeed%2F%2Fproduct
Here is my configuration.ini file's corresponding section:
[Financial Times: Financial-Services]
feed_updated_on =
feed_updated_field = ['updated']
link = http://www.ft.com/rss/companies/financial-services
last_entry_id =
id_field = link
But in my code, when I try the following line:
id_of_first_link = 'http://www.ft.com/cms/s/0/46858280-36f4-11e6-a780-b48ed7b6126f.html?ftcamp=published_links%2Frss%2Fcompanies_financial-services%2Ffeed%2F%2Fproduct'
feed_link['last_entry_id'] = id_of_first_link
I get the error:
ValueError: invalid interpolation syntax in 'http://www.ft.com/cms/s/0/46858280-36f4-11e6-a780-b48ed7b6126f.html?ftcamp=published_links%2Frss%2Fcompanies_financial-services%2Ffeed%2F%2Fproduct' at position 90
feed_link is the reference name of [Financial Times: Financial-Services] in the configuration.ini file. How to resolve this issue?
The exception refers to an invalid interpolation syntax
This is because in Python you're able to interpolate strings with the following syntax:
mystring = "Hello, my name is %s"
print(mystring % 'StackOverflow')
I think that at some point in configparser, it must be using this syntax, and therefore is getting a string that it cannot handle correctly.
There are a few ways to get around this. You can either use the str.replace() that I showed you, which escapes % by using a double percent sign %%...
Or you can try to provide a raw string instead, with this syntax:
id_of_first_link = r'http://www.ft.com/cms/s/0/46858280-36f4-11e6-a780-b48ed7b6126f.html?ftcamp=published_links%2Frss%2Fcompanies_financial-services%2Ffeed%2F%2Fproduct'
Note the r before the starting single-quote.
Raw strings will also allow you to type strings like r'C:\Windows\system32' without the backslashes escaping characters accidently.
Related
Python: I want to get an image as an input from the user as a raw string! I used input() to get the path. Giving it as a raw string makes the program work, I can do it by appending r before the path, but Image.open(' ') also takes r as a string and producing an error. Can someone help me in resolving this problem.
path=input('Please enter the path of the image')
im=Image.open(path)
get an error as no file found
if i give..
y='r'+path
im=Image.open(y)
then the error is
OSError: [Errno 22] Invalid argument: 'rC:\\Users\\User\\Desktop\.......jpeg'
I am new to python, so please help me if there is any method by which I can solve this issue.
raw strings are for a programmer's convenience; you don't have to have your users enter raw strings as normal input.
See the end of this post for the solution to your problem. Because you said you are new to Python, I have decided to give a detailed answer here.
Why raw strings?
Normal strings assign special meaning to the \ (backslash) character. This is fine as \ can be escaped by using \\ (two backslashes) to represent a single backslash.
However, this can sometimes become ugly.
Consider, for example, a path: C:\Users\Abhishek\test.txt. To represent this as a normal string in Python, all \ must be escaped:
string = 'C:\\Users\\Abhishek\\test.txt'
You can avoid this by using raw strings. Raw strings don't treat \ specially.
string = r'C:\Users\Abhishek\test.txt'
That's it. This is the only use of raw strings, viz., convenience.
Solution
If you are using Python 2, use raw_input instead of input. If you are using Python 3 (as you should be) input is fine. Don't try to input the path as a raw string.
I have this String
S="191042709832779540946_1513246254239&source=%7B%22query%22%3A%7B%22match_all%22%3A%7B%7D%7D%2C%22from%22%3A%s%2C%22size%22%3A20000%2C%22facets%22%3A%7B%22_type%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22_type%22%2C%22size%22%3A102%2C%22order%22%3A%22reverse_term%22%7D%7D%2C%22index.classification.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.classification.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.has_seal.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.has_seal.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.license.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.license.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.publisher.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.publisher.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.language.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.language.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%7D%7D&_=1513246254241"
In the above string I have to substitute an Integer in some place. For that I used %s.
s = S % 100
Then I got the following error.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: unsupported format character 'B' (0x42) at index 51
NOTE: You can search (ctrl+f) for %s to see it in the above string. I tried to highlight it. But it was not possible.
How can I substitute a value in the above string. Thanks in advance.
You need to avoid using %s for the substitution, and instead use {} with Python's format() function as follows:
text = "191042709832779540946_1513246254239&source=%7B%22query%22%3A%7B%22match_all%22%3A%7B%7D%7D%2C%22from%22%3A{}%2C%22size%22%3A20000%2C%22facets%22%3A%7B%22_type%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22_type%22%2C%22size%22%3A102%2C%22order%22%3A%22reverse_term%22%7D%7D%2C%22index.classification.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.classification.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.has_seal.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.has_seal.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.license.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.license.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.publisher.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.publisher.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.language.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.language.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%7D%7D&_=1513246254241"
replace = 100
print text.format(replace)
This would give you:
191042709832779540946_1513246254239&source=%7B%22query%22%3A%7B%22match_all%22%3A%7B%7D%7D%2C%22from%22%3A100%2C%22size%22%3A20000%2C%22facets%22%3A%7B%22_type%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22_type%22%2C%22size%22%3A102%2C%22order%22%3A%22reverse_term%22%7D%7D%2C%22index.classification.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.classification.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.has_seal.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.has_seal.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.license.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.license.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.publisher.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.publisher.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%2C%22index.language.exact%22%3A%7B%22terms%22%3A%7B%22field%22%3A%22index.language.exact%22%2C%22size%22%3A110%2C%22order%22%3A%22count%22%7D%7D%7D%7D&_=1513246254241
This is necessary as your text already has other % characters and this will not be compatible with the %s substitution. By using this method, replace could also be a string if needed.
You can simply use replace
newS = S.replace("%s", "100")
Here the usual syntax with % is difficult to apply because in your string there are a lot of '%x' that python do not take literally (it thinks they are placeholders for some other replacements, but in your caes there are just escaped HTML characters)
I am using python requests to connect to a website. I am passing some strings to get data about them.
The problem is some string contains slash /, so when they are passed in url, I got a ValueError.
this is my url:
https://api.flipkart.net/sellers/skus/%s/listings % string
when string is passed (string that does not contain slash), I get:
https://api.flipkart.net/sellers/skus/A35-Charry-228_39/listings
It returns a valid response. but when i pass string which contains a slash:
string = "L20-ORG/BLUE-109(38)"
I get url like:
https://api.flipkart.net/sellers/skus/L20-ORG/BLUE-109(38)/listings
Which throws the error.
how to solve this?
Raw string literals in Python
string = r"L20-ORG/BLUE-109(38)"
You could find more info here and here.
urllib.quote_plus is your friend. As urllib is a module from the standard library, you just have to import it with import urllib.
If you want to be conservative, just use it with default value:
string = urllib.quote_plus("L20-ORG/BLUE-109(38)")
gives 'L20-ORG%2FBLUE-109%2838%29'
If you know that some characters are harmless for your use case (say parentheses):
string = urllib.quote_plus("L20-ORG/BLUE-109(38)", '()')
gives 'L20-ORG%2FBLUE-109(38)'
I'm pretty new to python and programming in general. I'm currently working on a script to scrape stock quotes from Google finance. Here is my code:
import urllib.request as ur
import re
def getquote(symbol):
base_url = 'http://finance.google.com/finance?q='
content = ur.urlopen(base_url + symbol).read()
m = re.search(b'id="ref_(.*?)">(.*?)<', content)
if m:
quote = m.group(2)
else:
quote = 'no quote available for: ' + symbol
return quote
which returns:
b'655.65'
(655.65 is the current price of Google stock which is the symbol I passed in)
My question is: is there a way for me to either scrub the return so I just get the price without the b or the quotations? Ideally I'd like to have it returned as a float but if need be I can have it return as a string and convert it to a float when I need it later.
I've referenced these other posts:
How to create a stock quote fetching app in python
Python TypeError on regex
How to convert between bytes and strings in Python 3?
Convert bytes to a Python string
Perhaps I've missed something in one of those but I believe I've tried everything I could find and it is still returning in the format shown above.
SOLVED
The problem I was having wasn't displaying a string without quotes, it was that I had a value set to a byte literal that needed to first be converted to a string literal and then to a float. I had tried this but I tried this outside of the if statement (noob move). the solution was as v1k45 suggested:
add a line in the if statement
quote = float(quote.decode('utf-8'))
to decode it and convert to float.
thanks for the help!
Add a line in the if condition:
quote = float(quote.decode('utf-8'))
You have to decode the bytes to unicode to return a proper string. Use float() to convert it into a float.
I'm having an issue figuring out how to properly input base64 data into a string format in python 2.7. Here's the relevant code snippet:
fileExec = open(fileLocation, 'w+')
fileExec.write(base64.b64decode('%s')) %(encodedFile) # encodedFile is base64 data of a file grabbed earlier in the script.
fileExec.close()
os.startfile(fileLocation)
As silly as it may seem, I am required to use the string formatting in this case, due to the what this script is actually doing, but when I launch the script, I receive the following error:
TypeError: Incorrect Padding
I'm not quite sure what I need to do to the '%s' to get this to work. Any suggestions? Am I using the wrong string format?
Update: Here's a better idea of what I'm ultimately trying to accomplish:
encodedFile = randomString() # generates a random string for the variable name to be written
fileExec = randomString()
... snip ...
writtenScript += "\t%s.write(base64.b64decode(%s))\n" %(fileExec, encodedFile) # where writtenScript is the contents of the .py file that we are dynamically generating
I must use string formatting because the variable name will not always be the same in the python file we making.
That error usually means your base64 string may not be encoded properly. But here it is just a side-effect of a logic error in your code.
What you have done is basically this:
a = base64.b64decode('%s')
b = fileExec.write(a)
c = b % (encodedFile)
So you are attempting to decode the literal string "%s", which fails.
It should look more like this:
fileExec.write(base64.b64decode(encodedFile))
[edit: using redundant string format... pls don't do this in real code]
fileExec.write(base64.b64decode("%s" % encodedFile))
Your updated question shows that the b64decode part is inside of a string, not in your code. That is a significant difference. The code in your string is also missing a set of inner quotes around the second format:
writtenScript += "\t%s.write(base64.b64decode('%s'))\n" % (fileExec, encodedFile)
(notice the single quotes...)