2014-10-28 10 views
8

Ich muss meinen Code rückwärts kompatibel mit Python2.6 und BeautifulSoup 3 machen. Mein Code wurde mit Python2.7 und in diesem Fall mit BS4 geschrieben. Aber wenn ich versuche es bei squeezy-Server zu laufen, ich diesen Fehler (es hat python2.6 und bs3):BeautifulSoup - TypeError: 'NoneType' -Objekt ist nicht aufrufbar

try: 
    from bs4 import BeautifulSoup 
except ImportError: 
    from BeautifulSoup import BeautifulSoup 

gmp = open(fname, 'r') 
soup = BeautifulSoup(gmp) 
p = soup.body.div.find_all('p') 

p = soup.body.div.find_all('p') 
TypeError: 'NoneType' object is not callable 

Wenn ich ändern:

p = soup.body.div.findAll('p') 

dann bekomme ich diese Fehlermeldung:

p = soup.body.div.findAll('p') 
TypeError: 'NoneType' object is not callable 

Update des geworfenen Fehlers

File "/home/user/openerp/7.0/addons/my_module/models/gec.py", line 401, in parse_html_data 
    p = soup.body.div.findAll('p') #used findAll instead of find_all for backwards compatability to bs3 version 
TypeError: 'NoneType' object is not callable 

In beiden Fällen funktionieren beide Ansätze auf meinem Ubuntu mit python2.7 und bs4, aber nicht mit squeezy. Gibt es einen anderen Unterschied zwischen den Versionen, die ich nicht sehe/kenne und mir diesen Fehler gibt?

+0

Es hat keinen Sinn, auf 'BeautifulSoup import BeautifulSoup' (Version 3) zurückzugreifen, wenn nur Version 4 verwendet wird. –

+0

Sie sollten sehen, dass ich geschrieben habe, ich versuchte, rückwärtskompatible Syntax zu verwenden, aber immer noch denselben Fehler. – Andrius

Antwort

18

Sie verwenden BeautifulSoup 3, verwenden aber die BeautifulSoup 4-Syntax.

Ihr Rückfall bei Störung ist hier:

try: 
    from bs4 import BeautifulSoup 
except ImportError: 
    from BeautifulSoup import BeautifulSoup 

Wenn Sie entweder Version 3 oder 4, halten Sie sich an die Version 3 Syntax:

p = soup.body.div.findAll('p') 

weil find_all ist kein gültiges Verfahren in BeautifulSoup 3, so wird es stattdessen als Tag-Suche interpretiert. Es gibt kein find_all Tag in Ihrem HTML, also wird None zurückgegeben, das Sie dann versuchen, anzurufen.

Als nächstes wird der Parser, der von BeautifulSoup 3 verwendet wird, anders auf beschädigtes oder unvollständiges HTML reagieren. Wenn Sie lxml auf Ubuntu installiert haben, wird dies als Standard-Parser verwendet und es wird ein fehlender <body>-Tag für Sie eingefügt. BeautifulSoup 3 kann das auslassen.

Ich fordere Sie dringend auf, anstatt den Rückfall zu entfernen, und halten mit BeautifulSoup Version 4 nur. Version 3 wurde vor Jahren eingestellt und enthält nicht behobene Fehler. BeautifulSoup 4 bietet auch zusätzliche Funktionen, die Sie verwenden möchten.

BeautifulSoup ist reines Python und kann leicht in eine virtuelle Umgebung auf jeder von Python unterstützten Plattform installiert werden. Sie sind nicht gebunden an das System-Paket hier geliefert.

Auf Debian Squeezy zum Beispiel würden Sie mit BeautifulSoup 3.1.0, und sogar die BeautifulSoup developers do not want you to use it! stecken bleiben. Ihr Problem mit findAll stammt fast sicher aus der Verwendung dieser Version.

+0

Nun, meine Absicht war es, bs4 zu verwenden. Aber die Sache ist, squeezy hat nur bs3 und ich brauche es auch dort zu arbeiten. Aber warum funktioniert findAll nicht, wenn es auf bs3 zurückgreift? Nun, wenn ich bs3 benutze. – Andrius

+0

@Antrius: Ich war dabei, dies auf Ihre Frage zu posten: Was ist die vollständige Traceback der Ausnahme für 'findAll()' geworfen? Sind Sie sicher, dass Sie dort die richtige Ausnahmebedingung kopiert haben (wie für 'find_all')? –

+0

Ich kopiere genau den Fehler, den ich bekomme, wenn ich findAll verwende – Andrius

Verwandte Themen