【问题标题】:How to continue after receiving None response from xml parse收到来自 xml 解析的无响应后如何继续
【发布时间】:2016-05-17 22:31:27
【问题描述】:

我正在使用带有 Bottlenose 的 API 并使用 BeautifulSoup 解析 xml 响应来查找来自亚马逊的产品价格。 我有一个代码迭代的预定义产品列表。 这是我的代码:

import bottlenose as BN
import lxml
from bs4 import BeautifulSoup

i = 0
amazon = BN.Amazon('myid','mysecretkey','myassoctag',Region='UK',MaxQPS=0.9)
list = open('list.txt', 'r')

print "Number", "New Price:","Used Price:"

for line in list:
    i = i + 1
    listclean = line.strip()
    response = amazon.ItemLookup(ItemId=listclean, ResponseGroup="Large")

    soup = BeautifulSoup(response, "xml")

    usedprice=soup.LowestUsedPrice.Amount.string
    newprice=soup.LowestNewPrice.Amount.string
    print i , newprice, usedprice

这很好用,并且会遍历我的亚马逊产品列表,直到找到对该组标签没有任何价值的产品,like no new/used price.

Python 会在什么时候抛出这个响应:

AttributeError: 'NoneType' object has no attribute 'Amount'

这是有道理的,因为 BS 没有找到我搜索的标签/字符串。从我想要实现的目标来看,没有价值是完全可以的,但是代码此时崩溃并且不会继续。

我试过了:

if soup.LowestNewPrice.Amount != None:
    newprice=soup.LowestNewPrice.Amount.string
else:
    continue

也试过了:

newprice=0
if soup.LowestNewPrice.Amount != 0:
    newprice=soup.LowestNewPrice.Amount.string
else:
    continue

收到 nonetype 值返回后,我不知道如何继续。不确定问题根本在于语言还是我正在使用的库。

【问题讨论】:

    标签: python xml beautifulsoup


    【解决方案1】:

    你可以使用异常处理:

    try:
        # operation which causes AttributeError
    except AttributeError:
        continue
    

    try 块中的代码将被执行,如果引发 AttributeError,执行将立即进入 except 块(这将导致循环中的下一个项目运行)。如果没有引发错误,代码将愉快地跳过 except 块。


    如果您只想将缺失值设置为零并打印,您可以这样做

    try: newprice=soup.LowestNewPrice.Amount.string
    except AttributeError: newprice=0
    
    try: usedprice=soup.LowestUsedPrice.Amount.string
    except AttributeError: usedprice=0
    
    print i , newprice, usedprice
    

    【讨论】:

    • 这行得通,并且允许代码继续。但是,代码将完全跳过整个循环,因此如果没有使用过的价格,它也会跳过查找新价格。理想情况下,如果有一个“无”响应,我想要的是将调用的值设置为零。有没有办法在例外情况下做到这一点?
    • 澄清一下,我刚试过这个。 try: newprice=soup.LowestNewPrice.Amount.string except AttributeError: newprice=0 continue 如果返回 None 类型,这将继续程序,但它会跳过整个 for 循环迭代并移动到我列表中的下一项。
    • @AstroDavid 我在答案中添加了解决如何将值设置为零并继续的问题。请注意,continue 表达式意味着移动到下一个循环索引,因此在这种情况下您不想使用它。有关异常处理的更多信息,请参阅the python documentation
    • 哦,太好了,我从异常中删除了continue,现在它可以工作了。太好了,非常感谢。
    【解决方案2】:

    与None比较的正确方法是is None,而不是== Noneis not None,而不是!= None

    其次,您还需要检查soup.LowestNewPrice 是否为None,而不是Amount,即:

    if soup.LowestNewPrice is not None:
        ... read soup.LowestNewPrice.Amount
    

    【讨论】:

    • 将行更改为:if soup.LowestNewPrice.Amount is not None: newprice = soup.LowestNewPrice.Amount 仍然会抛出 Nonetype 响应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 2012-02-05
    • 1970-01-01
    • 2016-10-21
    • 2019-10-17
    • 2011-04-30
    相关资源
    最近更新 更多