2011-11-15 11 views
6

He estado tratando de usar html5lib con lxml en python 2.7 en el motor de la aplicación google. Pero cuando ejecuto el siguiente código, me da un error que dice "NameError: nombre global 'etree' no está definido". ¿No es posible usar lxml.etree en el motor de la aplicación google? ¿O me estoy perdiendo algo?Python 2.7 en Google App Engine, no puedo usar lxml.etree

app.yaml

application: testsite 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: false 

handlers: 
- url: /.* 
    script: index.py 

libraries: 
- name: lxml 
    version: "2.3" # I thought this would allow me to use lxml.etree 

index.py

from testhandler import TestHandler 
application = webapp.WSGIApplication([('/', TestHandler)], debug=True) 

testhandler.py

import urllib2 
import html5lib 
from html5lib import treebuilders 
try: 
    from lxml import etree 
    print("running with lxml.etree") 
except ImportError: 
    try: 
     # Python 2.5 
     import xml.etree.cElementTree as etree 
     print("running with cElementTree on Python 2.5+") 
    except ImportError: 
     try: 
      # Python 2.5 
      import xml.etree.ElementTree as etree 
      print("running with ElementTree on Python 2.5+") 
     except ImportError: 
      try: 
       # normal cElementTree install 
       import cElementTree as etree 
       print("running with cElementTree") 
      except ImportError: 
       try: 
        # normal ElementTree install 
        import elementtree.ElementTree as etree 
        print("running with ElementTree") 
       except ImportError: 
        print("Failed to import ElementTree from any known place") 

from google.appengine.ext import webapp 

class TestHandler(webapp.RequestHandler): 
    def get(self): 
     f = urllib2.urlopen("http://www.yahoo.com/").read() 
     doc = html5lib.parse(f, treebuilder='lxml') 
     elems = doc.xpath("//*[local-name() = 'a']") 
     self.response.out.write(len(elems)) 

error

running with cElementTree on Python 2.5+ 
Status: 500 Internal Server Error 
Content-Type: text/html; charset=utf-8 
Cache-Control: no-cache 
Expires: Fri, 01 Jan 1990 00:00:00 GMT 
Content-Length: 769 

<pre>Traceback (most recent call last): 
    File &quot;/usr/local/bin/google_appengine/google/appengine/ext/webapp/_webapp25.py&quot;,  line 701, in __call__ 
handler.get(*groups) 
    File &quot;/home/test/testhandler.py&quot;, line 38, in get 
    parser = html5lib.HTMLParser(tree= treebuilders.getTreeBuilder('lxml')) 
    File &quot;/home/test/html5lib/html5parser.py&quot;, line 68, in __init__ 
    self.tree = tree(namespaceHTMLElements) 
    File &quot;/home/test/html5lib/treebuilders/etree_lxml.py&quot;, line 176, in __init__ 
    builder = etree_builders.getETreeModule(etree, fullTree=fullTree) 
NameError: global name 'etree' is not defined 
</pre> 

ADD

Nah, intenté varias formas de crear un objeto de doc, pero no tuve suerte. Una de las formas, traté de importar from lxml.html import document_fromstring y eso me da este error.

Traceback (most recent call last): 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 4143, in _HandleRequest 
    self._Dispatch(dispatcher, self.rfile, outfile, env_dict) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 4049, in _Dispatch 
    base_env_dict=env_dict) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 616, in Dispatch 
    base_env_dict=base_env_dict) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 3120, in Dispatch 
    self._module_dict) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 3024, in ExecuteCGI 
    reset_modules = exec_script(handler_path, cgi_path, hook) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 2887, in ExecuteOrImportScript 
    exec module_code in script_module.__dict__ 
    File "/home/yoo/eclipse_workspace/website_checker/src/index.py", line 5, in <module> 
    from handlers.updatecheck import UpdateCheckHandler 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 1538, in Decorate 
    return func(self, *args, **kwargs) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 2503, in load_module 
    return self.FindAndLoadModule(submodule, fullname, search_path) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 1538, in Decorate 
    return func(self, *args, **kwargs) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 2375, in FindAndLoadModule 
    description) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 1538, in Decorate 
    return func(self, *args, **kwargs) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 2318, in LoadModuleRestricted 
    description) 
    File "/home/test/updatecheck.py", line 4, in <module> 
    from lxml.html import document_fromstring 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 1538, in Decorate 
    return func(self, *args, **kwargs) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 2503, in load_module 
    return self.FindAndLoadModule(submodule, fullname, search_path) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 1538, in Decorate 
    return func(self, *args, **kwargs) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 2375, in FindAndLoadModule 
    description) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 1538, in Decorate 
    return func(self, *args, **kwargs) 
    File "/usr/local/bin/google_appengine/google/appengine/tools/dev_appserver.py", line 2318, in LoadModuleRestricted 
    description) 
    File "/usr/lib/python2.7/dist-packages/lxml/html/__init__.py", line 12, in <module> 
    from lxml import etree 
ImportError: cannot import name etree 

De acuerdo con el error, parece motor de aplicación no me permite cargar el módulo etree por alguna razón. Quería usar xpath con lxml, pero no puedo perder mucho tiempo para descubrir qué está pasando aquí y tampoco tengo suficiente conocimiento de Python. Así que intentaré encontrar la manera con la versión 'simpletree'.

f = urllib2.urlopen("http://www.yahoo.com/").read() 
p = html5lib.HTMLParser() 
doc = p.parse(f) 
# do something with doc.childNodes 
self.response.out.write(len(doc.childNodes)) 

No es realmente una buena manera, pero al menos funcionó cuando probé en el motor de la aplicación de google en vivo.

+0

¿Qué versión de HTML5lib?En el repositorio, la línea con el error ya no es la línea 176, y no veo ninguna forma de que ese error ocurra en la versión actual, ya que el nombre se definirá o todo fallará con un ImportError. – geoffspear

+0

Perdón por no contactarte pronto. Creo que la versión es 0.90 según html5lib/__ init__.py en la línea 13 '__version__ =" 0.90 "'. Acabo de obtener la biblioteca por instalación de pip, ¿podría ser una versión anterior? –

+0

recibí este error cuando olvidé poner la entrada correcta en app.yaml, pero en lugar de usar 2.3 utilicé la última – semisided1

Respuesta

1

¿Has instalado lxml localmente? Tuve el mismo error antes: la importación falló. Puede descargar lxml aquí: http://pypi.python.org/pypi/lxml/

lxml funciona con GAE y esto es genial. Pero es una ausencia real de cualquier documentación o ejemplos sobre eso en este momento.

+0

Sí. Probé el código original en mi máquina local y funcionó perfectamente, pero cuando lo subí al motor de la aplicación de Google en vivo, me dan el error anterior. –

0

Trate

import lxml

en la parte superior de su testhandler

1

En Windows, he tenido este problema y es debido al hecho de la distro python27 no incluye el lxml. Puede usar el script easy_install pero tendrá que compilar el código fuente que me causó problemas.

El uso de este post que encontré en los foros de Google:

https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.python/Q8YeOIbn5Ds

Sin embargo, si usted quiere ahorrarse el dolor tratando de conseguir que construir desde el código fuente, sólo tiene que instalar un binario precompilado, por ejemplo, el disponible en: http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml

Simplemente descargue el archivo ejecutable del sitio web anterior y ejecute el * .exe y detiene todo el código necesario.

0

instalar con pip: pip install lxml