Mac执行pyautogui.screenshot()时报错

发布时间 2023-09-12 12:03:30作者: 逆行

报错信息

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[3], line 1
----> 1 pyautogui.screenshot()

File ~/anaconda3/lib/python3.11/site-packages/pyscreeze/__init__.py:527, in _screenshot_osx(imageFilename, region)
    523 """
    524 TODO
    525 """
    526 # TODO - use tmp name for this file.
--> 527 if tuple(PIL__version__) < (6, 2, 1):
    530     # Use the screencapture program if Pillow is older than 6.2.1, which
    531     # is when Pillow supported ImageGrab.grab() on macOS. (It may have
    532     # supported it earlier than 6.2.1, but I haven't tested it.)
    533     if imageFilename is None:
    534         tmpFilename = 'screenshot%s.png' % (datetime.datetime.now().strftime('%Y-%m%d_%H-%M-%S-%f'))

TypeError: '<' not supported between instances of 'str' and 'int'

可见指向 527 行的代码,对比2个变量时,出现类型错误,这是pyautogui的bug,我们只能自己来修复该错误。该语句是对比版本号,当PIL的版本小于 6.2.1时,才进入if语句。
PIL即Pillow库

通过 pip show Pillow 查看已安装的Pillow版本

pip show Pillow
Name: Pillow
Version: 9.4.0
Summary: Python Imaging Library (Fork)
Home-page: https://python-pillow.org
Author: Alex Clark (PIL Fork Author)
Author-email: aclark@python-pillow.org
License: HPND

可见在我的系统里,并不会进入if语句。
从报错信息可见文件路径为~/anaconda3/lib/python3.11/site-packages/pyscreeze/__init__.py,打开该文件,这里我们直接把 527行的代码改成 if False: 即可。

最终代码如下:

def _screenshot_osx(imageFilename=None, region=None):
    """
    TODO
    """
    # TODO - use tmp name for this file.
    # if tuple(PIL__version__) < (6, 2, 1):
    # 这里报错了。并且我使用的是9.4.0,并不会进入判断语句
    if False:            
        # Use the screencapture program if Pillow is older than 6.2.1, which
        # is when Pillow supported ImageGrab.grab() on macOS. (It may have
        # supported it earlier than 6.2.1, but I haven't tested it.)
        if imageFilename is None:
            tmpFilename = 'screenshot%s.png' % (datetime.datetime.now().strftime('%Y-%m%d_%H-%M-%S-%f'))
        else:
            tmpFilename = imageFilename
        subprocess.call(['screencapture', '-x', tmpFilename])
        im = Image.open(tmpFilename)

        if region is not None:
            assert len(region) == 4, 'region argument must be a tuple of four ints'
            region = [int(x) for x in region]
            im = im.crop((region[0], region[1], region[2] + region[0], region[3] + region[1]))
            os.unlink(tmpFilename)  # delete image of entire screen to save cropped version
            im.save(tmpFilename)
        else:
            # force loading before unlinking, Image.open() is lazy
            im.load()

        if imageFilename is None:
            os.unlink(tmpFilename)
    else:
        # Use ImageGrab.grab() to get the screenshot if Pillow version 6.3.2 or later is installed.
        im = ImageGrab.grab()
    return im

保存并重启虚拟环境。