折腾:
【已解决】Mac中启动uiautomator2的weditor界面调试环境
期间,后续去刷新页面,结果报错:
[E 201211 16:18:11 web:2242] 500 GET /api/v1/devices/android%3A2e2a0cb1/screenshot (::1) 562.18ms
[I 201211 16:18:31 web:2242] 200 POST /api/v1/connect (::1) 18.04ms
[I 201211 16:18:31 web:2242] 200 POST /api/v1/connect (::1) 31.33ms
[I 201211 16:18:31 page:297] Serial: android:2e2a0cb1
[E 201211 16:18:31 web:1784] Uncaught exception GET /api/v1/devices/android%3A2e2a0cb1/screenshot (::1)
HTTPServerRequest(protocol='http', host='localhost:17310', method='GET', uri='/api/v1/devices/android%3A2e2a0cb1/screenshot', version='HTTP/1.1', remote_ip='::1')
Traceback (most recent call last):
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/uiautomator2/__init__.py", line 879, in screenshot
rgbImg = Image.open(buff).convert("RGB")
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/PIL/Image.py", line 2861, in open
raise UnidentifiedImageError(
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x105919c70>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/tornado/web.py", line 1697, in _execute
result = method(*self.path_args, **self.path_kwargs)
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/weditor/web/handlers/page.py", line 301, in get
d.screenshot().convert("RGB").save(buffer, format='JPEG')
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/weditor/web/device.py", line 28, in screenshot
return self._d.screenshot()
File "</Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/decorator.py:decorator-gen-10>", line 2, in screenshot
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/retry/api.py", line 73, in retry_decorator
return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter,
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/retry/api.py", line 33, in __retry_internal
return f()
File "/Users/xxx/dev/xxx/crawler/appAutoCrawler/AppCrawler/venv/lib/python3.8/site-packages/uiautomator2/__init__.py", line 886, in screenshot
if d.settings['fallback_to_blank_screenshot']:
NameError: name 'd' is not defined
[E 201211 16:18:31 web:2242] 500 GET /api/v1/devices/android%3A2e2a0cb1/screenshot (::1) 555.80ms
表面上看是缺少了个d
但是感觉好像是由于 Pillow的PIL的image保存图片时出错的呢
像是之前自己遇到的:
【已解决】Python自动化安卓游戏测试报错:cannot write mode RGBA as JPEG
去看看代码:
venv/lib/python3.8/site-packages/uiautomator2/__init__.py
@retry((IOError, SyntaxError), delay=.5, tries=5, jitter=0.1,
max_delay=1, logger=logging) # delay .5, .6, .7, .8 ...
def screenshot(self, filename: Optional[str] = None, format="pillow"):
"""
Take screenshot of device
Returns:
PIL.Image.Image, np.ndarray (OpenCV format) or None
Args:
filename (str): saved filename, if filename is set then return None
format (str): used when filename is empty. one of ["pillow", "opencv", "raw"]
Raises:
IOError, SyntaxError, ValueError
Examples:
screenshot("saved.jpg")
screenshot().save("saved.png")
cv2.imwrite('saved.jpg', screenshot(format='opencv'))
"""
# print("filename=%s, format=%s" % (filename, format))
# print("before /screenshot/0: %s" % datetime.now())
beforeSceenshotTime = datetime.now()
# print("beforeSceenshotTime=%s" % beforeSceenshotTime)
r = self.http.get("/screenshot/0", timeout=10)
# print("after /screenshot/0: %s" % datetime.now())
afterSceenshotTime = datetime.now()
# print("afterSceenshotTime=%s" % afterSceenshotTime)
screenshotCostTime = afterSceenshotTime - beforeSceenshotTime
# print("/screenshot/0 time: %s" % screenshotCostTime)
# print("before process: %s" % datetime.now())
if filename:
beforeSaveFileTime = datetime.now()
with open(filename, 'wb') as f:
f.write(r.content)
afterSaveFileTime = datetime.now()
saveFileTime = afterSaveFileTime - beforeSaveFileTime
# print("save file time: %s" % saveFileTime)
return filename
elif format == 'pillow':
buff = io.BytesIO(r.content)
# print("after io.BytesIO: %s" % datetime.now())
try:
# print("before convert RGB: %s" % datetime.now())
rgbImg = Image.open(buff).convert("RGB")
# print("after convert RGB: %s" % datetime.now())
return rgbImg
except IOError as ex:
# Always fail in secure page
# 截图失败直接返回一个粉色的图片
# d.settings['default_screenshot'] =
if d.settings['fallback_to_blank_screenshot']:
raise IOError("PIL.Image.open IOError", ex)
return Image.new("RGB", self.window_size(), (220, 120, 100))
elif format == 'opencv':
import cv2
import numpy as np
nparr = np.fromstring(r.content, np.uint8)
# print("before cv2.imdecode: %s" % datetime.now())
decodedImage = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
# print("after cv2.imdecode: %s" % datetime.now())
return decodedImage
elif format == 'raw':
print("before resp content: %s" % datetime.now())
return r.content
else:
raise ValueError("Invalid format {}".format(format))
正好是最近调试过的代码。
if d.settings['fallback_to_blank_screenshot']:
去找了下,别处都是
self.settings
所以去改为:
if self.settings['fallback_to_blank_screenshot']:
估计就可以了。
但是此处只是解决了语法错误,没有解决逻辑错误:
依旧是去img转换报错的。
把自己的代码合并过来
jpegNotSupportFormatList = ["RGBA", "P"]
originImg = Image.open(buff)
if originImg.mode in jpegNotSupportFormatList:
originImg = originImg.convert("RGB")但是突然发现,其本身就是去转换为RGB的
算了, 还是去调试,看看:
if self.settings['fallback_to_blank_screenshot']:
raise IOError("PIL.Image.open IOError", ex)抛出的异常具体是啥
不过发现代码:
originImg = Image.open(buff)
print("originImg.mode=%s" % originImg.mode)
jpegNotSupportFormatList = ["RGBA", "P"]
if originImg.mode in jpegNotSupportFormatList:
originImg = originImg.convert("RGB")
rgbImg = originImg
# print("after convert RGB: %s" % datetime.now())
return rgbImg已经可以正常工作了:
[I 201211 16:37:54 page:297] Serial: android:2e2a0cb1 filename=None, format=pillow originImg.mode=RGBA [I 201211 16:37:55 web:2242] 200 GET /api/v1/devices/android%3A2e2a0cb1/screenshot (::1) 976.28ms
没问题了。
可以截图了:

【总结】
目前是把之前代码:
venv/lib/python3.8/site-packages/uiautomator2/__init__.py
elif format == 'pillow':
buff = io.BytesIO(r.content)
# print("after io.BytesIO: %s" % datetime.now())
try:
# print("before convert RGB: %s" % datetime.now())
rgbImg = Image.open(buff).convert("RGB")
# print("after convert RGB: %s" % datetime.now())
return rgbImg
except IOError as ex:
# Always fail in secure page
# 截图失败直接返回一个粉色的图片
# d.settings['default_screenshot'] =
if d.settings['fallback_to_blank_screenshot']:
raise IOError("PIL.Image.open IOError", ex)
return Image.new("RGB", self.window_size(), (220, 120, 100))改为:
elif format == 'pillow':
buff = io.BytesIO(r.content)
# print("after io.BytesIO: %s" % datetime.now())
try:
# print("before convert RGB: %s" % datetime.now())
# rgbImg = Image.open(buff).convert("RGB")
originImg = Image.open(buff)
print("originImg.mode=%s" % originImg.mode)
jpegNotSupportFormatList = ["RGBA", "P"]
if originImg.mode in jpegNotSupportFormatList:
originImg = originImg.convert("RGB")
rgbImg = originImg
# print("after convert RGB: %s" % datetime.now())
return rgbImg
except IOError as ex:
# Always fail in secure page
# 截图失败直接返回一个粉色的图片
# d.settings['default_screenshot'] =
# if d.settings['fallback_to_blank_screenshot']:
if self.settings['fallback_to_blank_screenshot']:
raise IOError("PIL.Image.open IOError", ex)
return Image.new("RGB", self.window_size(), (220, 120, 100)) 即可:正常截图了。
转载请注明:在路上 » 【已解决】weditor刷新安卓手机最新页面报错:500 GET /api/v1/devices/android screenshot NameError name d is not defined