BeautifulSoup - TypeError: 'NoneType'对象不可调用
我需要让我的代码能够在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
如果我改成:
p = soup.body.div.findAll('p')
那么我就会得到这个错误:
p = soup.body.div.findAll('p')
TypeError: 'NoneType' object is not callable
错误更新
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
无论哪种方法,在我的Ubuntu上用python2.7和bs4都能正常工作,但在squeezy上却不行。难道在这些版本之间还有我看不见/不知道的其他区别,导致了这个错误吗?
2 个回答
我知道这是一篇六年前的帖子,但我还是想发出来,以防有人遇到类似的问题。
看起来在第9行应该是一个格式化字符串,添加了f之后,它似乎工作得很好。
import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
product_all_pages = []
for i in range(1,15):
response = requests.get(f"https://www.bol.com/nl/s/?page={i}&searchtext=hand+sanitizer&view=list")
content = response.content
parser = BeautifulSoup(content, 'html.parser')
body = parser.body
producten = body.find_all(class_="product-item--row js_item_root")
product_all_pages.extend(producten)
len(product_all_pages)
price = float(product_all_pages[1].meta.get('content'))
productname = product_all_pages[1].find(class_="product-title--inline").a.getText()
print(price)
print(productname)
productlijst = []
for item in product_all_pages:
if item.find(class_="product-prices").getText() == '\nNiet leverbaar\n':
price = None
else:
price = float(item.meta['content'])
product = item.find(class_="product-title--inline").a.getText()
productlijst.append([product, price])
print(productlijst[:3])
df = pd.DataFrame(productlijst, columns=["Product", "price"])
print(df.shape)
df["price"].describe()
你现在使用的是BeautifulSoup 3,但却在用BeautifulSoup 4的写法。
你的备用方案出了问题:
try:
from bs4 import BeautifulSoup
except ImportError:
from BeautifulSoup import BeautifulSoup
如果你想用3或4版本,建议你坚持使用3版本的写法:
p = soup.body.div.findAll('p')
因为在BeautifulSoup 3中,find_all
这个方法是不存在的,所以它会被当作标签搜索来处理。而你的HTML中没有find_all
这个标签,所以返回的结果是None
,接着你又试图去调用它。
接下来,BeautifulSoup 3使用的解析器对破损或不完整的HTML的反应会有所不同。如果你在Ubuntu上安装了lxml
,那么它会被用作默认的解析器,并且会为你插入缺失的<body>
标签。而BeautifulSoup 3可能就不会插入这个标签。
我强烈建议你去掉备用方案,只使用BeautifulSoup 4 即可。3版本早就停止更新了,而且里面还有一些未修复的bug。BeautifulSoup 4还提供了你可能想用的额外功能。
BeautifulSoup是纯Python写的,可以很容易地安装到任何支持Python的平台上的虚拟环境里。你不需要依赖系统自带的包。
比如在Debian Squeezy上,你只能用BeautifulSoup 3.1.0,甚至连BeautifulSoup的开发者也不希望你使用它!。你在使用findAll
时遇到的问题几乎肯定是因为用到了这个版本。