Alright, I am fairly new to python and I am making a console witch will allow multiple features, one of those is to grab a page source and either print it on the page, or if they have another arg then name the file of that arg... The first arg would be the website url to grab the source from.
My imports are:
import os, urllib.request
This is my code:
def grab(command, args, argslist):
if args == "":
print("The " + command + " command wan't used correctly type help " + command + " for help...")
if args != "":
print("This may take a second...")
try:
argslistcheck = argslist[0]
if argslistcheck[0:7] != "http://":
argslist[0] = "http://" + argslist[0]
with urllib.request.urlopen(argslist[0]) as url:
source = url.read()
source = str(source, "utf-8")
except IndexError:
print("Couln't connect")
source = ""
try:
filesourcename = argslist[1] + ".txt"
filesourceopen = open(filesourcename, "w")
filesourceopen.write(source)
filesourceopen.close()
print("You can find the file save in " + os.getcwd() + " named " + argslist[1] + ".txt.")
except IndexError:
print(source)
Now while I will be ok with improving my code right now I'm focusing on the main point. Right now it works, I will improve the code later on, the only problem is that if the user inputs a fake website or a website page that doesn't exist then it returns lot's of errors. Yet if I change:
except IndexError:
print("Coulnd't connect")
source = ""
to just:
except:
print("Couldn't connect")
source = ""
Then it always says Couldn't connect...
Any help? I didn't put the rest of my code because I didn't think it would be useful, if you need it I can put it all.
The reason I titled this hide error is because it still works for some reason it just says that it was unable to connect, if the user types a second argument then it will save the source to the file he named.
try:
argslistcheck = argslist[0]
if argslistcheck[0:4] != "http://":
argslist[0] = "http://" + argslist[0]
with urllib.request.urlopen(argslist[0]) as url:
source = url.read()
source = str(source, "utf-8")
except IndexError:
print("Couln't connect")
source = ""
In that code block, the only thing that can raise an IndexError exception is the argslist[0]. This will happen if there is no element within that list. This is very likely not your problem.
Now if an invalid address is entered, urlopen will fail. But it will not raise an IndexError but rather an urllib.error.URLError or the more specialized urllib.error.HTTPError.
If you just write except IndexError you will only catch that error, but not the exception raised by the urlopen. If you want to catch those as well, you have to add another except case:
except IndexError:
print('Argument is missing')
except urllib.error.URLError:
print('Could not connect to the URL.')
The alternative is to just catch any exception by just not specifying any (this is what you did in your last code). Note that this is usually not recommended as it will hide any exceptions that occur which you might not have expected to ever happen; i.e. it will hide bugs. So if you know that there are only a few possible exceptions, just catch those and handle them explicitely.
Related
I want to continue even after the assert statement fails. Instead of saying "File not found" I would like to ignore it and continue my program. I am unable to figure out the syntax.
Overview of the script and problem faced :
This script is used for downloading pdf from urls which were written in a txt file. I had used assert to stop the program if the file wasn't found. It worked fine when all the urls in that txt file were working. The problem arose when there was a link which was dead and I didn't want the program to stop but instead continue to next link.
assert os.path.exists(of), "File not found at, " +str(of)
Program snippet :
for line in url_file:
stripped_line = line.split(',')
list_of_urls.append(stripped_line[2]+stripped_line[1])
driver.get(stripped_line[2]+stripped_line[1])
time.sleep(2)
of = download_dir+"/"+stripped_line[3]+".pdf"
fn = download_dir+"/"+stripped_line[0]+".pdf"
try:
assert os.path.exists(of), "File not found at, " +str(of)
except AssertionError:
pass
move(of, fn)
fns.append(stripped_line[0])
ofns.append(stripped_line[3])
status_file.write(stripped_line[0]+",File Downloaded\n")
url_file.close()
status_file.close()
driver.quit()
If you really want to use assert you can just us a try: except: block to catch the error thrown if the assertion is not True
try:
assert os.path.exists(of), "File not found at, " +str(of)
except AssertionError:
pass
However if your goal is just to print an error message if the file does not exist you can do:
if not os.path.exists(of):
print("File not found at, " +str(of))
if os.path.exists(of):
move(of, fn)
fns.append(stripped_line[0])
ofns.append(stripped_line[3])
Code:
def ScanNetwork():
nmScan = nmap.PortScanner()
s = nmScan.scan("192.168.1.1/24", '0-4444', arguments="-O")
for host in nmScan.all_hosts():
if nmScan[host].state() == "up":
print("Host : %s (%s)" % (host, nmScan[host].hostname()))
try:
print("Version: " + s['scan'][host]['osmatch'][0]['name'] + "\nType: " + s['scan'][host]['osmatch'][0]['osclass'][0]['type'])
except:
print("An Error occured while scanning this host!\nNo extra info was collected!")
continue
for proto in nmScan[host].all_protocols():
print("---------------------------")
print("\nProtocol : %s" % proto)
lport = nmScan[host][proto].keys()
lport = sorted(lport)
for port in lport:
print("\nport: " + f'{port}' + "\tstate: " + nmScan[host][proto][port]['state'])
print("---------------------------\n")
print("\n\nScan Completed!")
ScanNetwork()
Sometimes an exception occurs when the nmap fails to identify the Version or the Os running in a host. (It's a KeyError exception)
The part which is supposed to handle that exception is this:
try:
print("Version: " + s['scan'][host]['osmatch'][0]['name'] + "\nType: " + s['scan'][host]['osmatch'][0]['osclass'][0]['type'])
except:
print("An Error occured while scanning this host!\nNo extra info was collected!")
continue
I of course assume that there's nothing wrong with nmap's output and I've again made a huge beginner mistake and that's the reason my code is getting stuck..
Notes:
I've left the script running over night incase it returned some useful info but nothing happened!
Please do not tell me that I need to quit using the nmap module and turn to nmap3
Having tired you with all the above, does anyone know a way to still handle that exception without the code getting stuck?
You have forgotten to add the type of the exception to excpect while running the code inside the try-except block.
This should fix it:
try:
print("Version: " + s['scan'][host]['osmatch'][0]['name'] + "\n" + "Type: " + s['scan'][host]['osmatch'][0]['osclass'][0]['type'])
except KeyError:
print("An Error occured while scanning this host!\nNo extra info was collected!")
continue
In case you want to catch any possible exception that could occur (and yes custom ones included) then you should use the following code:
try:
<some critical code with possible exceptions to catch>
except Exception:
print("An exception occured")
Hello I am trying to make 'try' only work under one condition:
try:
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
I do not want the above code to work if the kwarg nodownload is True.
So I have tried the following:
try:
if nodownload:
print "Not downloading file!"
time.sleep(6)
raise
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
The above always downloads no matter if the --nd argument is passed in the command line. The below always skips the file rather the argument is passed or not.
if not nodownload:
print "Not downloading file!"
time.sleep(6)
raise
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
No download is input at the command line:
parser.add_argument('--nodownload', dest='nodownload', action='store_true',
help='This doesn't work for some reason')
You can use raise to cause an exception when you need to, thus making the try fail.
As others have mentioned, one can raise an exception.
Apart from using predefined exceptions, you may also use your own:
class BadFriend(Exception):
pass
class VirtualFriend(Exception):
pass
class DeadFriend(Exception):
pass
try:
name = raw_input("Tell me name of your friend: ")
if name in ["Elvis"]:
raise DeadFriend()
if name in ["Drunkie", "Monkey"]:
raise BadFriend()
if name in ["ET"]:
raise VirtualFriend()
print("It is nice, you have such a good friend.")
except BadFriend:
print("Better avoid bad friends.")
except VirtualFriend:
print("Whend did you shake hands with him last time?")
except DeadFriend:
print("I am very sorry to tell you, that...")
You can even pass some data via raised exception, but be careful not to abuse it too far (if
standard structures are working, use simpler ones).
I am a relative python newbie and I am getting confused with how to properly handle exceptions. Apologies for the dumb question.
In my main() I iterate through a list of dates and for each date I call a function, which downloads a csv file from a public web server. I want to properly catch exceptions for obvious reasons but especially because I do not know when the files of interest will be available for download. My program will execute as part of a cron job and will attempt to download these files every 3 hours if available.
What I want is to download the first file in the list of dates and if that results in a 404 then the program shouldn't proceed to the next file because the assumption is if the oldest date in the list is not available then none of the others that come after it will be available either.
I have the following python pseudo code. I have try/except blocks inside the function that attempts to download the files but if an exception occurred inside the function how do I properly handle it in the main() so I can make decisions whether to proceed to the next date or not. The reason why I created a function to perform the download is because I want to re-use that code later on in the same main() block for other file types.
def main():
...
...
# datelist is a list of date objects
for date in datelist:
download_file(date)
def download_file(date):
date_string = str(date.year) + str(date.strftime('%m')) + str(date.strftime('%d'))
request = HTTP_WEB_PREFIX+ date_string + FILE_SUFFIX
try:
response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
print "HTTPError = " + str(e)
except urllib2.URLError, e:
print "URLError = " + str(e)
except httplib.HTTPException, e:
print "HTTPException = " + str(e)
except IOError:
print "IOError = " + str(e)
except Exception:
import traceback
print "Generic exception: " + traceback.format_exc()
else:
print "No problem downloading %s - continue..." % (response)
try:
with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f:
except IOError:
print "IOError = " + str(e)
else:
f.write(response.read())
f.close()
The key concept here is, if you can fix the problem, you should trap the exception; if you can't, it's the caller's problem to deal with. In this case, the downloader can't fix things if the file isn't there, so it should bubble up its exceptions to the caller; the caller should know to stop the loop if there's an exception.
So let's move all the exception handling out of the function into the loop, and fix it so it craps out if there's a failure downloading the file, as the spec requires:
for date in datelist:
date_string = str(date.year) +
str(date.strftime('%m')) +
str(date.strftime('%d'))
try:
download_file(date_string)
except:
e = sys.exc_info()[0]
print ( "Error downloading for date %s: %s" % (date_string, e) )
break
download_file should now, unless you want to put in retries or something like that, simply not trap the exceptions at all. Since you've decoded the date as you like in the caller, that code can come out of download_file as well, giving the much simpler
def download_file(date_string):
request = HTTP_WEB_PREFIX + date_string + FILE_SUFFIX
response = urllib2.urlopen(request)
print "No problem downloading %s - continue..." % (response)
with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f:
f.write(response.read())
f.close()
I would suggest that the print statement is superfluous, but that if you really want it, using logger is a more flexible way forward, as that will allow you to turn it on or off as you prefer later by changing a config file instead of the code.
From my understanding of your question... you should just insert code into the except blocks that you want to execute when you encounter the particular exception. You don't have to print out the encountered error, you can do whatever you feel is necessary when it is raised... provide a popup box with information/options or otherwise direct your program to the next step. Your else section should isolate that portion, so it will only execute if none of your exceptions are raised.
I have some Python code with error handling in place but for some reason the code still seems to be unable to handle this particular error:
raise GQueryError("No corresponding geographic location could be found for the specified location, possibly because the address is relatively new, or because it may be incorrect.")
geopy.geocoders.google.GQueryError: No corresponding geographic location could be found for the specified location, possibly because the address is relatively new, or because it may be incorrect.
This is the source:
import csv
from geopy import geocoders
import time
g = geocoders.Google()
spamReader = csv.reader(open('locations.csv', 'rb'), delimiter='\t', quotechar='|')
f = open("output.txt",'w')
for row in spamReader:
a = ', '.join(row)
#exactly_one = False
time.sleep(1)
try:
place, (lat, lng) = g.geocode(a)
except ValueError:
#print("Error: geocode failed on input %s with message %s"%(a, error_message))
continue
b = str(place) + "," + str(lat) + "," + str(lng) + "\n"
print b
f.write(b)
Have I not included enough error handling? I was under the impression that "except ValueError" would handle this situation but I must be wrong on that.
Thanks in advance for any help out!
P.S. I pulled this out of the code but I don't know what it really means yet:
def check_status_code(self,status_code):
if status_code == 400:
raise GeocoderResultError("Bad request (Server returned status 400)")
elif status_code == 500:
raise GeocoderResultError("Unkown error (Server returned status 500)")
elif status_code == 601:
raise GQueryError("An empty lookup was performed")
elif status_code == 602:
raise GQueryError("No corresponding geographic location could be found for the specified location, possibly because the address is relatively new, or because it may be incorrect.")
elif status_code == 603:
raise GQueryError("The geocode for the given location could be returned due to legal or contractual reasons")
elif status_code == 610:
raise GBadKeyError("The api_key is either invalid or does not match the domain for which it was given.")
elif status_code == 620:
raise GTooManyQueriesError("The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time.")
Right now the try/except is only catching ValueErrors. To catch GQueryError as well, replace the except ValueError: line with:
except (ValueError, GQueryError):
Or if GQueryError isn't in your namespace, you may need something like this:
except (ValueError, geocoders.google.GQueryError):
Or to catch ValueError and all the errors listed in check_status_code:
except (ValueError, GQueryError, GeocoderResultError,
GBadKeyError, GTooManyQueriesError):
(Again, add geocoders.google. or whatever the error location is to the front of all the geopy errors if they're not in your namespace.)
Or, if you just want to catch all possible exceptions, you could simply do:
except:
but this is generally bad practice, because it'll also catch things like a syntax error in your place, (lat, lng) = g.geocode(a) line, which you don't want caught, so it's better to examine the geopy code to find all the possible exceptions it could be throwing that you want to catch. Hopefully all of those are listed in that bit of code you found.