unexposed unexposed - 4 months ago 23
Python Question

AttributeError: __exit__ while buffering downloaded image on python 2.7

I'm trying to automate captcha file recognition with a python script.
However, after several days of efforts my functions seems to be far from desired result.

Furthermore, the traceback I've got is not informative enough to help me investigate further.

Here is my function:

def getmsg():
solved = ''
probe_request = []
try:
probe_request = api.messages.get(offset = 0, count = 2)
except apierror, e:
if e.code is 14:
key = e.captcha_sid
imagefile = cStringIO.StringIO(urllib.urlopen(e.captcha_img).read())
img = Image.open(imagefile)
imagebuf = img.load()
with imagebuf as captcha_file:
captcha = cptapi.solve(captcha_file)
finally:
while solved is None:
solved = captcha.try_get_result()
tm.sleep(1.500)
print probe_request


Here is the traceback:

Traceback (most recent call last):
File "myscript.py", line 158, in <module>
getmsg()
File "myscript.py", line 147, in getmsg
with imagebuf as captcha_file:
AttributeError: __exit__


Can someone please clarify what exactly I'm doing wrong?

Also I did not succeed with image processing without buffering:

key = e.captcha_sid
response = requests.get(e.captcha_img)
img = Image.open(StringIO.StringIO(response.content))
with img as captcha_file:
captcha = cptapi.solve(captcha_file)


Which leads to:

captcha = cptapi.solve(captcha_file)
File "/usr/local/lib/python2.7/dist-packages/twocaptchaapi/__init__.py", line 62, in proxy
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/twocaptchaapi/__init__.py", line 75, in proxy
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/twocaptchaapi/__init__.py", line 147, in solve
raw_data = file.read()
File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 632, in __getattr__
raise AttributeError(name)
AttributeError: read

Answer

imagebuf is not a context manager. You can't use it in a with statement, which tests for a context manager by first storing the contextmanager.__exit__ method. There is no need to close it either.

cptapi.solve requires a file-like object; from the solve() docstring:

Queues a captcha for solving. file may either be a path or a file object.

There is no point in passing in an Image object here, just pass in the StringIO instance instead:

imagefile = cStringIO.StringIO(urllib.urlopen(e.captcha_img).read())
captcha = cptapi.solve(imagefile)

Again, there is no need to use close that object here, you don't need to use with.

Comments