2011-11-15 14 views
6

Ho cercato di utilizzare html5lib con lxml su python 2.7 nel motore di app di google. Ma quando eseguo il seguente codice, mi dà un errore dicendo "NameError: nome globale 'etree' non è definito". Non è possibile utilizzare lxml.etree sul motore di app di google? O mi sta sfuggendo qualcosa?Python 2.7 su Google App Engine, non è possibile utilizzare 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)) 

errore

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, ho provato diversi modi per creare un oggetto doc, ma senza fortuna. Uno dei modi, ho provato a importare from lxml.html import document_fromstring e questo mi dà questo errore.

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 

In base all'errore, sembra che il motore dell'app non mi consenta di caricare il modulo etree per qualche motivo. Volevo usare xpath con lxml, ma non posso passare molto tempo a capire cosa sta succedendo qui e non ho abbastanza conoscenza di Python. Quindi vorrei provare a trovare un modo con la versione '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)) 

Non proprio un buon modo, ma almeno ha funzionato quando ho provato sul motore di google live app.

+0

Quale versione di HTML5lib?Nel repository, la riga con l'errore non è più la riga 176, e non riesco a vedere in alcun modo che l'errore possa verificarsi nella versione corrente poiché il nome sarà definito o l'intera cosa fallirà con un ImportError. – geoffspear

+0

Ci scusiamo per non essere tornato presto. Penso che la versione sia 0.90 secondo html5lib/__ init__.py alla riga 13 '__version__ =" 0.90 "'. Ho appena ottenuto la libreria da pip install, potrebbe essere la versione precedente? –

+0

ho ricevuto questo errore quando ho dimenticato di inserire la voce corretta in app.yaml, ma invece di usare 2.3 ho usato l'ultima – semisided1

risposta

1

Hai installato localmente lxml? Ho avuto lo stesso errore prima - importazione fallita. Puoi scaricare lxml qui: http://pypi.python.org/pypi/lxml/

lxml funziona con GAE e questo è ottimo. Ma è una vera assenza di documentazione o esempi su questo al momento.

+0

Sì. Ho provato il codice originale sulla mia macchina locale e ha funzionato perfettamente, ma quando l'ho caricato per vivere il motore di app di google, poi mi dà l'errore sopra. –

0

Prova

import lxml

nella parte superiore del vostro testhandler

1

Su Windows, ho avuto questo problema ed è dovuto al fatto che la distro python27 non include il lxml. Puoi usare lo script easy_install ma dovrai compilare la fonte che mi ha dato problemi.

Utilizzando questo post che ho trovato sul forum di Google:

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

Tuttavia, se si vuole risparmiare il dolore cercando di farlo per costruire dai sorgenti, è sufficiente installare un binario precompilato, ad esempio la uno disponibile da: http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml

Basta scaricare l'eseguibile dal sito Web di cui sopra ed eseguire * .exe e blocca tutto il codice necessario.

0

installare con pip: pip install lxml

Problemi correlati