折腾:
【已解决】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