2016-02-08 2 views
1

Я нахожу цены продуктов Amazon, используя их API с Bottlenose и анализируя xml-ответ с помощью BeautifulSoup. У меня есть предопределенный список продуктов, через которые выполняется итерация кода. Это мой код:Как продолжить после получения Нет ответа от xml parse

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 

Это прекрасно работает и будет работать через мой список Amazon продуктов, пока он не попадает в продукт, который не имеет никакого значения для этого набора тегов, 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. Непонятно, лежит ли проблема в основном на языке или в библиотеках, которые я использую.

ответ

2

Вы можете использовать обработку исключений:

try: 
    # operation which causes AttributeError 
except AttributeError: 
    continue 

Код в блоке Ьгу будет выполняться и если атрибут AttributeError будет поднят, выполнение сразу же попадет в блок 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 
+0

Это работает и позволит продолжить код. Однако код полностью пропустит весь цикл, поэтому, если нет никакой цены, он также пропустит поиск новой цены. В идеале, что бы я хотел, это если есть ответ «Нет», это означает, что значение, которое нужно просто установить равным нулю. Есть ли способ сделать это с исключениями? –

+0

Чтобы уточнить, я просто попробовал это. 'try: newprice = soup.LowestNewPrice.Amount.string except AttributeError: newprice = 0 continue' Это будет продолжаться программа, если не будет возвращен тип None, но она пропустит всю итерацию цикла for и переместится к следующему элементу в моем списке. –

+0

@AstroDavid Я добавил к ответу, чтобы узнать, как вы можете просто установить значения, равные нулю, и продолжить. Обратите внимание, что выражение 'continue' означает переход к следующему индексу цикла, поэтому вы не хотите использовать его в этом случае. Подробнее об обработке исключений см. [Документация на python] (https://docs.python.org/2/tutorial/errors.html#handling-exceptions). – Matthew

0

Правильный способ сравнения с None: is None, а не == None или is not None, а не != None.

Во-вторых, необходимо также проверить soup.LowestNewPrice на None, а не Amount, а именно:

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

Изменение строки быть: 'если soup.LowestNewPrice.Amount не является None: newprice = soup.LowestNewPrice.Amount' все еще выдает ответ Nonetype. –

Смежные вопросы