使用BeautifulSoup上的Python on Appengine ImportError:没有名为bs4的模块

nic*_*las 5 python google-app-engine beautifulsoup python-2.7

编辑2:解决了!请参阅以下有关正确导入的答案 from lib.bs4 import BeautifulSoup而不仅仅是from bs4 import BeautifulSoup

编辑:将bs4放在项目的根目录似乎解决了这个问题; 但是,它不是一个理想的结构.因此,我将这个问题保持活跃,以尝试获得更强大的解决方案.

过去已经问过这个问题的变体,但那里的解决方案似乎没有用.我不确定这是因为BeautifulSoup或Appengine的变化,说实话.

请参阅:Python 2.7:如何在Google App Engine中使用BeautifulSoup?,如何在Google App Engine中包含第三方Python库?,哪个版本的BeautifulSoup适用于GAE(python 2.5)?

Lipis提出的解决方案似乎是将第三方库添加到项目根目录中的libs文件夹,然后将以下内容添加到主应用程序中:

import sys
sys.path.insert(0, 'libs')
Run Code Online (Sandbox Code Playgroud)

目前,我的结构是这样的:

ntj-test
??? lib
?   ??? bs4 
??? templates
??? main.py
??? get_data.py 
??? app.yaml
Run Code Online (Sandbox Code Playgroud)

这是我的app.yaml:

application: ntj-test
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: latest
- name: jinja2
  version: latest
Run Code Online (Sandbox Code Playgroud)

这是我的main.py:

import webapp2
import jinja2
import get_data
import sys

sys.path.insert(0, 'lib')

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader('templates'),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True,
)


class MainHandler(webapp2.RequestHandler):
    def get(self):

        teamName = get_data.all_coach_data()[1]
        coachName = get_data.all_coach_data()[2]
        teamKey = get_data.all_coach_data()[0]

        values = {
            'coachName': coachName,
            'teamName': teamName,
            'teamKey': teamKey,
        }

        template = JINJA_ENVIRONMENT.get_template('index.html')
        self.response.write(template.render(values))

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)
Run Code Online (Sandbox Code Playgroud)

get_data.py将正确的数据返回到我的变量以填充值,我已在调试器中验证了这些值.

在我的开发环境中启动main.py时出现问题(我还没有上传到gcloud).没有失败,无论我通过上述链接或整个谷歌搜索发现的狡猾技巧,终端总是返回:

Import Error: No module named bs4
Run Code Online (Sandbox Code Playgroud)

在上面的一个SO链接中,一位评论者说"GAE仅支持纯Python模块.bs4不纯,因为某些部分是用C语言编写的." 我不确定这是否属实,我不确定如何验证它.我没有足够的声誉来评论发现.:(

我已经浏览了Crummy网站上的bs4文档,我已经阅读了所有相关的SO问题和答案,我试图从Appengine的文档中收集提示.但是,我一直无法找到不涉及使用已弃用的BeautifulSoup版本的解决方案,因为它没有我需要的功能.

我是编程和使用StackOverflow的初学者,所以如果我遗漏了一些重要的信息或没有遵循问题的良好做法,请告诉我.我将在必要时编辑和添加其他信息.

谢谢!

编辑:我不确定get_data代码是否过度,但这里是:

from bs4 import BeautifulSoup
import urllib2, re

teamKeys = {
    'ATL': 'Atlanta Falcons',
    'HOU': 'Houston Texans',
}

def get_all_coaches():
    for key in teamKeys:
        page = urllib2.urlopen("http://www.nfl.com/teams/coaches?coaType=head&team=" + key)
        soup = BeautifulSoup(page)
        return(head_coach(soup))

def head_coach(soup):
    head = soup.select('.coachprofiletext p')[0].text
    position, name = re.split(': ', head)
    return name

def export_coach_data():
    testList = []
    for key in teamKeys:
        page = urllib2.urlopen("http://www.nfl.com/teams/coaches?coaType=head&team=" + key)
        soup = BeautifulSoup(page)
        teamKey = key
        teamName = teamKeys[key]
        headCoach = head_coach(soup)

        t = [
            teamKey,
            teamName,
            str(headCoach),
        ]

        testList.append(t)

    return(testList)

def all_coach_data():
    results = data.export_coach_data()

    ATL = results[0]
    HOU = results[1]

    return ATL
Run Code Online (Sandbox Code Playgroud)

我想指出,这可能是执行不力(我只是在业余时间认真开发几个月),但它确实将正确的值返回到main中的变量.

这是Appengine Launcher日志:

2014-11-05 15:36:53 Running command: "['C:\\Python27\\pythonw.exe', 'C:\\Program Files\\Google\\Cloud SDK\\google-cloud-sdk\\platform\\google_appengine\\dev_appserver.py', '--skip_sdk_update_check=yes', '--port=11080', '--admin_port=8003', u'G:\\projects\\coaches']"
INFO     2014-11-05 15:37:00,119 devappserver2.py:725] Skipping SDK update check.
WARNING  2014-11-05 15:37:00,157 api_server.py:383] Could not initialize images API; you are likely missing the Python "PIL" module.
INFO     2014-11-05 15:37:00,190 api_server.py:171] Starting API server at: http://localhost:19713
INFO     2014-11-05 15:37:00,210 dispatcher.py:183] Starting module "default" running at: http://localhost:11080
INFO     2014-11-05 15:37:00,216 admin_server.py:117] Starting admin server at: http://localhost:8003
ERROR    2014-11-05 20:37:48,726 wsgi.py:262] 

Traceback (most recent call last):

  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\runtime\wsgi.py", line 239, in Handle

    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())

  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\runtime\wsgi.py", line 298, in _LoadHandler

    handler, path, err = LoadObject(self._handler)

  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\runtime\wsgi.py", line 84, in LoadObject

    obj = __import__(path[0])

  File "G:\projects\coaches\main.py", line 3, in <module>

    import get_data

  File "G:\projects\coaches\get_data.py", line 1, in <module>

    from bs4 import BeautifulSoup

ImportError: No module named bs4

INFO     2014-11-05 15:37:48,762 module.py:652] default: "GET / HTTP/1.1" 500 -
Run Code Online (Sandbox Code Playgroud)

nic*_*las 3

编辑:有人指出,这有点黑客行为。如果是这样,如何修改此解决方案以不需要重命名 BS4 内的模块?

http://www.reddit.com/r/learnpython的几个用户帮助我解决了这个问题。

通过扩展 Lipis 提出的解决方案,我们在 main.py 中添加了以下内容:

import os, sys

rootdir = os.path.dirname(os.path.abspath(__file__))
lib = os.path.join(rootdir, 'lib')
sys.path.append(lib)
Run Code Online (Sandbox Code Playgroud)

然后,这是这里或任何其他答案中没有人提到的内容,我将“lib.bs4”添加到我的所有导入语句中,如下所示:

from lib.bs4 import BeautifulSoup
Run Code Online (Sandbox Code Playgroud)

但是,不仅如此,bs4 库本身也有引用bs4,所以我搜索并将所有这些替换为lib.bs4.<something>.

现在,我的应用程序终于运行了,结构也组织好了。所有功劳都归功于/u/invalidusemame和/u/prohulaelk。

希望这篇文章可以帮助遇到类似情况的其他人。也许很明显,所有导入都需要添加到导入语句中,但从所有答案中并不是立即显而易见的。

感谢所有帮助解决问题的人!