Astro David February 2016

How to continue after receiving None response from xml parse

I am finding prices of products from Amazon using their API with Bottlenose and parsing the xml response with BeautifulSoup. I have a predefined list of products that the code iterates through. This is my code:

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

This works fine and will run through my list of amazon products until it gets to a product which doesn't have any value for that set of tags, like no new/used price.

At which Python will throw up this response:

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

Which makes sense as there is no tags/string found by BS that I searched for. Having no value is perfectly fine from what I'm trying to achieve, however the code collapses at this point and will not continue.

I have tried:

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

and also tried:

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

I am at a loss for how to continue after receiving the nonetype value return. Unsure whether the problem lies fundamentally in the language or in the libraries I'm using.

Answers


Zbynek Vyskovsky - kvr000 February 2016

The correct way of comparing with None is is None, not == None or is not None, not != None.

Secondly, you also need to check soup.LowestNewPrice for None, not the Amount, i.e.:

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


Matthew February 2016

You can use exception handling:

try:
    # operation which causes AttributeError
except AttributeError:
    continue

The code in the try block will be executed and if an AttributeError is raised, the execution will immediately drop into the except block (which will cause the next item in the loop to be ran). If no error is raised, the code will happily skip the except block.


If you just wish to set the missing values to zero and print, you can do

try: newprice=soup.LowestNewPrice.Amount.string
except AttributeError: newprice=0

try: usedprice=soup.LowestUsedPrice.Amount.string
except AttributeError: usedprice=0

print i , newprice, usedprice

Post Status

Asked in February 2016
Viewed 2,339 times
Voted 7
Answered 2 times

Search




Leave an answer