最新消息:20210917 已从crifan.com换到crifan.org

【已解决】weditor刷新安卓手机最新页面报错:500 GET /api/v1/devices/android screenshot NameError name d is not defined

安卓 crifan 823浏览 0评论
折腾:
【已解决】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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
93 queries in 0.266 seconds, using 23.40MB memory