web-dev-qa-db-fra.com

BeautifulSoup - TypeError: l'objet 'NoneType' n'est pas appelable

J'ai besoin de rendre mon code rétrocompatible avec python2.6 et BeautifulSoup 3. Mon code a été écrit en utilisant python2.7 et dans ce cas en utilisant BS4. Mais quand j'essaye de l'exécuter sur le serveur squeezy, j'obtiens cette erreur (il a python2.6 et bs3):

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

Si je change pour:

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

alors j'obtiens cette erreur:

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

Mise à jour de l'erreur levée

  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

Quoi qu'il en soit, les deux approches fonctionnent sur mon Ubuntu avec python2.7 et bs4, mais pas sur Squeezy. Y a-t-il une autre différence entre ces versions que je ne vois/ne connais pas et qui me donne cette erreur?

12
Andrius

Vous utilisez BeautifulSoup 3, mais utilisez la syntaxe BeautifulSoup 4.

Votre solution de repli est en cause ici:

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

Si vous souhaitez utiliser la version 3 ou 4, respectez la syntaxe de la version 3:

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

parce que find_all n'est pas une méthode valide dans BeautifulSoup 3, elle est donc interprétée à la place comme une recherche de balise. Il n'y a pas de balise find_all Dans votre code HTML, donc None est renvoyé, que vous essayez ensuite d'appeler.

Ensuite, le analyseur utilisé par BeautifulSoup 3 répondra différemment au HTML cassé ou incomplet. Si vous avez lxml installé sur Ubuntu, alors il sera utilisé comme analyseur par défaut, et il insérera pour vous une balise <body> Manquante. BeautifulSoup 3 peut laisser cela de côté.

Je vous exhorte fortement à la place - supprimer la solution de rechange, et restez avec BeautifulSoup version 4 seulement. La version 3 a été arrêtée il y a des années et contient des bogues non corrigés. BeautifulSoup 4 offre également des fonctionnalités supplémentaires que vous voudrez peut-être utiliser.

BeautifulSoup est pur Python et facilement installé dans un environnement virtuel sur n'importe quelle plate-forme prise en charge par Python. Vous n'êtes pas lié à le package fourni par le système ici.

Sur Debian Squeezy par exemple, vous seriez bloqué avec BeautifulSoup 3.1.0, et même le les développeurs de BeautifulSoup ne veulent pas que vous l'utilisiez! . Votre problème avec findAll découle presque certainement de l'utilisation de cette version.

21
Martijn Pieters