class AmazonScraper(object): def __init__(self, access_key, secret_key, associate_tag, *args, **kwargs): self.api = AmazonAPI(access_key, secret_key, associate_tag, *args, **kwargs) def reviews(self, ItemId=None, URL=None): return Reviews(self, ItemId, URL) def review(self, Id=None, URL=None): return Review(self, Id, URL) def lookup(self, URL=None, **kwargs): if URL: kwargs['ItemId'] = extract_asin(URL) result = self.api.lookup(**kwargs) if isinstance(result, (list, tuple)): result = [Product(p) for p in result] else: result = Product(result) return result def similarity_lookup(self, **kwargs): for p in self.api.similarity_lookup(**kwargs): yield Product(p) def browse_node_lookup(self, **kwargs): return self.api.browse_node_lookup(**kwargs) def search(self, **kwargs): for p in self.api.search(**kwargs): yield Product(p) def search_n(self, n, **kwargs): for p in self.api.search_n(n, **kwargs): yield Product(p)
class AmazonProductProxy: def __init__(self, force_own_api=False): self.root = os.path.join(app.config['APP_ROOT'], "amws") self.profile = app.config['PROFILE'] aws_list_cred = self.get_aws_cred_from_file() if force_own_api: self.amazon = AmazonAPI(*aws_list_cred, Region='ES') else: if self.profile == BaseConfig.DEVELOPMENT_PROFILE: self.amazon = AmazonAPI(*aws_list_cred, Region='ES') else: self.amazon = ProductionAmazonAPI(*aws_list_cred, Region='ES') def search_products(self, query): product_res = self.extract_products( self.amazon.search(Keywords=query, SearchIndex='All', Availability="Available")) return product_res def search_by_asin(self, asin_list): return self.extract_products(self.amazon.lookup(ItemId=",".join(asin_list))) def create_cart(self, offer_id, quantity=1): item_dict = {'offer_id': offer_id, 'quantity': quantity} return self.amazon.cart_create(item_dict) def extract_products(self, products): product_res = [] try: for i, product in enumerate(products): # print "{0}. '{1}'".format(i, product.title) product_res.append(product) except Exception, e: return product_res return product_res
class Amazon: def __init__(self): self.amazon = AmazonAPI('AKIAJTMXQEFQVV7SEF5Q', 'CwNQ/cKQNXckNMhfb7oQ0KTmBoaJNPqSFqzKtubf', 'fbhackcom0d-21', region='UK') def search_for(self, text, top=3): try: products = self.amazon.search(Keywords=text, SearchIndex='All') top_products = [] product_titles = {} for product in products: if product.title is not None and product.price_and_currency is not None: title = product.title # if len(title) > 50: # title = title[:50] + "..." product_titles[product.offer_url] = title top_products.append({ 'offer_url': product.offer_url, 'name': product.title, 'image': product.medium_image_url, 'price': product.price_and_currency[0], 'currency': product.price_and_currency[1], }) top -= 1 if top == 0: break return top_products except: return []
def app_results(query): amazon = AmazonAPI(AWS_KEY, SECRET_KEY, ASSOC_TAG) products = amazon.search(Keywords=query, SearchIndex='All') if referrer == 'dashboard': return render_template("amazon_bottlenose2.html", products = products) else: form = AddProductForm() return render_template("amazon_bottlenose_add.html", products = products, form=form)
def app_results(query): amazon = AmazonAPI(AWS_KEY, SECRET_KEY, ASSOC_TAG) products = amazon.search(Keywords=query, SearchIndex='All') if referrer == 'dashboard': return render_template("amazon_bottlenose2.html", products=products) else: form = AddProductForm() return render_template("amazon_bottlenose_add.html", products=products, form=form)
def get_products(keyword): amazon = AmazonAPI(config['access_key'], config['secret_key'], config['associate_tag']) products = amazon.search(Keywords=keyword, SearchIndex='Books') html_list = [] for book in products: # probably limits itself to 50 books html = '''<div class='product-box'><a target="_blank" href="{}"><img src="{}" width="120" height="160" alt="No Img Available"></a><div class="product-title"><h3>{}</h3><p class="product-price">{} {}<br></p></div></div>'''.format( book.detail_page_url, book.large_image_url, book.title, book.price_and_currency[1], book.price_and_currency[0]) html_list.append(html) return ''.join(html_list[:10])
def getTopProductIDs(keywords="camera", searchIndex='Electronics'): AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG = \ getAmazomConfidentialKeys() amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) products = amazon.search(Keywords=keywords, SearchIndex=searchIndex) productIDs = [] for i, product in enumerate(products): productIDs.append(product.asin) return productIDs
def amazon_strips(): amazon = AmazonAPI('AKIAJLW4JVOUA6L62PKQ', 'z0+px3hgEbAR5zqTjSJL70k+JyiS87ps4qEbgA7g', 'insulinfirst-20') prod = amazon.search(Keywords='diabetes blood test strips', SearchIndex='All') rows_logged = 0 for i in prod: product = Product() # product manufacturer prod_manufacturerer = i.publisher product.product_manufacturer = prod_manufacturerer # description of product / Product Name prod_name = i.title product.product_name = prod_name # Price of Product prod_price = i.price_and_currency[0] product.product_price = prod_price # Image of product image = i.medium_image_url product.product_image = image # offer url url = i.offer_url product.product_url = url website = 'Amazon' product.product_dealer = website prod_type = 'Test Strips' product.product_type = prod_type prod_description = '' product.product_description = prod_description try: quantity = re.findall(r"[-+]?\d*\.\d+|\d+", prod_name)[-1] pps = format(float(prod_price) / float(quantity), '.2f') if float(pps) > 2: pps = 1000 product.product_price_per_strip = pps except IndexError: pass rows_logged += 1 db.session.add(product) db.session.commit() print("logged {} rows".format(rows_logged))
def lookup_item_by_keyword(self): """ Returns all results of items given by amazon's search for the supplied keyword :param keyword: the keyword to search by :return: """ amazon = AmazonAPI(secrets.AMAZON_ACCESS_KEY, secrets.AMAZON_SECRET_KEY, secrets.AMAZON_ASSOC_TAG) products = amazon.search( Keywords=self.keyword, SearchIndex='Apparel', MaxQPS=0.9 ) # might have to remove Sort='salesrank' sort since it grabs tons of different products return products
class ProductSearcher(object): def __init__(self, product_name): self.product_name = product_name keys = pandas.read_csv('accessKeys.csv').iloc[0] self.amazon = AmazonAPI(keys['access_key'], keys['access_secret'], 837361066829, region=REGION) def search_product_details(self, product_name=None): product_name = product_name if product_name is not None \ else self.product_name products = self.amazon.search(Keywords=product_name, SearchIndex='All') for product in products: print('product_title={}'.format(product.title)) print('price={}'.format(product.price_and_currency))
def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK") assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords="Kindle", SearchIndex="All") currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = "GBP" in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though")
def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK") assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though")
def run(): b = books() amazon = AmazonAPI(settings.AMZ, settings.AMZSCRT, settings.AMZID) query = amazon.search(Keywords='free kindle books', SearchIndex = 'KindleStore') for i in query: #new = books.objects.get(id=i.asin) b = books() #if book exists update the price and the update timestamp try: q = books.objects.get(id=i.asin) #if len(new) > 0: if i.price_and_currency[0] != None: q.price = i.price_and_currency[0] q.save() except: b.id=(i.asin) b.title = (i.title) b.description = (i.editorial_review) b.image = (i.large_image_url) b.author = (i.author) b.number_pages = (i.pages) b.publisher = (i.publisher) b.price = 'Free' b.url = (i.offer_url) b.reviews = (i.reviews[1]) b.slug = create_slug(b) b.save()
class AmazonScraper(object): def __init__(self, access_key, secret_key, associate_tag, *args, **kwargs): self.api = AmazonAPI(access_key, secret_key, associate_tag, *args, **kwargs) def reviews(self, ItemId=None, URL=None): return Reviews(self, ItemId, URL) def review(self, Id=None, URL=None): return Review(self, Id, URL) def reviewer(self, url): return Reviewer(url) def lookup(self, URL=None, **kwargs): if URL: kwargs['ItemId'] = extract_asin(URL) result = self.api.lookup(**kwargs) if isinstance(result, (list, tuple)): result = [Product(p) for p in result] else: result = Product(result) return result def similarity_lookup(self, **kwargs): for p in self.api.similarity_lookup(**kwargs): yield Product(p) def browse_node_lookup(self, **kwargs): return self.api.browse_node_lookup(**kwargs) def search(self, **kwargs): for p in self.api.search(**kwargs): yield Product(p) def search_n(self, n, **kwargs): for p in self.api.search_n(n, **kwargs): yield Product(p)
def getTop5Books(queryTerm): # AWSACCESSKEYID, AWSSECRETKEY, ASSOCIATETAG are declared as environment varialbes while creating the Lambda function AWSAccessKeyId = os.environ.get("AWSACCESSKEYID") AWSSecretKey = os.environ.get("AWSSECRETKEY") associateTag = os.environ.get("ASSOCIATETAG") dataOfAllBooks = [] api = AmazonAPI(AWSAccessKeyId , AWSSecretKey , associateTag) try: books = api.search(Keywords = queryTerm, SearchIndex = 'Books', salesrank = 'Bestselling') incrementor = 0 num_of_books = 1 for _, book in enumerate(books): if num_of_books <= 5: book_price = book.price_and_currency[0] # skip the book if it is free (they could be promotional stuff) if book_price and book.pages and int(book.pages) >= 50: node = book.browse_nodes[0] category = node.ancestor.name if (category == 'Books'): continue else: if not (is_valid_category(category)): category = node.ancestor.ancestor.name if (is_valid_category(category)): dataOfAllBooks = get_details(dataOfAllBooks, book) incrementor += 1 num_of_books += 1 else: dataOfAllBooks = get_details(dataOfAllBooks, book) incrementor += 1 num_of_books += 1 else: break return dataOfAllBooks except: message = {'contentType': 'PlainText', 'content': """Sorry, no such technical book on Amazon. Please try something else. Ex: suggest me a java book"""} return message
def run(): b = books() amazon = AmazonAPI(settings.AMZ, settings.AMZSCRT, settings.AMZID) query = amazon.search(Keywords='free kindle books', SearchIndex='KindleStore') for i in query: #new = books.objects.get(id=i.asin) b = books() #if book exists update the price and the update timestamp try: q = books.objects.get(id=i.asin) #if len(new) > 0: if i.price_and_currency[0] != None: q.price = i.price_and_currency[0] q.save() except: b.id = (i.asin) b.title = (i.title) b.description = (i.editorial_review) b.image = (i.large_image_url) b.author = (i.author) b.number_pages = (i.pages) b.publisher = (i.publisher) b.price = 'Free' b.url = (i.offer_url) b.reviews = (i.reviews[1]) b.slug = create_slug(b) b.save()
# set/create results dir output_dir = 'final_results/' # create dir if does not exist if not os.path.exists(output_dir): os.makedirs(output_dir) else: # empty the directory if already exists for file in os.listdir(output_dir): file_path = os.path.join(output_dir, file) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as e: print(e) amazon = AmazonAPI("AKIAIQ4EUAQUFXLIBKYA", "z4REKu6NbtgRQlvJc1Dvb2EfMjx/ycfiUUMZLqAN", "mobilea0f740b-20") products = amazon.search(Keywords="black leather jacket", SearchIndex='All') for i, product in enumerate(products): name = "{0}. '{1}': ${2}".format(i, product.title, product.list_price[0]) print name # get image try: urllib.urlretrieve(product.large_image_url, os.path.join(output_dir, name + ".png")) except: print "Could not retrieve image"
import re import requests import bs4 as bs import urllib # cgitb.enable() # form = cgi.FieldStorage() # keyword = form.getvalue('Amazon') access_key = 'AKIAJ5KTDL536GDNI57Q' secret_key = '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' assoc_tag = 'ibafeva-20' userSearchKeyword = input("Search Keyword: ") keyword = userSearchKeyword amazon = AmazonAPI(access_key,secret_key, assoc_tag) products = amazon.search(Keywords=keyword, SearchIndex='All') headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', } for i, product in enumerate(products): print("{0}. '{1}'".format(product.title, product.price_and_currency[0]))
class TestAmazonApi(TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B007HCCNJU") assert_true('Kindle' in product.title) assert_equals(product.ean, '0814916017775') assert_equals(product.large_image_url, 'http://ecx.images-amazon.com/images/I/41VZlVs8agL.jpg') assert_equals(product.get_attribute('Publisher'), 'Amazon') assert_equals( product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), { 'ItemDimensions.Width': '650', 'ItemDimensions.Height': '130' }) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') def test_batch_lookup(self): """Test Batch Product Lookup. Tests that a batch product lookup request returns multiple results. """ asins = [ 'B0051QVESA', 'B005DOK8NW', 'B005890G8Y', 'B0051VVOB2', 'B005890G8O' ] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), 5) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n(1, Keywords='kindle', SearchIndex='All') assert_equals(len(products), 1) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK") assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId="B0051QVF7A") assert_equals(len(products), 10) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId="B0051QVF7A") for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False)
class Amazon(object): def __init__(self): try: self.connection = AmazonAPI( settings.AMAZON_ACCESS_KEY, settings.AMAZON_SECRET_KEY, settings.AMAZON_ASSOCIATE_TAG ) logger.info(u'Established Amazon API connection') except: self.connection = None logger.error(traceback.format_exc()) logger.error(u'Failed to establish Amazon API connection') self.total_count = 0 def get_review_count(self, title, url, has_review, review_url): if not has_review: return 0 try: response = requests.get(review_url) soup = BeautifulSoup(response.content, 'html.parser') count = soup.find(string=re.compile('[0-9,]+ customer reviews')) count = int(count.split()[0].replace(',', '')) logger.info( u'Review count for Amazon item {} from url {} is {}'.format( title, url, count ) ) return count except AttributeError: logger.warning( u'Review count for Amazon item {} from url {} not foun' 'd'.format(title, url) ) return 0 except: logger.error(traceback.format_exc()) return 0 def get_image_list(self, result): image_list = [] for url in [str(image.LargeImage.URL) for image in result.images]: response = requests.get(url) image = Image.open(BytesIO(response.content)) height, width = image.size if height >= 500 and width >= 500: image_list.append(url) logger.info( u'Got {} images for Amazon item {}'.format( len(image_list), result.title ) ) return json.dumps(image_list) def parse_result(self, result, search_obj): url = '/'.join(result.offer_url.split('/')[:-1]) title = result.title feature_list = json.dumps(result.features) image_list = self.get_image_list(result) price = result.price_and_currency[0] or result.list_price[0] or 0 manufacturer = result.manufacturer mpn = result.mpn review_count = self.get_review_count(title, url, *result.reviews) item = { 'search': search_obj, 'url': url, 'title': title, 'feature_list': feature_list, 'image_list': image_list, 'price': price, 'manufacturer': manufacturer, 'mpn': mpn, 'review_count': review_count, } message = 'Parsed Amazon item:\n' for key, value in item.items(): message += '{}: {}\n'.format(key.upper(), value) logger.info(message.strip()) return item def search(self, search_obj): try: results = self.connection.search( Keywords=search_obj.query, SearchIndex='All' ) results = list(reversed(list(results))) logger.info( u'Got {} search results from Amazon API for query {}'.format( len(results), search_obj.query ) ) except: results = [] logger.error(traceback.format_exc()) logger.warning( u'Got 0 search results from Amazon API for query {}'.format( search_obj.query ) ) search_obj.date_searched = timezone.now() search_obj.save() count = 0 for result in results: if count > settings.MAX_AMAZON_ITEM_COUNT_PER_SEARCH: logger.info( u'Reached maximum Amazon item count per search limit' ) break result = self.parse_result(result, search_obj) item_obj = AmazonItem(**result) if item_obj.is_valid(): try: item_obj.save() logger.info( u'Saved amazon item: {}'.format(item_obj.title) ) count += 1 except: logger.error(traceback.format_exc()) logger.warning( u'Failed to save amazon item: {}'.format( item_obj.title ) ) logger.info( u'Saved {} amazon items for query {}'.format( count, search_obj.query ) ) self.total_count += count
class TestAmazonApi(unittest.TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, CacheReader=cache_reader, CacheWriter=cache_writer, MaxQPS=0.5 ) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B00I15SB16") assert_true('Kindle' in product.title) assert_equals(product.ean, '0848719039726') assert_equals( product.large_image_url, 'http://ecx.images-amazon.com/images/I/51XGerXeYeL.jpg' ) assert_equals( product.get_attribute('Publisher'), 'Amazon' ) assert_equals(product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), {'ItemDimensions.Width': '469', 'ItemDimensions.Height': '40'}) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') def test_lookup_nonexistent_asin(self): """Test Product Lookup with a nonexistent ASIN. Tests that a product lookup for a nonexistent ASIN raises AsinNotFound. """ assert_raises(AsinNotFound, self.amazon.lookup, ItemId="ABCD1234") def test_bulk_lookup(self): """Test Baulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_lookup_bulk(self): """Test Bulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_lookup_bulk_empty(self): """Test Bulk Product Lookup With No Results. Tests that a bulk product lookup request with no results returns an empty list. """ asins = ['not-an-asin', 'als-not-an-asin'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(type(products), list) assert_equals(len(products), 0) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n( 1, Keywords='kindle', SearchIndex='All' ) assert_equals(len(products), 1) def test_search_no_results(self): """Test Product Search with no results. Tests that a product search with that returns no results throws a SearchException. """ products = self.amazon.search(Title='no-such-thing-on-amazon', SearchIndex='Automotive') assert_raises(SearchException, (x for x in products).next) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG ) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK" ) assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId=TEST_ASIN) assert_true(len(products) > 5) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId=TEST_ASIN) for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False) def test_obscure_date(self): """Test Obscure Date Formats Test a product with an obscure date format """ product = self.amazon.lookup(ItemId="0933635869") assert_equals(product.publication_date.year, 1992) assert_equals(product.publication_date.month, 5) assert_true(isinstance(product.publication_date, datetime.date)) def test_single_creator(self): """Test a product with a single creator """ product = self.amazon.lookup(ItemId="B00005NZJA") creators = dict(product.creators) assert_equals(creators[u"Jonathan Davis"], u"Narrator") assert_equals(len(creators.values()), 2) def test_multiple_creators(self): """Test a product with multiple creators """ product = self.amazon.lookup(ItemId="B007V8RQC4") creators = dict(product.creators) assert_equals(creators[u"John Gregory Betancourt"], u"Editor") assert_equals(creators[u"Colin Azariah-Kribbs"], u"Editor") assert_equals(len(creators.values()), 2) def test_no_creators(self): """Test a product with no creators """ product = self.amazon.lookup(ItemId="8420658537") assert_false(product.creators) def test_single_editorial_review(self): product = self.amazon.lookup(ItemId="1930846258") expected = u'In the title piece, Alan Turing' assert_equals(product.editorial_reviews[0][:len(expected)], expected) assert_equals(product.editorial_review, product.editorial_reviews[0]) assert_equals(len(product.editorial_reviews), 1) def test_multiple_editorial_reviews(self): product = self.amazon.lookup(ItemId="B000FBJCJE") expected = u'Only once in a great' assert_equals(product.editorial_reviews[0][:len(expected)], expected) expected = u'From the opening line' assert_equals(product.editorial_reviews[1][:len(expected)], expected) # duplicate data, amazon user data is great... expected = u'Only once in a great' assert_equals(product.editorial_reviews[2][:len(expected)], expected) assert_equals(len(product.editorial_reviews), 3) def test_languages_english(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="1930846258") assert_true('english' in product.languages) assert_equals(len(product.languages), 1) def test_languages_spanish(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="8420658537") assert_true('spanish' in product.languages) assert_equals(len(product.languages), 1) def test_region(self): amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) assert_equals(amazon.region, 'US') # old 'region' parameter amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region='UK') assert_equals(amazon.region, 'UK') # kwargs method amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, Region='UK') assert_equals(amazon.region, 'UK') def test_kwargs(self): amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, MaxQPS=0.7) def test_images(self): """Test images property Test that the images property has a value when using the Images ResponseGroup """ product = self.amazon.lookup(ResponseGroup='Images', ItemId='B00TSVVNQC') assert_equals(type(product.images), list) assert_equals(len(product.images), 7)
from amazon.api import AmazonAPI # Amazon Credentials AMAZON_ACCESS_KEY = "AKIAJHD6XRGK5NFMCPNA" AMAZON_SECRET_KEY = "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" AMAZON_ASSOC_TAG = "srvani92-20" amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) products = amazon.search(Keywords='Room Essentials Magazine File Holder', SearchIndex='All') for i, product in enumerate(products): print("{0}. '{1}'".format(i, product.price_and_currency), product.title)
class TestAmazonApi(TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B0051QVF7A") assert_equals(product.title, 'Kindle, Wi-Fi, 6" E Ink Display - for international shipment') assert_equals(product.price_and_currency, (109.0, 'USD')) assert_equals(product.ean, '0814916014354') assert_equals(product.large_image_url, 'http://ecx.images-amazon.com/images/I/411H%2B731ZzL.jpg') assert_equals(product.get_attribute('Publisher'), 'Amazon Digital Services, Inc') assert_equals(product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), {'ItemDimensions.Width': '450', 'ItemDimensions.Height': '34'}) def test_batch_lookup(self): """Test Batch Product Lookup. Tests that a batch product lookup request returns multiple results. """ asins = ['B0051QVESA', 'B005DOK8NW', 'B005890G8Y', 'B0051VVOB2', 'B005890G8O'] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), 5) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n(1, Keywords='kindle', SearchIndex='All') assert_equals(len(products), 1) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK") assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though")
class AZ(object): def __init__(self): init_logging() self.logger = logging.getLogger(__name__) self.logger.info("Amazon object initialized") with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "az_config.yml"), "r") as fh: settings = yaml.load(fh) self.db = Mysql(settings['db_config']) self.access_key = settings['access_key_id'] self.secret_key = settings['secret_key_id'] self.associate_tag = settings['associate_tag'] self.default_weight = settings['default_weight'] self.az_price = None self.az_asin = None self.az_sales_rank = None self.az_url = None self.az_match = None self.amazon = AmazonAPI(self.access_key, self.secret_key, self.associate_tag) def destroy(self): self.logger.info("Database connection closed...") self.db.exit() self.logger.info("Amazon object destroyed") def find_best_match(self, title, cat='All'): # TODO: consider using cat='Blended' for default """ :param title: string containing the source site product title :param cat: string containing the category for searchindex on amazon :return: product dict with price, weight, sales_rank, offer_url and T if match occurred on title search, K if match occurred on keyword search, N if no match occurred. """ self._find_by_title(title, cat) if self.product['az_price'] != 0: self.product['az_match'] = 'T' if self.product['az_price'] == 0: self._find_by_key(title, cat) if self.product['az_price'] != 0: self.product['az_match'] = 'K' if self.product['az_price'] == 0: # we didn't find any match so clean remaining attrs (self.product['az_sales_rank'], self.product['az_match'], self.product['az_url']) = (0, 'N', '') self._get_attrs() #return self.az_price, self.az_weight, self.az_sales_rank, self.az_match, self.az_url, self.az_asin # consider returning a status flag def _find_by_title(self, title, cat): lowest = 0.0 try: products = self.amazon.search(Title=title, SearchIndex=cat) for i, p in enumerate(products): price = p.price_and_currency[0] if lowest == 0.0: lowest = price self.product['asin'] = p.asin elif price < lowest: lowest = price self.product['asin'] = p.asin except Exception as e: self.logger.warn("%s had no match in amazon" % title) self.product['az_price'] = lowest def _find_by_key(self, title, cat): lowest = 0.0 try: products = self.amazon.search(Keywords=title, SearchIndex=cat) for i, p in enumerate(products): price = p.price_and_currency[0] if lowest == 0.0: lowest = price self.product['asin'] = p.asin elif price < lowest: lowest = price self.product['asin'] = p.asin except Exception as e: self.logger.warn("%s had no match in amazon" % title) self.product['az_price'] = lowest def _get_attrs(self): (r, w, u, i) = (None, None, None, None) if self.product.get('asin', None) is not None: try: p = self.amazon.lookup(ItemId=self.product['asin']) r = int(p.sales_rank) i = p.images[0].LargeImage.URL.text w = p.get_attribute('ItemDimensions.Weight') u = p.offer_url self._get_meta_rate(p.reviews[1]) except: pass if r is None: r = 0 if i is None: i = '' if w is None: w = self.product['az_weight'] # this should not be in hundreth-pounds else: w = float(w)*0.01 # its coming from amazon in hundreth-pounds seemingly else: # there was no product found. (r, w, u, i) = (0, 0, '', '') self.product['az_sales_rank'] = r self.product['az_weight'] = w self.product['az_url'] = u self.product['img'] = i def _get_weight(self): w = None if self.product['asin'] is not None: try: p = self.amazon.lookup(ItemId=self.product['asin']) w = p.get_attribute('ItemDimensions.Weight') except: pass if w is None: w = self.product['az_weight'] else: w = float(w)*0.01 # its coming from amazon in hundreth-pounds seemingly else: w = 0 return w def _get_meta_rate(self, url): rank_page = get_page(url, 1) if rank_page[0].find(string=re.compile(r'There are no customer reviews for this item')): self.product['num_reviews'] = 0 self.product['avg_review'] = 0 else: try: rating = rank_page[0].find("span", {"class":"asinReviewsSummary"}).img.attrs['title'] self.product['num_reviews'] = rating except: self.product['num_reviews'] = 0 try: reviews = rank_page[0].find(string=re.compile(r'\d+ customer reviews')) # TODO: strip out text self.product['avg_review'] = reviews except: self.product['avg_review'] = 0 def _init_prod_dict(self): self.product = {} self.product['az_weight'] = self.default_weight self.product['az_price'] = 0.0 self.product['avg_review'] = 0 self.product['num_reviews'] = 0 def match_products(self): """ Method looks for unmatched products in match_cw. When it finds a new product, attempts to match with amazon product. When successful, will then update amazon product row and match_cw row :return: """ new_prods = self._get_unmatched_products() for k in new_prods: self._init_prod_dict() self.product['name'] = new_prods[k]['title'] self.find_best_match(self.product['name']) if self.product.get('asin', None) is None: continue self._persist_product(self.product, k) def _get_unmatched_products(self): """ Finds all the empty products in match_cw. Empty is a null element for az_pk_id in a product row, which means it was written by another product find and had no match. :return: dict {wal_pk_id: {title, match_pk_id}} """ new_products = {} with self.db.con.cursor() as cursor: select_sql = "SELECT pk_id, wal_pk_id " \ "FROM match_cw " \ "WHERE az_pk_id is NULL" try: cursor.execute(select_sql, ()) ret = cursor.fetchall() new_products = {e['wal_pk_id']: {'match_pk_id': e['pk_id']} for e in ret} except Exception as e: self.logger.exception(e) select_sql = "SELECT title " \ "FROM walmart_product " \ "WHERE pk_id=%s" for e in new_products: cursor.execute(select_sql, (e)) ret = cursor.fetchone() if ret is not None: new_products[e]['title'] = ret['title'] return new_products def _persist_match(self, az_pk_id, wal_pk_id): """ should actually write az_pk_id to existing product row.... :param az_pk_id: this is the az_pk_id to write to match_cw row :wal_pk_id: this is the wal_pk_id that identifies the row to update :return: """ if az_pk_id is None: return with self.db.con.cursor() as cursor: select_sql = "SELECT pk_id " \ "FROM match_cw " \ "WHERE wal_pk_id=%s" cursor.execute(select_sql, (wal_pk_id)) ret = cursor.fetchone() if ret is None: self.logger.warn("There was a match issue with wal_pk_id %s" % az_pk_id) return # there was no row for that amazon product update_sql = "UPDATE match_cw " \ "SET az_pk_id=%s, " \ "last_update=now() " \ "WHERE pk_id=%s" cursor.execute(update_sql, (az_pk_id, ret['pk_id'])) self.db.con.commit() def _update_match(self, match): """ TODO: this needs to update things like roi, etc. possibly pull it out... :param match: :return: """ if match is None: return with self.db.con.cursor() as cursor: select_sql = "SELECT pk_id " \ "FROM match_cw " \ "WHERE az_pk_id=%s" cursor.execute(select_sql, (match['pk_id'])) ret = cursor.fetchone() if ret is None: self.logger.warn("There was a match issue with az_pk_id %s" % match['pk_id']) return # there was no row for that amazon product update_sql = "UPDATE match_cw " \ "SET az_pk_id=%s, wal_pk_id=%s, " \ "net=%s, roi=%s, match_score=%s, " \ "match_meth=%s, last_update=now() " \ "WHERE pk_id=%s" cursor.execute(update_sql, (match['az_pk_id'], match['wal_pk_id'], match['net'], match['roi'], match['match_score'], match['match_meth'], match['pk_id'])) self.db.con.commit() def _persist_product(self, product, wal_pk_id): """ This method will insert or update a row for the product in the az table as well as call to update the corresponding row in match_cw with the az_pk_id. Expects to find az_product with asin. If a match_cw_id is passed in product dict, then there is a row in match_cw that needs to be updated with the product az_pk_id. :param product: dict with values to insert/update in az_product. :param wal_pk_id: pk_id from original search on no amazon info in row :return: """ if 'name' not in product: self.logger.warn("Attempt to persist empty product!") return with self.db.con.cursor() as cursor: (az_id, az_price) = (0, 0.0) # declare as a wider scope var to track through entire method select_sql = "SELECT pk_id, price " \ "FROM az_product " \ "WHERE asin=%s" cursor.execute(select_sql, (product['asin'])) ret = cursor.fetchone() # no row in az product table with that asin, so insert row if ret is None: insert_sql = "INSERT INTO az_product " \ "(asin, avg_rate, img, num_reviews, " \ "price, sales_rank, shipping_cost, " \ "title, upc, url, weight, " \ "last_read, last_changed) " \ "VALUES " \ "(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, now(), now())" try: cursor.execute(insert_sql, (product['asin'], product['avg_review'], product['img'], product['num_reviews'], product.get('az_price', 0.0), product['az_sales_rank'], product.get('shipping_cost', 1.00), # no shipping cost or upc product['name'], product.get('upc',''), product['az_url'], product['az_weight'])) self.db.con.commit() # now go back and get the pk_id of the new row just inserted select_sql = "SELECT pk_id, price " \ "FROM az_product " \ "WHERE asin=%s" cursor.execute(select_sql, (product['asin'])) ret = cursor.fetchone() az_id = ret.get('pk_id', None) if az_id is None: self.logger.warn("Error in inserting new az_product.") return az_price = ret.get('price', 0.0) except: self.logger.exception('Failed to insert new az product: %s.' % product['asin']) return # otherwise, product exists - if price is changed update product elif product['az_price'] != ret['price']: update_sql = "UPDATE az_product " \ "SET asin=%s, avg_rate=%s, " \ "img=%s, num_reviews=%s, " \ "price=%s, sales_rank=%s, " \ "shipping_cost=%s, last_read=now(), " \ "last_changed=now(), title=%s, " \ "url=%s, weight=%s " \ "WHERE pk_id=%s" try: cursor.execute(update_sql, (product['az_price'], product['name'], product['az_url'], product['img'], ret['pk_id'])) self.db.con.commit() except: self.logger.exception('Failed to update az product: %s.' % product['asin']) # otherwise, product exists but price is unchanged so simply refresh timestamp else: update_sql = "UPDATE az_product " \ "SET last_read=now()" \ "WHERE pk_id=%s" cursor.execute(update_sql, (ret['pk_id'])) self.db.con.commit() # now need to place match in match_cw if product.get('az_match'): self._persist_match(ret['pk_id'], wal_pk_id)
class TestAmazonApi(TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B007HCCNJU") assert_true('Kindle' in product.title) assert_equals(product.ean, '0814916017775') assert_equals( product.large_image_url, 'http://ecx.images-amazon.com/images/I/41VZlVs8agL.jpg' ) assert_equals( product.get_attribute('Publisher'), 'Amazon' ) assert_equals(product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), {'ItemDimensions.Width': '650', 'ItemDimensions.Height': '130'}) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') def test_batch_lookup(self): """Test Batch Product Lookup. Tests that a batch product lookup request returns multiple results. """ asins = ['B0051QVESA', 'B005DOK8NW', 'B005890G8Y', 'B0051VVOB2', 'B005890G8O'] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), 5) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n( 1, Keywords='kindle', SearchIndex='All' ) assert_equals(len(products), 1) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG ) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK" ) assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId="B0051QVF7A") assert_equals(len(products), 10) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId="B0051QVF7A") for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False)
MYSQL_DB_PORT = ENV['MYSQL_DB_PORT'] or die("DB port not specified") MYSQL_DB = ENV['MYSQL_DB'] or die("DB not specified") cnx = mysql.connector.connect(user=MYSQL_DB_USER, password=MYSQL_DB_PASSWORD, host=MYSQL_DB_HOST, port=MYSQL_DB_PORT, database=MYSQL_DB) query = ("SELECT json from watchlist") cursor = cnx.cursor() cursor.execute(query) for (json) in cursor: print(json) AMAZON_AFFILATE_ID = ENV['AMAZON_AFFILATE_ID'] AMAZON_SECRET_KEY = ENV['AMAZON_SECRET_KEY'] AMAZON_ACCESS_KEY = ENV['AMAZON_ACCESS_KEY'] cursor.close() cnx.close() amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_AFFILATE_ID, region="IN") products = amazon.search(Keywords='dyson', SearchIndex='All') for i, product in enumerate(products): print(product.parsed_response.ItemAttributes.ListPrice.FormattedPrice)
class AMZNMain: # Login information and opening statements def __init__(self): # Welcome the user print( "\n**************************************************************\n" + "Welcome to the Amazon-Discounts Command Line Interface (v1.0)!\n" + "Below are prompted instructions for your login information.\n" + "For the case that you might have made a mistake, please press\n" + "CTRL+C to start over. If anything breaks, please send a request\n" + "to: https://github.com/cristiangonzales/Amazon-Discounts/issues.\n" + "Thank you!\n" + "**************************************************************\n") # Prompt for information to log into the account key = input("Please enter your AWS key here: ") secret_key = input("Please enter your AWS secret key here: ") asso_tag = input("Please enter your AWS associate tag here: ") region = input("Please enter your region here (i.e. US, FR, CN, UK," + "IN, CA, DE, JP, IT): ") self.amazon = AmazonAPI(aws_key=str(key), aws_secret=str(secret_key), aws_associate_tag=str(asso_tag), region=str(region).upper()) # Initialize our cart to be pointing at nothing, at first self.cart = None # Ask for the discount rate, the output file, and the option discount = int( input("\nPlease enter the discount you would like to query for\n" + "(enter a whole number 1-99): ")) # Check to see if it is actually an integer between 0-99 if (not isinstance(discount, int)) or discount < 1 or discount > 99: raise Exception( "Sorry, you did not enter a number between 1 and 99!") # Prompt the user for an output text file to write to outputFile = open("../../amazon-discounts.log", 'w') errorLog = open("../../failed-proxies.log", 'w') # Optional argument as determined by the user optionArg = input( "Please enter a type of item you wish to search for!\n" + "If you do not have a particular type of item,\n" + "then enter a number so that we can search Goldbox\n" + "for you and look for discounts there. Also, if you\n" + "wish to search for a single item, you may enter the\n" + "keywords 'item lookup': ") # For this option argument, if it is not a keyword, then scrape Amazon's Goldbox page, # and if not, then search for that item through the API. Though, if a user inputs "item # lookup", then simply make a single list with that ASIN number appended. if optionArg.isdigit(): asinList = AMZNGoldboxFind().scrape_goldbox(int(optionArg)) elif optionArg.replace(" ", "").upper() == "ITEMLOOKUP": singleItem = str( input("\nPlease enter in the ASIN number of the item you\n" + "wish to look for here: ")) asinList = [] asinList.append(singleItem) else: asinList = self.item_search(optionArg, discount) # Cart count used in the final conditional. We will do a comparison. If the counter is 0, then we will # use the cart_create method to create the cart, and if not, then we will use the cart_add method # to add to the existing cart. cartCount = 0 # Iterate through the entire ASIN list to do the appropriate comparisons to see if that ASIN meets our # discount, and then we will write to the file for asin in asinList: # Here, we do an item lookup and get the title, current price, and offer url for this ASIN # In the case that the item is too low, then it will simply continue onto the next iteration # of the loop. try: titlePriceURLList = self.item_lookup(str(asin)) except: continue title = titlePriceURLList[0] currentPrice = titlePriceURLList[1] offerUrl = titlePriceURLList[2] # Interfacing with the CamelCamelCamel scraper, passing in the ASIN number and attempting to # get the average, lowest, and highest price for that ASIN number. Should it be the case that # the average price is none, then we will check for it and see if it is accordingly. camelPriceHistory = AMZNCamelScraper().AccessASIN(asin) averagePrice = camelPriceHistory.get_average_price() lowestPrice = camelPriceHistory.get_lowest_price() highestPrice = camelPriceHistory.get_highest_price() # Conditional here to see if the average price is NoneType. If it is, it did not connect so we # should move onto the next ASIN (continue to the next iteration) if averagePrice is None: errorLog.write("Proxy tunneling failed at " + str(camelPriceHistory.get_proxy())) continue # Now, we check the discount, sending the average price, the current price, and the user's discount if self.check_discount(discount, averagePrice, currentPrice): percentageOff = self.calculate_percentage_off( averagePrice, currentPrice) outputFile.write("Title: " + title + "\nAmazon price: " + str(currentPrice) + "\nCamelCamelCamel average price: " + str(averagePrice) + "\nCamelCamelCamel highest price: " + str(highestPrice) + "\nCamelCamelCamel lowest price: " + str(lowestPrice) + "\nPercentage off from average: " + str(percentageOff) + "\nURL: " + offerUrl + "\n\n") # Logic to add this item to our cart (if it is our first time adding to the cart, then create # the cart item, and if it isn't the first time, then we simply add to the existiing cart if cartCount == 0: self.cart_create(str(asin)) cartCount = cartCount + 1 else: self.cart_add(str(asin)) # Write the purchase URL to the logging file if cartCount != 0: outputFile.write("Click here to add all items to your cart: " + str(self.cart.purchase_url)) else: outputFile.write( "Sorry, we did not find any items to add to your cart!") # Once we are done, close the output file and error log, and say goodbye. errorLog.close() outputFile.close() print( "\nThank you for using the Amazon-Discounts CLI! Exiting now...\n") """ Item search in the case that the user requests a query. :param keywords: The keyword that the user requests in the case that they want to query Amazon, as a string. :param pctoff: The percent off that the user requests, as an integer. :return: A list of ASIN values, as strings """ def item_search(self, keywords, pctoff): try: result = self.amazon.search(SearchIndex='All', Keywords=keywords, MinPercentageOff=pctoff) asinList = [] for i, product in enumerate(result): asinList.append(product.asin) # logging.debug(product.asin) return asinList except Exception as e: raise AmazonException(str(e)) """ Item lookup for the specified ASIN number. :param ASIN: The ASIN number, as a string. :return amznList [title, price, URL] as an array. Title is a string, price as a float, and URL as a string """ def item_lookup(self, ASIN): try: # Initialize the Amazon list amznList = [] # Lookup the result based on ASIN result = self.amazon.lookup(ItemId=ASIN) # Append the appropriate values amznList.append(result.title) # logging.debug(result.title) amznList.append(float(result.formatted_price.replace('$', ''))) # logging.debug(result.formatted_price.replace('$', '')) amznList.append(result.offer_url) # logging.debug(result.offer_url) # Return the list to the caller return amznList except Exception as e: raise AmazonException(str(e)) """ Check to see if this is a discount, as wanted by the user. :return bool (dependent on if this is a discount that we want or not). """ def check_discount(self, discount, averagePrice, price): return (100 - (float(price) / float(averagePrice) * 100)) >= float(discount) """ calculate the percentage off the current Amazon price is from the average price. :return int """ def calculate_percentage_off(self, averagePrice, price): return int(100 - (float(price) / float(averagePrice) * 100)) """ Once we do all the appropriate comparisons, we will create the cart and add this item to the user's cart (this method is only used on the first ASIN). :param ASIN: The ASIN number of the discounted item :return void """ def cart_create(self, ASIN): try: product = self.amazon.lookup(ItemId=ASIN) item = {'offer_id': product.offer_id, 'quantity': 1} self.cart = self.amazon.cart_create(item) except Exception as e: raise AmazonException(str(e)) """ This method is instantiated if we have already created the cart, and we wish to add to it. :param ASIN: The ASIN number of the discounted item :return void """ def cart_add(self, ASIN): try: product = self.amazon.lookup(ItemId=ASIN) item = {'offer_id': product.offer_id, 'quantity': 1} self.amazon.cart_add(item, self.cart.cart_id, self.cart.hmac) except Exception as e: raise AmazonException(str(e))
Makeup_parents.append(browse_id[0].id) for n in child: if n.id not in Makeup_parents: Makeup_subdir[n.name] = n.id except: print(browse_id[0].name, 'doesnt have child', browse_id[0].id) if browse_id[0].id not in Makeup_parents: Makeup_subdir[browse_id[0].name] = browse_id[0].id Makeup_subdir = dict() Makeup_parents = [] for k, v in Makeup_dir.items(): Browse_node_mining(v) products = amazon.search(SearchIndex='Beauty', BrowseNode=11058361) # eyeshadow node= 11058361 product = [r for r in products] def get_soup(url): if 'amazon.com' not in url: url = 'https://www.amazon.com' + url nap_time_sec = 1 logging.debug( 'Script is going to sleep for {} (Amazon throttling). ZZZzzzZZZzz.'. format(nap_time_sec)) sleep(nap_time_sec) header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36' }
def lambda_handler(event, context): logger.debug('input to lambda: {}'.format(event) ) try: session_attributes = event['sessionAttributes']['data'] decoded = base64.b64decode(session_attributes) data = json.loads(decoded) title = data[0]['title'] AWSAccessKeyId = 'AKIAJCMZHQR6KKOAH4SQ' AWSSecretKey = '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' associateTag = '200b3-21' api = AmazonAPI(AWSAccessKeyId , AWSSecretKey , associateTag) decoded = base64.b64decode(session_attributes) data = json.loads(decoded) print data[0] book_authors = [] book_authors = str(data[0]['authors']).split(",") print 'authors after split:', book_authors length = book_authors.__len__() books_list = range(length) books_url = [] books_image = [] for incrementor in range(length): book_titles = "" book_url = "" book_image_url = "" number = 0 print 'Author: ', book_authors[incrementor] books = api.search(Author = book_authors[incrementor], SearchIndex = 'Books', salesrank = 'Bestselling') for _, book in enumerate(books): if number == 0: book_titles = book.title[:78] + '..' if book_titles == title: continue else: #book_titles = book.title book_url = book.detail_page_url.split('?',1)[0] book_image_url = book.large_image_url number += 1 else: break print 'other books by {} are {}'.format(book_authors[incrementor], book_titles) books_list[incrementor] = book_titles books_url.append(book_url) books_image.append(book_image_url) print 'titles: ', books_list print 'urls: ', books_url print 'images: ', books_image content = "" for len in range(books_list.__len__()): content = content + " " + str(books_list[len]) message = {'contentType': 'PlainText', 'content': """The author(s) for {} is {}. Other books by the same author(s): {}""".format(data[0]['title'], data[0]['authors'], content)} print books_list output = elicit_intent(message, create_response_cards(books_list, books_url, books_image)) logger.debug('output to lex: {}'.format(output)) return output except: message = {'contentType': 'PlainText', 'content': """Please choose a book first. How about these:"""} return elicit(message)
from amazon.api import AmazonAPI import json from datetime import date with open('amazon.config') as configfile: config = json.load(configfile) amazon = AmazonAPI(str(config['AWS_ACCESS_KEY_ID']), str(config['AWS_SECRET_ACCESS_KEY']), str(config['AWS_ASSOCIATE_TAG']), region='US') results = amazon.search(Author='ben aaronovitch', Sort='-publication_date', SearchIndex='Books') for item in results: if item.publication_date >= date.today(): if item.edition != "Reprint" and item.binding == "Hardcover": print item.title print item.publication_date print item.offer_url print item.authors print item.isbn else: break
class TestAmazonApi(unittest.TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI( _AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, CacheReader=cache_reader, CacheWriter=cache_writer, MaxQPS=0.5 ) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_true('Kindle' in product.title) assert_equals(product.ean, '0848719083774') assert_equals( product.large_image_url, 'https://images-na.ssl-images-amazon.com/images/I/51hrdzXLUHL.jpg' ) assert_equals( product.get_attribute('Publisher'), 'Amazon' ) assert_equals(product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), {'ItemDimensions.Width': '450', 'ItemDimensions.Height': '36'}) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup_nonexistent_asin(self): """Test Product Lookup with a nonexistent ASIN. Tests that a product lookup for a nonexistent ASIN raises AsinNotFound. """ assert_raises(AsinNotFound, self.amazon.lookup, ItemId="ABCD1234") @flaky(max_runs=3, rerun_filter=delay_rerun) def test_bulk_lookup(self): """Test Baulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup_bulk(self): """Test Bulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup_bulk_empty(self): """Test Bulk Product Lookup With No Results. Tests that a bulk product lookup request with no results returns an empty list. """ asins = ['not-an-asin', 'als-not-an-asin'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(type(products), list) assert_equals(len(products), 0) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n( 1, Keywords='kindle', SearchIndex='All' ) assert_equals(len(products), 1) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_iterate_pages(self): products = self.amazon.search(Keywords='internet of things oreilly', SearchIndex='Books') assert_false(products.is_last_page) for product in products: pass assert_true(products.is_last_page) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_no_results(self): """Test Product Search with no results. Tests that a product search with that returns no results throws a SearchException. """ products = self.amazon.search(Title='no-such-thing-on-amazon', SearchIndex='Automotive') assert_raises(SearchException, next, (x for x in products)) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI( _AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG ) assert_equals(amazon.api.Region, "US") @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI( _AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, region="UK" ) assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") @flaky(max_runs=3, rerun_filter=delay_rerun) def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId=TEST_ASIN) assert_true(len(products) > 5) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId=TEST_ASIN) for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_obscure_date(self): """Test Obscure Date Formats Test a product with an obscure date format """ product = self.amazon.lookup(ItemId="0933635869") assert_equals(product.publication_date.year, 1992) assert_equals(product.publication_date.month, 5) assert_true(isinstance(product.publication_date, datetime.date)) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_single_creator(self): """Test a product with a single creator """ product = self.amazon.lookup(ItemId="B00005NZJA") creators = dict(product.creators) assert_equals(creators[u"Jonathan Davis"], u"Narrator") assert_equals(len(creators.values()), 2) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_multiple_creators(self): """Test a product with multiple creators """ product = self.amazon.lookup(ItemId="B007V8RQC4") creators = dict(product.creators) assert_equals(creators[u"John Gregory Betancourt"], u"Editor") assert_equals(creators[u"Colin Azariah-Kribbs"], u"Editor") assert_equals(len(creators.values()), 2) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_no_creators(self): """Test a product with no creators """ product = self.amazon.lookup(ItemId="8420658537") assert_false(product.creators) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_single_editorial_review(self): product = self.amazon.lookup(ItemId="1930846258") expected = u'In the title piece, Alan Turing' assert_equals(product.editorial_reviews[0][:len(expected)], expected) assert_equals(product.editorial_review, product.editorial_reviews[0]) assert_equals(len(product.editorial_reviews), 1) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_multiple_editorial_reviews(self): product = self.amazon.lookup(ItemId="B01HQA6EOC") expected = u'<p>Introducing an instant classic—master storyteller' assert_equals(product.editorial_reviews[0][:len(expected)], expected) expected = u'<strong>An Amazon Best Book of February 2017:</strong>' assert_equals(product.editorial_reviews[1][:len(expected)], expected) # duplicate data, amazon user data is great... expected = u'<p>Introducing an instant classic—master storyteller' assert_equals(product.editorial_reviews[2][:len(expected)], expected) assert_equals(len(product.editorial_reviews), 3) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_languages_english(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="1930846258") assert_true('english' in product.languages) assert_equals(len(product.languages), 1) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_languages_spanish(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="8420658537") assert_true('spanish' in product.languages) assert_equals(len(product.languages), 1) def test_region(self): amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG) assert_equals(amazon.region, 'US') # old 'region' parameter amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, region='UK') assert_equals(amazon.region, 'UK') # kwargs method amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, Region='UK') assert_equals(amazon.region, 'UK') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_is_adult(self): product = self.amazon.lookup(ItemId="B01E7P9LEE") assert_true(product.is_adult is not None) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_product_group(self): product = self.amazon.lookup(ItemId="B01LXM0S25") assert_equals(product.product_group, 'DVD') product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.product_group, 'Digital Music Album') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_product_type_name(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.product_type_name, 'DOWNLOADABLE_MUSIC_ALBUM') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_formatted_price(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.formatted_price, '$12.49') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_price_and_currency(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") price, currency = product.price_and_currency assert_equals(price, Decimal('12.49')) assert_equals(currency, 'USD') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_list_price(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") price, currency = product.list_price assert_equals(price, Decimal('12.49')) assert_equals(currency, 'USD') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_running_time(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.running_time, '3567') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_studio(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.studio, 'Atlantic Records UK') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_is_preorder(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.is_preorder , None) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_detail_page_url(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_true(product.detail_page_url.startswith('https://www.amazon.com/%C3%B7-Deluxe-Ed-Sheeran/dp/B01NBTSVDN')) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_availability(self): product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_equals(product.availability, 'Usually ships in 24 hours') product = self.amazon.lookup(ItemId="1491914254") # pre-order book assert_equals(product.availability, 'Not yet published') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_availability_type(self): product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_equals(product.availability_type, 'now') product = self.amazon.lookup(ItemId="1491914254") # pre-order book assert_equals(product.availability_type, 'now') product = self.amazon.lookup(ItemId="B00ZV9PXP2") # late availability assert_equals(product.availability_type, 'now') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_availability_min_max_hours(self): product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_equals(product.availability_min_hours, '0') assert_equals(product.availability_max_hours, '0') def test_kwargs(self): amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, MaxQPS=0.7) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_images(self): """Test images property Test that the images property has a value when using the Images ResponseGroup """ product = self.amazon.lookup(ResponseGroup='Images', ItemId='B00TSVVNQC') assert_equals(type(product.images), list) assert_equals(len(product.images), 7)
class AmznBot(object): def __init__(self): # create product dictionary self._prod = None # create slack instance pointer self._slk_instance = None # get config self._cfg = get_config() # get token and amazon API instanc self._tokens = get_toke() try: self._amazon = AmazonAPI(self._tokens['AWSAccessKeyId'], self._tokens['AWSSecretKey'], self._tokens['AWSAssociateTag']) except KeyError: sys.exit('Check Amazon tokens and try again :(') def search(self): results = self._get_search() for i, product in enumerate(results): print '{0}: \'{1}\''.format(product.formatted_price, product.title) def items(self): # get results results = self._get_items() # iterate over resulsts for i, product in enumerate(results): print '{0} - {1}'.format(i, self._format_msg(product)) def report(self, items=None, search=None, period=1200, debug=None): # check period try: sleep_time = int(period) except ValueError: sys.exit('--period argument must be a number') # check args if not items and not search: sys.exit('Must provide at least one argument: items | search') # reporter list reporters = [] if items: # append item reporter reporters.append(self._get_items) if search: # append search reporter reporters.append(self._get_search) # get slack instance try: # get channel self._slk_chnl = self._cfg['channel'] # get slack instance slk_toke = self._tokens['SLACK_API_TOKEN'] self._slk_instance = slackclient.SlackClient(slk_toke) except KeyError: sys.exit('Check Slack token and/or config file :(') # initialize product dictionary self._prod = self._init_prod_dict(reporters) # report while True: try: # sleep period minutes if debug: print 'Sleeping {0} seconds'.format(sleep_time) self.items() else: # post to slack self._update_slack(reporters) time.sleep(sleep_time) except KeyboardInterrupt: sys.exit('\nShutting Down :)') def _post_slack(self, msg): # send message try: self._slk_instance.api_call('chat.postMessage', as_user='******', channel='#{0}'.format(self._slk_chnl), text=msg) except AttributeError: sys.exit('Slack instance was not initialized') def _format_msg(self, product): return PRODUCT_MSG.format( product.asin, product.formatted_price, product.title, product.sales_rank, product.availability, product.offer_url, ) def _get_search(self): # search items try: return self._amazon.search(Keywords=self._cfg['keywords'], SearchIndex=self._cfg['searchindex']) except KeyError: sys.exit('Make sure config file has \'keywords\' and \ \'searchindex\'') def _get_items(self): # check items try: itemids = self._cfg['itemid'] except KeyError: sys.exit('Make sure config file has \'itemid\'') # get number of groups of 10 or less num_grp = int(math.ceil(len(itemids) / 10.0)) # now create list of item groups for 10 items or less item_ls = [] for i in range(num_grp): item_ls.append(itemids[i * 10:(i + 1) * 10]) # now get results results = [] for itemid_grp in item_ls: # format for request item_id_str = ','.join(itemid_grp) # get products product = self._amazon.lookup(ItemId=item_id_str) # make sure its a list if type(product) is not list: product = [product] # add to results results += product return results def _init_prod_dict(self, reporters): # local dictionary items = {} # loop over reporters for reporter in reporters: # get results results = reporter() # get iniital prices and format start up message starting_msg = STARTUP_MSG.format(time.asctime()) for product in results: # get initial price items[product.asin] = product.formatted_price # create string for initial price starting_msg += self._format_msg(product) # post to slack self._post_slack(starting_msg) # leave return items def _gen_update(self, reporters): # loop over reporters for reporter in reporters: # get results results = reporter() # init slack message string slk_msg = '' # format msg if type(results) is AmazonSearch or list: for product in results: if self._prod[product.asin] != product.formatted_price: # create string for slack message slk_msg += self._format_msg(product) # update product dictionary self._prod[product.asin] = product.formatted_price else: if self._prod[results.asin] != results.formatted_price: # create string for slack message slk_msg += self._format_msg(results) # update product dictionary self._prod[results.asin] = results.formatted_price yield slk_msg def _update_slack(self, reps): # get updates updates = [msg for msg in self._gen_update(reps) if msg is not ''] # any updates, post to slack if any(updates): for slk_msg in updates: # create msg header hdr = 'Update: {0}'.format(time.asctime()) slk_msg = '\n{0} {1} {2}\n{3}'.format('*|', hdr, '|*', slk_msg) # send message self._post_slack(slk_msg)
AMAZON_SECRET_KEY = line amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) if not start: with open('lastNDB', 'rb') as f: for line in f: lastNDB = line.strip() with open('../get_freebase_num/ndb_no_freebase.txt', 'rb') as f: for line in f: (ndb_no, searchTerm) = line.split('|') print ndb_no print searchTerm if start: products = amazon.search(Keywords=searchTerm, SearchIndex='Grocery') knownUnit = None prices = [] units = {} for i, product in enumerate(products): try: if product.price_and_currency[0] is not None: with open('ndb_nos/' + ndb_no + '.txt', 'a') as f: f.write("{0}\t{2}\t{1}\n".format( i, unidecode(product.title), product.price_and_currency[0])) except: pass with open('lastNDB', 'a') as f: f.write(ndb_no + '\n') else:
def getProducts(self, request, format=None): amazon = AmazonAPI(settings.AMAZON_ACCESS_KEY, settings.AMAZON_SECRET_KEY, settings.AMAZON_ASSOC_TAG) data = {'result': []} tags = request.GET.get('tags', '') range = request.GET.get('range', '') for tag in tags.split(','): if range == 'low': print("range", range) products = amazon.search(Keywords='{} shirt'.format(tag), SearchIndex='Apparel', BrowseNode="9056987011", ResponseGroup='Large', Sort='salesrank') nodes = amazon.browse_node_lookup(ResponseGroup='TopSellers', BrowseNodeId='9103696011') for n in nodes: print(n) else: products = amazon.search(Keywords='{} shirt'.format(tag), SearchIndex='Apparel', BrowseNode="9103696011", ResponseGroup='Large') count = 0 for it in products.iterate_pages(): time.sleep(1) for product in products: count += 1 print("Getting product", count, product.asin, product.sales_rank) nodes = [] product_type = 2 if not product.sales_rank: continue if range == 'low' and int(product.sales_rank) > 100000: continue if range == 'high' and product.sales_rank < 100000: continue for node in product.browse_nodes: for n in node.ancestors: nodes.append(n.name) nodes.append(node.name) if node.name == "Women" or "women" in product.title.lower( ) or "woman" in product.title.lower(): product_type = 1 elif node.name == "Men" or "men" in product.title.lower( ) or "man" in product.title.lower(): product_type = 0 if "Novelty" in nodes: pass else: continue data['result'].append({ 'title': product.title, 'sales_rank': product.sales_rank, 'monthly_sales_estimate': monthly_sales_estimate(product.sales_rank), 'asin': product.asin, 'small_image_url': product.large_image_url, 'reviews': product.reviews, 'detail_page_url': product.detail_page_url, 'features': product.features, 'type': product_type }) amazon_products.after_response(data) return data
from amazon.api import AmazonAPI ACCESS_KEY = 'AKIAI3FFIB6W2LW6D36A' SECRET = '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' ASSOC = 'mahmoudatef95-21' bookName = 'clean code' amazon = AmazonAPI(ACCESS_KEY, SECRET, ASSOC) results = amazon.search(Keywords=bookName, SearchIndex="Books") print(results) for item in results: print item.title, item.isbn, item.price_and_currency
class TestAmazonApi(TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B0051QVF7A") assert_equals(product.title, 'Kindle, Wi-Fi, 6" E Ink Display - for international shipment') assert_equals(product.ean, "0814916014354") assert_equals(product.large_image_url, "http://ecx.images-amazon.com/images/I/411H%2B731ZzL.jpg") assert_equals(product.get_attribute("Publisher"), "Amazon Digital Services, Inc") assert_equals( product.get_attributes(["ItemDimensions.Width", "ItemDimensions.Height"]), {"ItemDimensions.Width": "450", "ItemDimensions.Height": "34"}, ) assert_true(len(product.browse_nodes) > 0) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, "eBook Readers") def test_batch_lookup(self): """Test Batch Product Lookup. Tests that a batch product lookup request returns multiple results. """ asins = ["B0051QVESA", "B005DOK8NW", "B005890G8Y", "B0051VVOB2", "B005890G8O"] products = self.amazon.lookup(ItemId=",".join(asins)) assert_equals(len(products), 5) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords="kindle", SearchIndex="All") for product in products: assert_true(hasattr(product, "title")) break else: assert_true(False, "No search results returned.") def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n(1, Keywords="kindle", SearchIndex="All") assert_equals(len(products), 1) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK") assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords="Kindle", SearchIndex="All") currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = "GBP" in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId="B0051QVF7A") assert_equals(len(products), 10) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId="B0051QVF7A") for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, "eBook Readers") assert_equals(bn.is_category_root, False)
class TestAmazonApi(unittest.TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI( _AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, CacheReader=cache_reader, CacheWriter=cache_writer, MaxQPS=0.5 ) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_true('Kindle' in product.title) assert_equals(product.ean, '0848719083774') assert_equals( product.large_image_url, 'https://images-na.ssl-images-amazon.com/images/I/51hrdzXLUHL.jpg' ) assert_equals( product.get_attribute('Publisher'), 'Amazon' ) assert_equals(product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), {'ItemDimensions.Width': '450', 'ItemDimensions.Height': '36'}) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup_nonexistent_asin(self): """Test Product Lookup with a nonexistent ASIN. Tests that a product lookup for a nonexistent ASIN raises AsinNotFound. """ assert_raises(AsinNotFound, self.amazon.lookup, ItemId="ABCD1234") @flaky(max_runs=3, rerun_filter=delay_rerun) def test_bulk_lookup(self): """Test Baulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup_bulk(self): """Test Bulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_lookup_bulk_empty(self): """Test Bulk Product Lookup With No Results. Tests that a bulk product lookup request with no results returns an empty list. """ asins = ['not-an-asin', 'als-not-an-asin'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(type(products), list) assert_equals(len(products), 0) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n( 1, Keywords='kindle', SearchIndex='All' ) assert_equals(len(products), 1) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_iterate_pages(self): products = self.amazon.search(Keywords='internet of things oreilly', SearchIndex='Books') assert_false(products.is_last_page) for product in products: if products.current_page < 8: assert_false(products.is_last_page) else: assert_true(products.is_last_page) assert_true(products.is_last_page) assert_true(products.current_page == 8) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_no_results(self): """Test Product Search with no results. Tests that a product search with that returns no results throws a SearchException. """ products = self.amazon.search(Title='no-such-thing-on-amazon', SearchIndex='Automotive') assert_raises(SearchException, next, (x for x in products)) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI( _AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG ) assert_equals(amazon.api.Region, "US") @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI( _AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, region="UK" ) assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") @flaky(max_runs=3, rerun_filter=delay_rerun) def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId=TEST_ASIN) assert_true(len(products) > 5) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId=TEST_ASIN) for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_obscure_date(self): """Test Obscure Date Formats Test a product with an obscure date format """ product = self.amazon.lookup(ItemId="0933635869") assert_equals(product.publication_date.year, 1992) assert_equals(product.publication_date.month, 5) assert_true(isinstance(product.publication_date, datetime.date)) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_single_creator(self): """Test a product with a single creator """ product = self.amazon.lookup(ItemId="B00005NZJA") creators = dict(product.creators) assert_equals(creators[u"Jonathan Davis"], u"Narrator") assert_equals(len(creators.values()), 2) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_multiple_creators(self): """Test a product with multiple creators """ product = self.amazon.lookup(ItemId="B007V8RQC4") creators = dict(product.creators) assert_equals(creators[u"John Gregory Betancourt"], u"Editor") assert_equals(creators[u"Colin Azariah-Kribbs"], u"Editor") assert_equals(len(creators.values()), 2) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_no_creators(self): """Test a product with no creators """ product = self.amazon.lookup(ItemId="8420658537") assert_false(product.creators) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_single_editorial_review(self): product = self.amazon.lookup(ItemId="1930846258") expected = u'In the title piece, Alan Turing' assert_equals(product.editorial_reviews[0][:len(expected)], expected) assert_equals(product.editorial_review, product.editorial_reviews[0]) assert_equals(len(product.editorial_reviews), 1) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_multiple_editorial_reviews(self): product = self.amazon.lookup(ItemId="B01HQA6EOC") expected = u'<p>Introducing an instant classic—master storyteller' assert_equals(product.editorial_reviews[0][:len(expected)], expected) expected = u'<strong>An Amazon Best Book of February 2017:</strong>' assert_equals(product.editorial_reviews[1][:len(expected)], expected) # duplicate data, amazon user data is great... expected = u'<p>Introducing an instant classic—master storyteller' assert_equals(product.editorial_reviews[2][:len(expected)], expected) assert_equals(len(product.editorial_reviews), 3) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_languages_english(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="1930846258") assert_true('english' in product.languages) assert_equals(len(product.languages), 1) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_languages_spanish(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="8420658537") assert_true('spanish' in product.languages) assert_equals(len(product.languages), 1) def test_region(self): amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG) assert_equals(amazon.region, 'US') # old 'region' parameter amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, region='UK') assert_equals(amazon.region, 'UK') # kwargs method amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, Region='UK') assert_equals(amazon.region, 'UK') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_is_adult(self): product = self.amazon.lookup(ItemId="B01E7P9LEE") assert_true(product.is_adult is not None) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_product_group(self): product = self.amazon.lookup(ItemId="B01LXM0S25") assert_equals(product.product_group, 'DVD') product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.product_group, 'Digital Music Album') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_product_type_name(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.product_type_name, 'DOWNLOADABLE_MUSIC_ALBUM') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_formatted_price(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.formatted_price, '$12.49') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_price_and_currency(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") price, currency = product.price_and_currency assert_equals(price, Decimal('12.49')) assert_equals(currency, 'USD') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_list_price(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") price, currency = product.list_price assert_equals(price, Decimal('12.49')) assert_equals(currency, 'USD') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_running_time(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.running_time, '774') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_studio(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.studio, 'Atlantic Records UK') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_is_preorder(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_equals(product.is_preorder, '1') @flaky(max_runs=3, rerun_filter=delay_rerun) def test_detail_page_url(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") assert_true(product.detail_page_url.startswith('https://www.amazon.com/%C3%B7-Deluxe-Ed-Sheeran/dp/B01NBTSVDN')) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_availability(self): product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_equals(product.availability, 'Usually ships in 24 hours') product = self.amazon.lookup(ItemId="1491914254") # pre-order book assert_equals(product.availability, 'Not yet published') product = self.amazon.lookup(ItemId="B000SML2BQ") # late availability assert_true(product.availability is not None) product = self.amazon.lookup(ItemId="B01LTHP2ZK") # unavailable assert_true(product.availability is None) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_availability_type(self): product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_equals(product.availability_type, 'now') product = self.amazon.lookup(ItemId="1491914254") # pre-order book assert_equals(product.availability_type, 'now') product = self.amazon.lookup(ItemId="B00ZV9PXP2") # late availability assert_equals(product.availability_type, 'now') product = self.amazon.lookup(ItemId="B01LTHP2ZK") # unavailable assert_true(product.availability_type is None) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_availability_min_max_hours(self): product = self.amazon.lookup(ItemId="B00ZV9PXP2") assert_equals(product.availability_min_hours, '0') assert_equals(product.availability_max_hours, '0') def test_kwargs(self): amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, MaxQPS=0.7) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_images(self): """Test images property Test that the images property has a value when using the Images ResponseGroup """ product = self.amazon.lookup(ResponseGroup='Images', ItemId='B00TSVVNQC') assert_equals(type(product.images), list) assert_equals(len(product.images), 7)
class Main(object): """ A class that gives access to this test application """ # The list of products obtained searched_products = list() products = None def __init__(self): self.region_options = bottlenose.api.SERVICE_DOMAINS.keys() # Check if we have credentials stored, if so, load them if os.path.isfile("amazon_credentials.json"): LOGGER.info("Getting Amazon credentials from stored file...") credentials = json.load(open("amazon_credentials.json")) AMAZON_ACCESS_KEY = credentials["amazon_access_key"] AMAZON_SECRET_KEY = credentials["amazon_secret_key"] AMAZON_ASSOC_TAG = credentials["amazon_assoc_tag"] if AMAZON_SECRET_KEY and AMAZON_ACCESS_KEY and AMAZON_ASSOC_TAG: LOGGER.info("Got Amazon credentials!") self.amazon_us = AmazonAPI( str(AMAZON_ACCESS_KEY), str(AMAZON_SECRET_KEY), str(AMAZON_ASSOC_TAG), region="US" ) else: LOGGER.error("Some mandatory Amazon credentials are empty. Aborting...") sys.exit() else: LOGGER.error("Could not find amazon_credentials_file.json file. Aborting...") sys.exit() def search_products_by_brand(self): """ Call the search method of the Amazon API searching for products/sellers of a particular brand """ while True: brand_id = raw_input("Please insert brand to extract product info from -> ") try: if brand_id and isinstance(brand_id, str): row_counter = 1 self.products = self.amazon_us.search(Brand=brand_id, SearchIndex="Automotive") """pages = self.products.iterate_pages() i = 1 for page in pages: for product in page.Items: print "{0}. '{1}'".format(i, product.title) i += 1 sleep(0.9) for i, product in enumerate(self.products): print "{0}. '{1}'".format(i, product.title) sleep(0.9) return""" excel_book = self.create_brand_excel_file(brand_id, "products") index = excel_book.get_active_sheet() sheet = excel_book.get_sheet(index) for i, product in enumerate(self.products): print "{0}. '{1}'".format(i, product.title) product_url = product.offer_url final = product_url.rsplit("/", 1) if product_url: try: # Write a line in excel file sheet.write(row_counter, 0, brand_id) sheet.write(row_counter, 1, product.asin) sheet.write(row_counter, 2, product.editorial_review) sheet.write(row_counter, 3, product.label) sheet.write(row_counter, 4, str(product.list_price)) sheet.write(row_counter, 5, product.manufacturer) sheet.write(row_counter, 6, product.mpn) sheet.write(row_counter, 7, product.offer_url) sheet.write(row_counter, 8, product.part_number) sheet.write(row_counter, 9, str(product.price_and_currency)) sheet.write(row_counter, 10, product.publisher) sheet.write(row_counter, 11, product.sales_rank) sheet.write(row_counter, 12, product.sku) sheet.write(row_counter, 13, product.title) # Get the ASIN if product.item.ASIN: sheet.write(row_counter, 15, str(product.item.ASIN)) else: sheet.write(row_counter, 15, "Unknown") # Get the Images from the Item images_urls = [] if product.large_image_url: images_urls.append(product.large_image_url) try: image_sets = product.item.ImageSets for image_set in image_sets: if image_set.ImageSet.LargeImage.URL: images_urls.append(str(image_set.ImageSet.LargeImage.URL)) images = ", ".join(x for x in images_urls) sheet.write(row_counter, 16, images) except AttributeError as e: print e.message sheet.write(row_counter, 16, "Unknown") # Get the model if product.model: sheet.write(row_counter, 17, str(product.model)) else: sheet.write(row_counter, 17, "Unknown") # Get the publication date if product.publication_date: sheet.write(row_counter, 18, str(product.publication_date)) else: sheet.write(row_counter, 18, "Unknown") # Get the product seller using Scrapy product_file = urllib2.urlopen(product_url).read() hxs = Selector(text=product_file) # Get the seller seller = hxs.xpath('//div[@id="merchant-info"]/a/text()').extract() if seller: sheet.write(row_counter, 14, str(seller[0])) self.searched_products.append(product) else: sheet.write(row_counter, 14, "Unknown") row_counter += 1 # Wait for 2 seconds before making another request sleep(2) except URLError as e: sheet.write(row_counter, 14, "Unknown") print e.reason row_counter += 1 sleep(2) sleep(0.9) excel_book.save(brand_id + ".xls") break else: print "Whoops, looks like there entered a non-valid brand, it should be a text, for instance " '"Wako industries"' except ValueError: print "Whoops, looks like you entered a non-valid brand, must be a valid text, please try again..." def search_products_by_sku(self): print "hey" def search_products_by_seller(self): """ Call the search method of the Amazon API searching for sellers of a particular brand """ while True: seller_id = raw_input("Please insert seller to extract product info from -> ") try: if seller_id and isinstance(seller_id, str): row_counter = 1 self.products = self.amazon_us.search( Keywords=seller_id, Title="Headlights", SearchIndex="Automotive" ) excel_book = self.create_seller_excel_file(seller_id, "products") index = excel_book.get_active_sheet() sheet = excel_book.get_sheet(index) for i, product in enumerate(self.products): print "{0}. '{1}'".format(i, product.title) product_url = product.offer_url final = product_url.rsplit("/", 1) if product_url: # Write a line in excel file sheet.write(row_counter, 0, seller_id) sheet.write(row_counter, 1, product.asin) sheet.write(row_counter, 2, product.editorial_review) sheet.write(row_counter, 3, product.label) sheet.write(row_counter, 4, str(product.list_price)) sheet.write(row_counter, 5, product.manufacturer) sheet.write(row_counter, 6, product.mpn) sheet.write(row_counter, 7, product.offer_url) sheet.write(row_counter, 8, product.part_number) sheet.write(row_counter, 9, str(product.price_and_currency)) sheet.write(row_counter, 10, product.publisher) sheet.write(row_counter, 11, product.sales_rank) sheet.write(row_counter, 12, product.sku) sheet.write(row_counter, 13, product.title) # Get the ASIN if product.item.ASIN: sheet.write(row_counter, 14, str(product.item.ASIN)) else: sheet.write(row_counter, 14, "Unknown") # Get the Images from the Item images_urls = [] if product.large_image_url: images_urls.append(product.large_image_url) try: image_sets = product.item.ImageSets for image_set in image_sets: if image_set.ImageSet.LargeImage.URL: images_urls.append(str(image_set.ImageSet.LargeImage.URL)) images = ", ".join(x for x in images_urls) sheet.write(row_counter, 15, images) except AttributeError as e: print e.message sheet.write(row_counter, 15, "Unknown") # Get the model if product.model: sheet.write(row_counter, 16, str(product.model)) else: sheet.write(row_counter, 16, "Unknown") # Get the publication date if product.publication_date: sheet.write(row_counter, 18, str(product.publication_date)) else: sheet.write(row_counter, 17, "Unknown") row_counter += 1 # Wait for 2 seconds before making another request sleep(2) sleep(0.9) excel_book.save(seller_id + ".xls") break else: print "Whoops, looks like there entered a non-valid brand, it should be a text, for instance " '"Wako industries"' except ValueError: print "Whoops, looks like you entered a non-valid brand, must be a valid text, please try again..." def create_brand_excel_file(self, file_name=None, sheet_name=None): """ A helper method that creates a excel file for products :rtype : Workbook :return: The excel object with the header row inserted """ book = xlwt.Workbook() excel_name = file_name + ".xls" # delete the file if already exists if os.path.isfile(excel_name): os.remove(excel_name) sheet_name = sheet_name sheet = book.add_sheet(sheet_name) col1_name = "Brand" col2_name = "ASIN" col3_name = "Editorial review" col4_name = "Label" col5_name = "List price" col6_name = "Manufacturer" col7_name = "mpn" col8_name = "url" col9_name = "part number" col10_name = "Price and currency" col11_name = "Publisher" col12_name = "Sales rank" col13_name = "SKU" col14_name = "Title" col15name = "Sold by" col16name = "ASIN" col17name = "Images URLs" col18name = "model" col19name = "Publication Date" style = xlwt.XFStyle() # font font = xlwt.Font() font.name = "Arial" font.colour_index = xlwt.Style.colour_map["white"] font.bold = True style.font = font # background color pattern = xlwt.Pattern() pattern.pattern = xlwt.Pattern.SOLID_PATTERN pattern.pattern_fore_colour = xlwt.Style.colour_map["dark_purple"] style.pattern = pattern # borders borders = xlwt.Borders() borders.bottom = xlwt.Borders.THIN style.borders = borders # Write the first row headers sheet.write(0, 0, col1_name, style=style) sheet.write(0, 1, col2_name, style=style) sheet.write(0, 2, col3_name, style=style) sheet.write(0, 3, col4_name, style=style) sheet.write(0, 4, col5_name, style=style) sheet.write(0, 5, col6_name, style=style) sheet.write(0, 6, col7_name, style=style) sheet.write(0, 7, col8_name, style=style) sheet.write(0, 8, col9_name, style=style) sheet.write(0, 9, col10_name, style=style) sheet.write(0, 10, col11_name, style=style) sheet.write(0, 11, col12_name, style=style) sheet.write(0, 12, col13_name, style=style) sheet.write(0, 13, col14_name, style=style) sheet.write(0, 14, col15name, style=style) sheet.write(0, 15, col16name, style=style) sheet.write(0, 16, col17name, style=style) sheet.write(0, 17, col18name, style=style) sheet.write(0, 18, col19name, style=style) book.save(excel_name) return book def create_seller_excel_file(self, file_name=None, sheet_name=None): """ A helper method that creates a excel file for a seller products :rtype : Workbook :return: The excel object with the header row inserted """ book = xlwt.Workbook() excel_name = file_name + ".xls" # delete the file if already exists if os.path.isfile(excel_name): os.remove(excel_name) sheet_name = sheet_name sheet = book.add_sheet(sheet_name) col1_name = "Brand" col2_name = "ASIN" col3_name = "Editorial review" col4_name = "Label" col5_name = "List price" col6_name = "Manufacturer" col7_name = "mpn" col8_name = "url" col9_name = "part number" col10_name = "Price and currency" col11_name = "Publisher" col12_name = "Sales rank" col13_name = "SKU" col14_name = "Title" col15name = "ASIN" col16name = "Images URLs" col17name = "model" col18name = "Publication Date" style = xlwt.XFStyle() # font font = xlwt.Font() font.name = "Arial" font.colour_index = xlwt.Style.colour_map["white"] font.bold = True style.font = font # background color pattern = xlwt.Pattern() pattern.pattern = xlwt.Pattern.SOLID_PATTERN pattern.pattern_fore_colour = xlwt.Style.colour_map["dark_purple"] style.pattern = pattern # borders borders = xlwt.Borders() borders.bottom = xlwt.Borders.THIN style.borders = borders # Write the first row headers sheet.write(0, 0, col1_name, style=style) sheet.write(0, 1, col2_name, style=style) sheet.write(0, 2, col3_name, style=style) sheet.write(0, 3, col4_name, style=style) sheet.write(0, 4, col5_name, style=style) sheet.write(0, 5, col6_name, style=style) sheet.write(0, 6, col7_name, style=style) sheet.write(0, 7, col8_name, style=style) sheet.write(0, 8, col9_name, style=style) sheet.write(0, 9, col10_name, style=style) sheet.write(0, 10, col11_name, style=style) sheet.write(0, 11, col12_name, style=style) sheet.write(0, 12, col13_name, style=style) sheet.write(0, 13, col14_name, style=style) sheet.write(0, 14, col15name, style=style) sheet.write(0, 15, col16name, style=style) sheet.write(0, 16, col17name, style=style) sheet.write(0, 17, col18name, style=style) book.save(excel_name) return book def show_menu(self): """ Creates the menu """ menu_option_search_by_brand = Button("Search by brand", self.search_products_by_brand, 1) menu_option_search_by_sku = Button("Search by SKU or MPN", self.search_products_by_sku, 2) menu_option_search_by_seller = Button("Search by seller", self.search_products_by_seller, 3) menu_option_quit = Button("Quit", self.quit, 0) main_menu_buttons = [ menu_option_search_by_brand, menu_option_search_by_sku, menu_option_search_by_seller, menu_option_quit, ] main_menu = Menu(main_menu_buttons) controller = Controller(main_menu) controller.cycle() def quit(self): """ Displays all the adverts in screen and when done shows the menu again """ print ("Bye, we will miss you :(!") sys.exit()
class TestAmazonApi(TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B007HCCNJU") assert_true('Kindle' in product.title) assert_equals(product.ean, '0814916017775') assert_equals(product.large_image_url, 'http://ecx.images-amazon.com/images/I/41VZlVs8agL.jpg') assert_equals(product.get_attribute('Publisher'), 'Amazon') assert_equals( product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), { 'ItemDimensions.Width': '650', 'ItemDimensions.Height': '130' }) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') def test_batch_lookup(self): """Test Batch Product Lookup. Tests that a batch product lookup request returns multiple results. """ asins = [ 'B00AWH595M', 'B007HCCNJU', 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA' ] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), 5) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n(1, Keywords='kindle', SearchIndex='All') assert_equals(len(products), 1) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK") assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId="B0051QVF7A") assert_true(len(products) > 5) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId="B0051QVF7A") for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False) def test_obscure_date(self): """Test Obscure Date Formats Test a product with an obscure date format """ product = self.amazon.lookup(ItemId="0933635869") assert_equals(product.publication_date.year, 1992) assert_equals(product.publication_date.month, 5) assert_true(isinstance(product.publication_date, datetime.date)) def test_single_creator(self): """Test a product with a single creator """ product = self.amazon.lookup(ItemId="B00005NZJA") creators = dict(product.creators) assert_equals(creators[u"Jonathan Davis"], u"Narrator") assert_equals(len(creators.values()), 1) def test_multiple_creators(self): """Test a product with multiple creators """ product = self.amazon.lookup(ItemId="B007V8RQC4") creators = dict(product.creators) assert_equals(creators[u"John Gregory Betancourt"], u"Editor") assert_equals(creators[u"Colin Azariah-Kribbs"], u"Editor") assert_equals(len(creators.values()), 2) def test_no_creators(self): """Test a product with no creators """ product = self.amazon.lookup(ItemId="8420658537") assert_false(product.creators) def test_single_editorial_review(self): product = self.amazon.lookup(ItemId="1930846258") expected = u'In the title piece, Alan Turing' assert_equals(product.editorial_reviews[0][:len(expected)], expected) assert_equals(product.editorial_review, product.editorial_reviews[0]) assert_equals(len(product.editorial_reviews), 1) def test_multiple_editorial_reviews(self): product = self.amazon.lookup(ItemId="B000FBJCJE") expected = u'Only once in a great' assert_equals(product.editorial_reviews[0][:len(expected)], expected) expected = u'From the opening line' assert_equals(product.editorial_reviews[1][:len(expected)], expected) # duplicate data, amazon user data is great... expected = u'Only once in a great' assert_equals(product.editorial_reviews[2][:len(expected)], expected) assert_equals(len(product.editorial_reviews), 3) def test_languages_english(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="1930846258") assert_true('english' in product.languages) assert_equals(len(product.languages), 1) def test_languages_spanish(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="8420658537") assert_true('spanish' in product.languages) assert_equals(len(product.languages), 1)
from amazon.api import AmazonAPI from SecretConfigs import * amazon = AmazonAPI(SecretConfigs.awsAccessKey(), SecretConfigs.awsSecretKey(), SecretConfigs.awsAssociateTag()) products = amazon.search(Keywords='Orange Zest', SearchIndex='All') for i, product in enumerate(products): print (i, product.title)
from amazon.api import AmazonAPI SALES_RANK = 100 AMAZON_ACCESS_KEY = 'AKIAJ6AHCTMPFVQSP3NA' AMAZON_SECRET_KEY = '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' AMAZON_ASSOC_TAG = '678654738313' asin = 'B00NVDNDUW' amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK") product = amazon.search(asin = asin) product1 = amazon.lookup(ItemId='B00EOE0WKQ')
# 取得した商品情報の利用目的はAmazonのサイトにエンドユーザーを誘導し商品の販売を促進することに限定されている # APIの利用にはAmazonアソシエイト・プログラムへの登録が必要。一定期間売上が発生しないと利用できなくなる場合があるので注意 # 実行方法 # forego run python amazon_product_search.py # 上記のように実行するとforegoがカレントディレクトリに存在する「.env」という名前のファイルから環境変数を読み取ってプログラムにわたす。 # これを実行すると次々とツイートが表示される。キャンセルするには「ctrl-C」 import os from amazon.api import AmazonAPI # pip install python-amazon-simple-product-api # 環境変数から認証情報を取得する。 AMAZON_ACCESS_KEY = os.environ['AMAZON_ACCESS_KEY'] AMAZON_SECRET_KEY = os.environ['AMAZON_SECRET_KEY'] AMAZON_ASSOCIATE_TAG = os.environ['AMAZON_ASSOCIATE_TAG'] # AmazonAPIオブジェクトを作成する。キーワード引数Regionに'JP'を指定し、Amazon.co.jpを選択する。 amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOCIATE_TAG, Region='JP') # search()メソッドでItemSearch操作を使い、商品情報を検索する。 # キーワード引数Keywordsで検索語句を、SearchIndexで検索対象とする商品のカテゴリを指定する。 # SearchIndex='All'はすべてのカテゴリから検索することを意味する。 products = amazon.search(Keywords='kindle', SearchIndex='All') for product in products: # 得られた商品(AmazonProductオブジェクト)について反復する。 print(product.title) # 商品名を表示。 print(product.offer_url) # 商品のURLを表示。 price, currency = product.price_and_currency print(price, currency) # 価格と通貨を表示。
print(data['name']) Name = data['name'] counter = 0 with open( 'C:\\Users\\AshwinAmbal\\Desktop\\SDL Lab\\{0}\\favorite_books_desc.csv' .format(Name), 'r') as f: reader = csv.reader(f, delimiter='|') for row in reader: try: with open( 'C:\\Users\\AshwinAmbal\\Desktop\\SDL Lab\\{0}\\probable_gifts.csv' .format(Name), 'a', newline='') as csvfile: writer = csv.writer(csvfile, delimiter='|') products = amazon.search(Keywords=row[1], SearchIndex='Books') for i, product in enumerate(products): print(product) writer.writerow([product]) counter += 1 break if counter == 3: break except Exception as e: print(e) continue except Exception as e: print(e) continue for data in datastore['friends']['data']:
class TestAmazonApi(TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B007HCCNJU") assert_true('Kindle' in product.title) assert_equals(product.ean, '0814916017775') assert_equals( product.large_image_url, 'http://ecx.images-amazon.com/images/I/41VZlVs8agL.jpg' ) assert_equals( product.get_attribute('Publisher'), 'Amazon' ) assert_equals(product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), {'ItemDimensions.Width': '650', 'ItemDimensions.Height': '130'}) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') def test_batch_lookup(self): """Test Batch Product Lookup. Tests that a batch product lookup request returns multiple results. """ asins = ['B00AWH595M', 'B007HCCNJU', 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), 5) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n( 1, Keywords='kindle', SearchIndex='All' ) assert_equals(len(products), 1) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG ) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK" ) assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId="B0051QVF7A") assert_true(len(products) > 5) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId="B0051QVF7A") for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False) def test_obscure_date(self): """Test Obscure Date Formats Test a product with an obscure date format """ product = self.amazon.lookup(ItemId="0933635869") assert_equals(product.publication_date.year, 1992) assert_equals(product.publication_date.month, 5) assert_true(isinstance(product.publication_date, datetime.date)) def test_single_creator(self): """Test a product with a single creator """ product = self.amazon.lookup(ItemId="B00005NZJA") creators = dict(product.creators) assert_equals(creators[u"Jonathan Davis"], u"Narrator") assert_equals(len(creators.values()), 1) def test_multiple_creators(self): """Test a product with multiple creators """ product = self.amazon.lookup(ItemId="B007V8RQC4") creators = dict(product.creators) assert_equals(creators[u"John Gregory Betancourt"], u"Editor") assert_equals(creators[u"Colin Azariah-Kribbs"], u"Editor") assert_equals(len(creators.values()), 2) def test_no_creators(self): """Test a product with no creators """ product = self.amazon.lookup(ItemId="8420658537") assert_false(product.creators) def test_single_editorial_review(self): product = self.amazon.lookup(ItemId="1930846258") expected = u'In the title piece, Alan Turing' assert_equals(product.editorial_reviews[0][:len(expected)], expected) assert_equals(product.editorial_review, product.editorial_reviews[0]) assert_equals(len(product.editorial_reviews), 1) def test_multiple_editorial_reviews(self): product = self.amazon.lookup(ItemId="B000FBJCJE") expected = u'Only once in a great' assert_equals(product.editorial_reviews[0][:len(expected)], expected) expected = u'From the opening line' assert_equals(product.editorial_reviews[1][:len(expected)], expected) # duplicate data, amazon user data is great... expected = u'Only once in a great' assert_equals(product.editorial_reviews[2][:len(expected)], expected) assert_equals(len(product.editorial_reviews), 3) def test_languages_english(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="1930846258") assert_true('english' in product.languages) assert_equals(len(product.languages), 1) def test_languages_spanish(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="8420658537") assert_true('spanish' in product.languages) assert_equals(len(product.languages), 1)
class TestAmazonApi(unittest.TestCase): """Test Amazon API Test Class for Amazon simple API wrapper. """ def setUp(self): """Set Up. Initialize the Amazon API wrapper. The following values: * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY * AMAZON_ASSOC_TAG Are imported from a custom file named: 'test_settings.py' """ self.amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, CacheReader=cache_reader, CacheWriter=cache_writer, MaxQPS=0.5 ) def test_lookup(self): """Test Product Lookup. Tests that a product lookup for a kindle returns results and that the main methods are working. """ product = self.amazon.lookup(ItemId="B00I15SB16") assert_true('Kindle' in product.title) assert_equals(product.ean, '0848719039726') assert_equals( product.large_image_url, 'https://images-na.ssl-images-amazon.com/images/I/51XGerXeYeL.jpg' ) assert_equals( product.get_attribute('Publisher'), 'Amazon' ) assert_equals(product.get_attributes( ['ItemDimensions.Width', 'ItemDimensions.Height']), {'ItemDimensions.Width': '469', 'ItemDimensions.Height': '40'}) assert_true(len(product.browse_nodes) > 0) assert_true(product.price_and_currency[0] is not None) assert_true(product.price_and_currency[1] is not None) assert_equals(product.browse_nodes[0].id, 2642129011) assert_equals(product.browse_nodes[0].name, 'eBook Readers') def test_lookup_nonexistent_asin(self): """Test Product Lookup with a nonexistent ASIN. Tests that a product lookup for a nonexistent ASIN raises AsinNotFound. """ assert_raises(AsinNotFound, self.amazon.lookup, ItemId="ABCD1234") def test_bulk_lookup(self): """Test Baulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_lookup_bulk(self): """Test Bulk Product Lookup. Tests that a bulk product lookup request returns multiple results. """ asins = [TEST_ASIN, 'B00BWYQ9YE', 'B00BWYRF7E', 'B00D2KJDXA'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(len(products), len(asins)) for i, product in enumerate(products): assert_equals(asins[i], product.asin) def test_lookup_bulk_empty(self): """Test Bulk Product Lookup With No Results. Tests that a bulk product lookup request with no results returns an empty list. """ asins = ['not-an-asin', 'als-not-an-asin'] products = self.amazon.lookup_bulk(ItemId=','.join(asins)) assert_equals(type(products), list) assert_equals(len(products), 0) def test_search(self): """Test Product Search. Tests that a product search is working (by testing that results are returned). And that each result has a title attribute. The test fails if no results where returned. """ products = self.amazon.search(Keywords='kindle', SearchIndex='All') for product in products: assert_true(hasattr(product, 'title')) break else: assert_true(False, 'No search results returned.') def test_search_n(self): """Test Product Search N. Tests that a product search n is working by testing that N results are returned. """ products = self.amazon.search_n( 1, Keywords='kindle', SearchIndex='All' ) assert_equals(len(products), 1) def test_search_no_results(self): """Test Product Search with no results. Tests that a product search with that returns no results throws a SearchException. """ products = self.amazon.search(Title='no-such-thing-on-amazon', SearchIndex='Automotive') assert_raises(SearchException, next, (x for x in products)) def test_amazon_api_defaults_to_US(self): """Test Amazon API defaults to the US store.""" amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG ) assert_equals(amazon.api.Region, "US") def test_search_amazon_uk(self): """Test Poduct Search on Amazon UK. Tests that a product search on Amazon UK is working and that the currency of any of the returned products is GBP. The test fails if no results were returned. """ amazon = AmazonAPI( AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region="UK" ) assert_equals(amazon.api.Region, "UK", "Region has not been set to UK") products = amazon.search(Keywords='Kindle', SearchIndex='All') currencies = [product.price_and_currency[1] for product in products] assert_true(len(currencies), "No products found") is_gbp = 'GBP' in currencies assert_true(is_gbp, "Currency is not GBP, cannot be Amazon UK, though") def test_similarity_lookup(self): """Test Similarity Lookup. Tests that a similarity lookup for a kindle returns 10 results. """ products = self.amazon.similarity_lookup(ItemId=TEST_ASIN) assert_true(len(products) > 5) def test_product_attributes(self): """Test Product Attributes. Tests that all product that are supposed to be accessible are. """ product = self.amazon.lookup(ItemId=TEST_ASIN) for attribute in PRODUCT_ATTRIBUTES: getattr(product, attribute) def test_browse_node_lookup(self): """Test Browse Node Lookup. Test that a lookup by Brose Node ID returns appropriate node. """ bnid = 2642129011 bn = self.amazon.browse_node_lookup(BrowseNodeId=bnid)[0] assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False) def test_obscure_date(self): """Test Obscure Date Formats Test a product with an obscure date format """ product = self.amazon.lookup(ItemId="0933635869") assert_equals(product.publication_date.year, 1992) assert_equals(product.publication_date.month, 5) assert_true(isinstance(product.publication_date, datetime.date)) def test_single_creator(self): """Test a product with a single creator """ product = self.amazon.lookup(ItemId="B00005NZJA") creators = dict(product.creators) assert_equals(creators[u"Jonathan Davis"], u"Narrator") assert_equals(len(creators.values()), 2) def test_multiple_creators(self): """Test a product with multiple creators """ product = self.amazon.lookup(ItemId="B007V8RQC4") creators = dict(product.creators) assert_equals(creators[u"John Gregory Betancourt"], u"Editor") assert_equals(creators[u"Colin Azariah-Kribbs"], u"Editor") assert_equals(len(creators.values()), 2) def test_no_creators(self): """Test a product with no creators """ product = self.amazon.lookup(ItemId="8420658537") assert_false(product.creators) def test_single_editorial_review(self): product = self.amazon.lookup(ItemId="1930846258") expected = u'In the title piece, Alan Turing' assert_equals(product.editorial_reviews[0][:len(expected)], expected) assert_equals(product.editorial_review, product.editorial_reviews[0]) assert_equals(len(product.editorial_reviews), 1) def test_multiple_editorial_reviews(self): product = self.amazon.lookup(ItemId="B000FBJCJE") expected = u'<b>One of <i>Time</i>' assert_equals(product.editorial_reviews[0][:len(expected)], expected) expected = u'From the opening line' assert_equals(product.editorial_reviews[1][:len(expected)], expected) # duplicate data, amazon user data is great... expected = u'<b>One of <i>Time</i>' assert_equals(product.editorial_reviews[2][:len(expected)], expected) assert_equals(len(product.editorial_reviews), 3) def test_languages_english(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="1930846258") assert_true('english' in product.languages) assert_equals(len(product.languages), 1) def test_languages_spanish(self): """Test Language Data Test an English product """ product = self.amazon.lookup(ItemId="8420658537") assert_true('spanish' in product.languages) assert_equals(len(product.languages), 1) def test_region(self): amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG) assert_equals(amazon.region, 'US') # old 'region' parameter amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, region='UK') assert_equals(amazon.region, 'UK') # kwargs method amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, Region='UK') assert_equals(amazon.region, 'UK') def test_kwargs(self): amazon = AmazonAPI(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, MaxQPS=0.7) def test_images(self): """Test images property Test that the images property has a value when using the Images ResponseGroup """ product = self.amazon.lookup(ResponseGroup='Images', ItemId='B00TSVVNQC') assert_equals(type(product.images), list) assert_equals(len(product.images), 7)