コード例 #1
0
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)
コード例 #2
0
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
コード例 #3
0
ファイル: shopping.py プロジェクト: jhirniak/pinkunicorns
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 []
コード例 #4
0
ファイル: borrow.py プロジェクト: tatertot/lendinglibrary
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)
コード例 #5
0
ファイル: borrow.py プロジェクト: tatertot/lendinglibrary
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)
コード例 #6
0
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])
コード例 #7
0
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
コード例 #8
0
ファイル: amazon_strips.py プロジェクト: bharris62/IF_Tools
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))
コード例 #9
0
 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
コード例 #10
0
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))
コード例 #11
0
    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")
コード例 #12
0
    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")
コード例 #13
0
ファイル: callApi.py プロジェクト: rschmidtz/booklos-dev
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()
コード例 #14
0
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)
コード例 #15
0
ファイル: book_bot.py プロジェクト: zerocool443/BookBot
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
コード例 #16
0
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()
コード例 #17
0
# 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"
コード例 #18
0
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]))





コード例 #19
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)
コード例 #20
0
ファイル: utils.py プロジェクト: tishmen/amazon_ebay
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
コード例 #21
0
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)
コード例 #22
0
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)
コード例 #23
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="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")
コード例 #24
0
ファイル: AZProdSearch.py プロジェクト: smehan/py-webetl
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)
コード例 #25
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)
コード例 #26
0
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)
コード例 #27
0
ファイル: AMZNMain.py プロジェクト: khaihua/Amazon-Discounts
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))
コード例 #28
0
        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'
    }
コード例 #29
0
ファイル: author_details.py プロジェクト: zerocool443/BookBot
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)
コード例 #30
0
ファイル: amazon_api_test.py プロジェクト: DoHe/pybook
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
コード例 #31
0
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)
コード例 #32
0
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)
コード例 #33
0
        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:
コード例 #34
0
    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
コード例 #35
0
ファイル: aws.py プロジェクト: mohamed-elfiky/GoodBook
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
コード例 #36
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="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)
コード例 #37
0
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)
コード例 #38
0
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()
コード例 #39
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 = [
            '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)
コード例 #40
0
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)
コード例 #41
0
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')
コード例 #42
0
# 取得した商品情報の利用目的は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)    # 価格と通貨を表示。
コード例 #43
0
        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']:
コード例 #44
0
ファイル: allPythonContent.py プロジェクト: Mondego/pyreco
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)
コード例 #45
0
ファイル: tests.py プロジェクト: kumarremoa/Goferbot
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)