I'm working with Twint(a Twitter scraper) but somehow there is a problem that I can't fix. I wonder if there is a way that when an error occurs, wait 1 min and re-execute this?
My code is like this:
import twint
geos = ["40.74566208501717, -73.99137569478954", "35.68802408270403, 139.76489869554837", "31.22521968438549, 121.51655148017774"]
for geo in geos:
print(str(geo)+','+'10km')
c = twint.Config()
c.Limit = 20
c.Geo = str(geo)+','+'10km'
twint.run.Search(c)
Sometimes,twint.run.Search(c) can't function correctly.So, once there is an error, is there a way to only execute this loop again but not re-executing the whole loop?
Would anyone help me? Any idea would be really helpful. Thank you much!
If you want to simply pretend the error didn't happen, you could do:
try:
twint.run.Search(c)
except WhateverExceptionType:
pass
(replace WhateverExceptionType with the actual type of error you're seeing)
If when there's an error you wanted to have the whole program wait for a minute before continuing the loop, put that in the except:
import time
...
try:
twint.run.Search(c)
except WhateverExceptionType:
time.sleep(60)
If you want it to re-execute that specific search after waiting (rather than continuing with the next loop iteration), put that in the except. Note that if code within an except raises, then it will raise out of the except and stop your program.
try:
twint.run.Search(c)
except WhateverExceptionType:
time.sleep(60)
twint.run.Search(c)
You could do something like this to try the search again after 60 sec and with say maximum 10 retries:
import time
for geo in geos:
print(str(geo)+','+'10km')
c = twint.Config()
c.Limit = 20
c.Geo = str(geo)+','+'10km'
success=False
retries = 0
while not success and retries <= 10:
try:
twint.run.Search(c)
success=True
except twint.token.RefreshTokenException:
time.sleep(60)
retries += 1
except: # <- catches all other exceptions
retries = 11 # <- e.g. stop trying if another exception was raised
Related
I have below script which generates report for large size data.
Due to large size data request call times out.
I have added exception to handle this situation which works fine to get keep script running.
Issue I am having is after exception it goes to next project and skips the projects where it timed out.
I want it to start from same project again.
How can I achieve this ?
if __name__ = ‘__main__’
for project in AllProjectData['value']:
try:
project_name = project['name']
** code to be executed
except:
requests.ConnectionError,
requests.exceptions.ReadTimeout,
requests.exceptions.Timeout,
requests.exceptions.ConnectTimeout
continue
You are catching exceptions in a very odd way. I've never seen it done like this. I believe this code is catching all exceptions. For example:
try:
1/0
except:
ZeroDivisionError
pass
Works fine, but so does (it should raise IndexError):
try:
a = []
print(a[1])
except:
ZeroDivisionError
pass
So you shouldn't write except statements this way. What you should have is something along the lines:
success = False
while not success:
try:
# Your execution code
except (requests.ConnectionError,
requests.exceptions.ReadTimeout,
requests.exceptions.Timeout,
requests.exceptions.ConnectTimeout):
continue
else:
success = True
Also you should try and not put so much code in your except statement as it is confusing as to what you're trying to catch and where. Also, you're completely missing some possibilities like a KeyError when there's no id field in project and others.
Try this -
def myfunc():
# Write the code given in question completely
# Then add this in your except statement
except:
requests.ConnectionError,
requests.exceptions.ReadTimeout,
requests.exceptions.Timeout,
requests.exceptions.ConnectTimeout
# Call your function so that it will jump back to the same function
myfunc()
# You don't need continue keyword because it jumps to the same function
The simplest way would be to use a while loop with a counter variable. Let me demonstrate:
i = 0
while i < len(AllProjectData['value']):
try:
project = AllProjectData['value'][i]
# code to be executed
i += 1 # increment counter on success
except:
requests.ConnectionError,
requests.exceptions.ReadTimeout,
requests.exceptions.Timeout,
requests.exceptions.ConnectTimeout
continue
This way, you will go to the next project only if work on the previous project was executed, as the loop variable is incremented only in the try block.
Note: I have assumed that your iterable is indexable. If it's not, just pass it inside the list() constructor.
I am trying to catch an exception thrown by Selenium. When the exception is thrown I would like to restart the scraping process.
try:
startScraping(rootPage)
except (InvalidSessionIdException):
startScraping(rootPage)
finally:
driver.close()
Above is the code I am using.
The problem I am facing is that when an InvalidSessionIdException occurs the script still stops execution and shows a stacktrace.
the second startScraping(rootPage) (in the except block) is not protected by any try/except block...
If an exception occurs, retrying immediately is probably bound to fail ... again. I would
catch the exception
print a meaningful warning
wait a while
repeat until it works, or a given number of times with a for loop
like this
import time
nb_retries = 10
for nb_attempts in range(nb_retries):
try:
startScraping(rootPage)
break # success, exit the loop
except InvalidSessionIdException as e:
print("Warning: {}, attempt {}/{}".format(e,nb_attempts+1,nb_retries))
time.sleep(1)
else:
# loop went through after 10 attempts and no success
print("unable to scrape after {} retries".format(nb_retries))
driver.close()
Try this if you want to restart the process and ignoring the exception:
while True:
try:
startScraping(rootPage)
break # after finishing the scraping process
except (InvalidSessionIdException):
pass # or print the excepion
driver.close()
as mentioned in the code, you can print the exception or do any other exception handling you may want.
import time
import pyautogui
location = pyautogui.locateOnScreen('ok.png')
pyautogui.click(location)
HOW DO I WRITE THE FOLLOWING STATEMENT AS CODE?
If image is no found on screen, keep running location until the image is found.
otherwise the code is terminating immediately.
I tried :
While location == None : #Or location == False
pyautogui.click(location)
Try using while like this:
while location is not None:
pyautogui.click(location)
According to the Pyautogui documentation:
If the image can’t be found on the screen, locateOnScreen() raises ImageNotFoundException
This means that you have to handle the error message in order to keep the program running in case the image is not there.
Try using exception handling:
import pyautogui
while True:
# Try to do this
try:
location = pyautogui.locateOnScreen('ok.png')
# Location found with no errors: break the while loop and proceed
break
# If an error has occurred (image not found), keep waiting
except:
pass
pyautogui.click(location)
NOTE: This generates an infinite loop until the image is found on screen. To break this loop and stop the script execution use CTRL+C on the Shell.
In alternative you may set a maximum time waiting for the image:
import time
import pyautogui
max_wait = 30 # Seconds
end = time.time() + max_wait
while time.time() <= end:
# Try to do this
try:
location = pyautogui.locateOnScreen('ok.png')
# Location found with no errors: break the while loop and proceed
break
# If an error has occurred (image not found), keep waiting
except:
pass
pyautogui.click(location)
import sys
from twisted.internet import reactor, defer, task
from twisted.python import log
def periodic_task():
log.msg("periodic task running")
x = 10 / 0
def periodic_task_crashed(reason):
log.err(reason, "periodic_task broken")
log.startLogging(sys.stdout)
my_task = task.LoopingCall(periodic_task)
d = my_task.start(1)
d.addErrback(periodic_task_crashed)
reactor.run()
I am getting the output and it stops the script. is ther any way to continue run the script even if there is an exception error . to be frank instead of x = 10 / 0 I am doing some api calls . but when there is an error it stops the script. But what I want is to run the script even if there is an error and check again and again.
Just handle the exeption, use a try ... except block around the code you know might fail.
def periodic_task():
log.msg("periodic task running")
try:
x = 10 / 0
except Exception as error:
# Here you should at least log the error, exceptions do not should pass silently.
pass
To ensure that the script continues to run, even if there is an error, use a try / except block.
Within the except block, in order to, as specified in your query, ensure that the code checks the error, again and again, you'd use 'function recursion' to run the function again from within the function:
def periodic_task():
log.msg("periodic task running")
try:
x = 10 / 0 # include 'API calls' here
except: # include 'exception type'
periodic_task()
Although, there are many pitfalls with function recursion so be wary!
I am trying to catch an exception that is not raised, just logged. Is there any way to do this?
def exampleFunction():
try:
x = 1 / 0
except Exception:
logging.exception('divide by 0 error here.')
try:
exampleFunction()
except <condition based on if logging.exception was called>
print('there was a divide by 0 error when I called exampleFunction()')
I assume that exampleFunction is in some horrible third party code that you do not own, otherwise there are lots of better alternatives.
What you can do:
import logging # make sure this is the FIRST import of logging
import horrible_third_party_lib
def catch_log(msg):
# do something when this is called
old_logging = logging.exception
try:
logging.exception=catch_log
horrible_third_party_lib.exampleFunction()
finally:
logging.exception=old_logging
You can then do everything you want in the function. It's horrible and sensitive to import order, but I have used this and it works (scikit learn does something similarly repugnant..)
Question: I am trying to catch an exception
The Questions Title should be rewriten to "I am trying to reraise an exception"
Read Python Documentation#raise
Seems somewhat double work, but you can do it like that:
def exampleFunction():
try:
x = 1 / 0
except Exception as e:
print("logging.exception({})".format(e))
raise
try:
exampleFunction()
except ZeroDivisionError as e:
print('there was a divide by 0 error when I called exampleFunction()')
Output:
logging.exception(division by zero)
there was a divide by 0 error when I called exampleFunction()
Tested with Python:3.5.3