【问题标题】:ImportError: No module named bs4 when called from launchdImportError:从launchd调用时没有名为bs4的模块
【发布时间】:2016-02-27 14:36:29
【问题描述】:

我正在一个脚本中运行以下 python 导入,该脚本可以从终端的命令行和 ipython 笔记本正常运行。

#!/usr/bin/python
import os
import re
import urllib
import urllib2 as ul
import sys
from bs4 import BeautifulSoup as bs

当它通过 Mac 启动从 .plist 文件调用时,我收到以下错误:

11/24/15 1:17:05 PM com.jerry.sat_images[668]   Traceback (most recent call last):
11/24/15 1:17:05 PM com.jerry.sat_images[668]     File "/Users/jerrykallam/python_practice/sat_image.py", line 6, in <module>
11/24/15 1:17:05 PM com.jerry.sat_images[668]       import bs4
11/24/15 1:17:05 PM com.jerry.sat_images[668]   ImportError: No module named bs4
11/24/15 1:17:05 PM com.apple.launchd.peruser.501[165]  (com.jerry.sat_images[668]) Exited with exit code: 1

从命令行和 ipython bs4 导入,脚本工作正常。这是似乎可以正常工作的 .plist 代码。不知道为什么脚本只有在被 launchd 调用时才能导入 bs4。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.jerry.satimages</string>
        <key>ProgramArguments</key>
        <array>
           <string>python</string>
            <string>/Users/jerrykallam/python_practice/sat_image.py</string>
        </array>
        <key>StartInterval</key>
        <integer>360</integer>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist> 

【问题讨论】:

  • 你能运行sudo pip freeze | grep beautifulsoup4 看看是否为超级用户安装了包吗?
  • 我得到以下信息:目录 '/Users/jerrykallam/Library/Caches/pip/http' 或其父目录不属于当前用户,并且缓存已被禁用。请检查该目录的权限和所有者。如果使用 sudo 执行 pip,您可能需要 sudo 的 -H 标志。 beautifulsoup4==4.3.2
  • 那个目录的权限和所有者是什么?
  • 当我运行 sudo -H pip freeze | grep beautifulsoup4,我得到:beautifulsoup4==4.3.2
  • 权限为:drwx------ 4 jerrykallam 员工 136 Oct 26 14:53 http

标签: python launchd bs4 launchdagent


【解决方案1】:

我遇到了这个确切的问题(OS X 10.11.3 El Cap)。将 PYTHONPATH 添加到 EnvironmentVariables 不起作用。起作用的是调用 python 的特定路径。

所以,在 ProgramArguments 中而不是:

   <string>python</string>

...这个:

   <string>/your/python/path</string>

【讨论】:

    【解决方案2】:

    这可能是因为 launchd 以 root 身份运行其守护进程,而 bs4 可能未安装在超级用户的 PYTHONPATH 中的某个位置。要解决此问题,您可以添加 EnvironmentVariables 键,并在那里设置 PYTHONPATH 的值。要弄清楚你的 PYTHONPATH 是什么,你可以运行echo $PYTHONPATH

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
        <dict>
            <key>Label</key>
            <string>com.jerry.satimages</string>
            <key>ProgramArguments</key>
            <array>
               <string>python</string>
                <string>/Users/jerrykallam/python_practice/sat_image.py</string>
            </array>
            <!-- ADDED THIS -->
            <key>EnvironmentVariables</key>
            <dict>
                <key>PYTHONPATH</key>
                <string>/your/python/path</string>
            </dict>
            <key>StartInterval</key>
            <integer>360</integer>
            <key>RunAtLoad</key>
            <true/>
        </dict>
    </plist> 
    

    【讨论】:

      【解决方案3】:

      查找 CLI 与从 plist 中运行时 sys.path 的差异。如果 bs4 模块相对于 python 路径不在正确的位置,它就不会找到它。

       #!/usr/bin/env python
      
       import sys
       print sys.path 
      

      使用 plist 版本,您可能必须:

      fd=open('/var/tmp/fred.txt','w') 
      
      ted = sys.path
      
      fd.writelines(ted) 
      fd.close() 
      

      而不仅仅是“打印 sys.path”。

      基本上,我猜测 .plist 文件是在您的 unix(ish) 环境完全设置之前运行的。

      【讨论】:

        猜你喜欢
        • 2012-07-31
        • 1970-01-01
        • 2014-10-31
        • 1970-01-01
        • 2017-06-18
        • 2017-02-19
        • 2015-01-02
        • 2018-12-30
        • 2021-04-02
        相关资源
        最近更新 更多