Rev 20315 | Blame | Compare with Previous | Last modification | View Log | RSS feed
from xml.dom.minidom import parseStringimport reimport urllibimport hashlibimport hmacimport base64from time import strftime, gmtimefrom requests import requestclass MWS(object):URI = "/"VERSION = "2009-01-01"NS = ''def __init__(self, access_key, secret_key, merchant_id,domain='https://mws-eu.amazonservices.com', uri="", version=""):self.access_key = access_keyself.secret_key = secret_keyself.merchant_id = merchant_idself.domain = domainself.uri = uri or self.URIself.version = version or self.VERSIONdef make_request(self, extra_data, action,method="GET", **kwargs):params = {'AWSAccessKeyId': self.access_key,'SignatureVersion': '2','Timestamp': self.get_timestamp(),'Version': self.version,'SignatureMethod': 'HmacSHA256','Action': action}if action=='GetLowestOfferListingsForSKU':params['ExcludeMe']='true'if action =='GetLowestOfferListingsForASIN':params['ItemCondition'] = 'New'params.update(extra_data)request_description = '&'.join(['%s=%s' % (k, urllib.quote(params[k], safe='-_.~').encode('utf-8')) for k in sorted(params)])signature = self.calc_signature(method, request_description)url = '%s%s?%s&Signature=%s' % (self.domain, self.uri, request_description, urllib.quote(signature))#headers = {'User-Agent': 'AmazonJavascriptScratchpad/1.0 (Language=Python)'}#headers.update(kwargs.get('extra_headers', {}))response = request(method, url)if action=='GetLowestOfferListingsForSKU':return self.parse_competitor_pricing_response(response)elif action=='GetMyPriceForSKU':return self.parse_my_pricing_response(response)elif action=='GetProductCategoriesForSKU':return self.parse_product_category_for_sku(response)elif action=='GetMatchingProductForId':return self.parse_product_attributes(response)elif action=='GetLowestOfferListingsForASIN':return self.parse_lowest_pricing_asins(response)elif action == 'GetMatchingProduct':return self.parse_get_matching_product(response)else:raisedef parse_get_matching_product(self, response):spString = re.sub('<\?.*\?>','',response.text)spString = "<dom>" + spString + "</dom>"dom = parseString(spString)asinStatuses = dom.getElementsByTagName('GetMatchingProductResult')asinMap = {}for asinStatus in asinStatuses:#print asinStatus.attributes.items()status = asinStatus.attributes.items()[0][1]asin = asinStatus.attributes.items()[1][1]asinMap[asin] = statusreturn asinMapdef parse_product_category_for_sku(self,response):browseNodes = []#node = ""spString = re.sub('<\?.*\?>','',response.text)spString = "<dom>" + spString + "</dom>"dom = parseString(spString)selfTag = dom.getElementsByTagName('Self')for element in selfTag:temp = []browsingNodes = element.getElementsByTagName('ProductCategoryName')for browsingNode in browsingNodes:temp.append(browsingNode.firstChild.nodeValue)browseNodes.append(temp)return browseNodesdef parse_product_attributes(self,response):spString = re.sub('<\?.*\?>','',response.text)spString = "<dom>" + spString + "</dom>"dom = parseString(spString)sku = dom.getElementsByTagName("GetMatchingProductForIdResult")[0].attributes.items()[2][1]dimensions = dom.getElementsByTagName("ns2:PackageDimensions")for dimension in dimensions:height = dimension.getElementsByTagName("ns2:Height")[0].firstChild.nodeValue #Inchlength = dimension.getElementsByTagName("ns2:Length")[0].firstChild.nodeValue #Inchwidth = dimension.getElementsByTagName("ns2:Width")[0].firstChild.nodeValue #Inchweight = dimension.getElementsByTagName("ns2:Weight")[0].firstChild.nodeValue #Poundsreturn {'sku':sku,'length':length,'width':width,'height':height,'weight':weight}def parse_lowest_pricing_asins(self,response):#GetLowestOfferListingsForASINResultspString = re.sub('<\?.*\?>','',response.text)spString = "<dom>" + spString + "</dom>"dom = parseString(spString)asinOffers = dom.getElementsByTagName('GetLowestOfferListingsForASINResult')asinMap = {}for asinOffer in asinOffers:asin = asinOffer.attributes.items()[1][1]asinMap[asin] = 0.0for offer in asinOffer.getElementsByTagName('LowestOfferListing'):price = offer.getElementsByTagName('Amount')[0].firstChild.nodeValueasinMap[asin] = float(price)breakreturn asinMapdef parse_competitor_pricing_response(self,response):spString = re.sub('<\?.*\?>','',response.text)spString = "<dom>" + spString + "</dom>"dom = parseString(spString)skuOffers = dom.getElementsByTagName('GetLowestOfferListingsForSKUResult')offerMap = {}otherInfo = {}for skuOffer in skuOffers:status = skuOffer.attributes.items()[0][1]sku = skuOffer.attributes.items()[1][1]info = []for offer in skuOffer.getElementsByTagName('LowestOfferListing'):temp = {}try:if len(info)==3:breakamount = offer.getElementsByTagName('Amount')[0].firstChild.nodeValuetemp['sellingPrice'] = float(amount)temp['promoPrice'] = float(amount)temp['fulfillmentChannel'] = offer.getElementsByTagName('FulfillmentChannel')[0].firstChild.nodeValuetry:temp['shippingTime'] = (offer.getElementsByTagName('Max')[0].firstChild.nodeValue).replace('days','')except:temp['shippingTime'] = '0-0'try:temp['rating'] = (offer.getElementsByTagName('SellerPositiveFeedbackRating')[0].firstChild.nodeValue)if temp['rating'] == 'Just Launched':temp['rating'] = '100'else:str_rating = temp['rating'].replace('-',' ').replace('%','')a = str_rating.split()l = []for x in a:if x.isdigit():l.append(x)temp['rating'] = l[0]except:temp['rating'] = '0'except:passtemp['notOurSku'] = Trueinfo.append(temp)offerMap[sku]=infofor skuOffer in skuOffers:sku = skuOffer.attributes.items()[1][1]temp = {}temp['lowestMfnIgnored']=0.0temp['isLowestMfnIgnored']=Falsetemp['lowestFba']=0.0temp['isLowestFba']=Falsetemp['lowestMfn']=0.0temp['isLowestMfn']=Falsefor offer in skuOffer.getElementsByTagName('LowestOfferListing'):try:fulfillmentChannel = offer.getElementsByTagName('FulfillmentChannel')[0].firstChild.nodeValueamount = offer.getElementsByTagName('Amount')[0].firstChild.nodeValuetry:rating = (offer.getElementsByTagName('SellerPositiveFeedbackRating')[0].firstChild.nodeValue)if rating == 'Just Launched':rating = 100else:str_rating = rating.replace('-',' ').replace('%','')a = str_rating.split()l = []for x in a:if x.isdigit():l.append(x)rating = int(l[0])except:rating = 0if fulfillmentChannel=='Merchant' and not temp['isLowestMfnIgnored'] and not temp['isLowestMfn'] and rating < 60:temp['lowestMfnIgnored'] = float(amount)temp['isLowestMfnIgnored']=Trueelif fulfillmentChannel=='Merchant' and not temp['isLowestMfn'] and rating > 60:temp['lowestMfn'] = float(amount)temp['isLowestMfn']=Trueelif fulfillmentChannel=='Amazon' and not temp['isLowestFba']:temp['lowestFba'] = float(amount)temp['isLowestFba']=Trueelse:passexcept:passotherInfo[sku]=tempreturn offerMap, otherInfodef parse_my_pricing_response(self,response):spString = re.sub('<\?.*\?>','',response.text)spString = "<dom>" + spString + "</dom>"dom = parseString(spString)skuOffers = dom.getElementsByTagName('GetMyPriceForSKUResult')skuMap = {}for skuOffer in skuOffers:try:status = skuOffer.attributes.items()[0][1]sku = skuOffer.attributes.items()[1][1]asin = skuOffer.getElementsByTagName('ASIN')[0].firstChild.nodeValueskuMap[sku]={}except:continuefor offer in skuOffer.getElementsByTagName('Offer'):offerSku = offer.getElementsByTagName('SellerSKU')[0].firstChild.nodeValuefcChannel = offer.getElementsByTagName('FulfillmentChannel')[0].firstChild.nodeValueif not (offerSku==sku and fcChannel=='AMAZON'):continuetemp = {}try:promoPrice = offer.getElementsByTagName('LandedPrice')[0].getElementsByTagName('Amount')[0].firstChild.nodeValueregularPrice = offer.getElementsByTagName('RegularPrice')[0].getElementsByTagName('Amount')[0].firstChild.nodeValuetemp['sellingPrice'] = float(regularPrice)temp['promoPrice'] = float(promoPrice)if promoPrice == regularPrice:temp['promotion'] = Falseelse:temp['promotion'] = Truetemp['status'] = statustemp['asin'] = asintemp['notOurSku'] = Falsetemp['fulfillmentChannel'] ='AMAZON'temp['shippingTime'] = '0-0'temp['rating'] = '0'except:passskuMap[sku]=tempreturn skuMapdef calc_signature(self, method, request_description):sig_data = method + '\n' + self.domain.replace('https://', '').lower() + '\n' + self.uri + '\n' + request_descriptionreturn base64.b64encode(hmac.new(str(self.secret_key), sig_data, hashlib.sha256).digest())def get_timestamp(self):return strftime("%Y-%m-%dT%H:%M:%SZ", gmtime())class Products(MWS):URI = '/Products/2011-10-01'VERSION = '2011-10-01'NS = '{https://mws-eu.amazonservices.com/Products/2011-10-01}'def get_my_pricing_for_sku(self, marketplaceid, skus):data = dict(SellerId=self.merchant_id, MarketplaceId=marketplaceid)num=0for sku in skus:data['SellerSKUList.SellerSKU.%d' % (num + 1)] = skunum+=1return self.make_request(data,'GetMyPriceForSKU')def get_competitive_pricing_for_sku(self, marketplaceid, skus):data = dict(SellerId=self.merchant_id, MarketplaceId=marketplaceid)num=0for sku in skus:data['SellerSKUList.SellerSKU.%d' % (num + 1)] = skunum+=1return self.make_request(data,'GetLowestOfferListingsForSKU')def get_product_category_for_sku(self, marketplaceid, sku):data = dict(SellerId=self.merchant_id, MarketplaceId=marketplaceid)data['SellerSKU'] = skureturn self.make_request(data,'GetProductCategoriesForSKU')def get_product_attributes_for_sku(self, marketplaceid, skus):data = dict(SellerId=self.merchant_id, MarketplaceId=marketplaceid)num=0for sku in skus:data['IdList.Id.%d' % (num + 1)] = skunum+=1data['IdType'] = 'ASIN'return self.make_request(data,'GetMatchingProductForId')def get_competitive_pricing_for_asin(self, marketplaceid, asins):data = dict(SellerId=self.merchant_id, MarketplaceId=marketplaceid)num=0for asin in asins:data['ASINList.ASIN.%d' % (num + 1)] = asinnum+=1return self.make_request(data,'GetLowestOfferListingsForASIN')def get_matching_product(self, marketplaceid, asins):data = dict(SellerId=self.merchant_id, MarketplaceId=marketplaceid)num=0for asin in asins:data['ASINList.ASIN.%d' % (num + 1)] = asinnum+=1return self.make_request(data,'GetMatchingProduct')def main():p = Products("AKIAII3SGRXBJDPCHSGQ", "B92xTbNBTYygbGs98w01nFQUhbec1pNCkCsKVfpg", "AF6E3O0VE0X4D")print p.get_matching_product("A21TJRUUN4KGV", ["B016QBT87W","B0168L23VS"])if __name__=='__main__':main()