BeautifulSoup - TypeError:'NoneType'对象不可调用

And*_*ius 12 python beautifulsoup backwards-compatibility

我需要使我的代码向后兼容python2.6和BeautifulSoup 3.我的代码是使用python2.7编写的,在这种情况下使用BS4.但是当我尝试在squeezy服务器上运行它时,我得到了这个错误(它有python2.6和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
Run Code Online (Sandbox Code Playgroud)

如果我改为:

   p = soup.body.div.findAll('p')
Run Code Online (Sandbox Code Playgroud)

然后我收到这个错误:

p = soup.body.div.findAll('p')
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)

抛出错误的更新

  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
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,这两种方法都可以在我的Ubuntu上运行python2.7和bs4,但不能用于squeezy.那些我没有看到/知道的版本之间是否有任何其他差异并给我这个错误?

Mar*_*ers 22

您正在使用BeautifulSoup 3,但正在使用BeautifulSoup 4语法.

你的后备是错误的:

try:
    from bs4 import BeautifulSoup
except ImportError:
    from BeautifulSoup import BeautifulSoup
Run Code Online (Sandbox Code Playgroud)

如果要使用版本3或4,请坚持使用版本3语法:

p = soup.body.div.findAll('p')
Run Code Online (Sandbox Code Playgroud)

因为find_all它不是BeautifulSoup 3中的有效方法,所以它被解释为标签搜索.find_all您的HTML中没有标记,因此None会返回,然后您尝试调用.

接下来,BeautifulSoup 3使用的解析器将对已损坏或不完整的HTML做出不同的响应.如果您已lxml在Ubuntu上安装,那么它将被用作默认解析器,并且它将<body>为您插入缺少的标记.BeautifulSoup 3可能会把它留下来.

我强烈建议你,而不是删除回退,并坚持使用BeautifulSoup版本4 .版本3已在几年前停止使用,并包含未修复的错误.BeautifulSoup 4还提供了您可能想要使用的其他功能.

BeautifulSoup是纯Python,可以在Python支持的任何平台上轻松安装到虚拟环境中.您没有绑定系统提供的包.

例如,在Debian Squeezy上,你会遇到BeautifulSoup 3.1.0,甚至BeautifulSoup开发人员都不希望你使用它!.您的问题findAll几乎肯定源于使用该版本.