def get_related(self, browse_stream): """ get the list of apps under the "more you might like" section under app details :param browse_stream: the link from the app details to request the list of related apps :return: a list of related apps and their details """ headers = { 'X-DFE-Device-Id': self.android_id, 'X-DFE-Client-Id': 'am-android-google', 'Accept-Encoding': '', 'Host': 'android.clients.google.com', 'Authorization': 'GoogleLogin Auth=' + self.auth, 'User-Agent': MARKET_USER_AGENT } response = self.session.get(GOOGLE_FDFE_URL + "/" + browse_stream, params=None, headers=headers, allow_redirects=True) related_response = apkfetch_pb2.ResponseWrapper() related_response.ParseFromString(response.content) if not related_response: raise Exception('Could not get related apps for') if related_response.commands.displayErrorMessage != "": raise Exception('error getting related apps: ' + related_response.commands.displayErrorMessage) return related_response.preFetch[0].response.payload.listResponse.doc[ 0]
def get_download_url(self, package_name, version_code): """ performs a GET request to get the download url of a specific app :param package_name: the app to get the download url from :param version_code: the version of the app to download :return: the download url """ headers = { 'X-DFE-Device-Id': self.android_id, 'X-DFE-Client-Id': 'am-android-google', 'Accept-Encoding': '', 'Host': 'android.clients.google.com', 'Authorization': 'GoogleLogin Auth=' + self.auth, 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } data = {'doc': package_name, 'ot': '1', 'vc': version_code} response = self.session.get(GOOGLE_DELIVERY_URL, params=data, verify=True, headers=headers, allow_redirects=True) delivery_response = apkfetch_pb2.ResponseWrapper() delivery_response.ParseFromString(response.content) if not delivery_response: raise Exception('Could not get download url for: ' + package_name) if delivery_response.commands.displayErrorMessage != "": raise Exception('error getting download url: ' + delivery_response.commands.displayErrorMessage + " for: " + package_name) return delivery_response.payload.deliveryResponse.appDeliveryData.downloadUrl
def reviews(self, package_name, amount=50): """ performs a GET request to get the reviews of a specific app :param package_name: the app to get reviews from :param amount: amount of reviews to get :return: a list of reviews """ headers = { 'X-DFE-Device-Id': self.android_id, 'X-DFE-Client-Id': 'am-android-google', 'Accept-Encoding': '', 'Host': 'android.clients.google.com', 'Authorization': 'GoogleLogin Auth=' + self.auth, 'User-Agent': MARKET_USER_AGENT } params = {'doc': package_name, 'n': amount} response = self.session.get(GOOGLE_REVIEWS_URL, params=params, headers=headers, allow_redirects=True) review_response = apkfetch_pb2.ResponseWrapper() review_response.ParseFromString(response.content) if not review_response: raise Exception('Could not get reviews for: ' + package_name) if review_response.commands.displayErrorMessage != "": raise Exception('error getting reviews: ' + review_response.commands.displayErrorMessage + " for: " + package_name) return review_response.payload.reviewResponse.getResponse
def details(self, package_name): """ performs a GET request to get the details of a specific app :param package_name: the app to get details from :return: the details of the app """ headers = { 'X-DFE-Device-Id': self.android_id, 'X-DFE-Client-Id': 'am-android-google', 'Accept-Encoding': '', 'Host': 'android.clients.google.com', 'Authorization': 'GoogleLogin Auth=' + self.auth, 'User-Agent': MARKET_USER_AGENT } params = {'doc': package_name} response = self.session.get(GOOGLE_DETAILS_URL, params=params, headers=headers, allow_redirects=True) details_response = apkfetch_pb2.ResponseWrapper() details_response.ParseFromString(response.content) details = details_response.payload.detailsResponse.docV2 if not details: raise Exception('Could not get details for: ' + package_name) if details_response.commands.displayErrorMessage != "": raise Exception('error getting details: ' + details_response.commands.displayErrorMessage + " for: " + package_name) return details
def version(self, package_name): headers = {'X-DFE-Device-Id': self.androidid, 'X-DFE-Client-Id': 'am-android-google', 'Accept-Encoding': '', 'Host': 'android.clients.google.com', 'Authorization': 'GoogleLogin ' + self.auth} params = {'doc': package_name} response = self.session.get(GOOGLE_DETAILS_URL, params=params, headers=headers, allow_redirects=True) details_response = apkfetch_pb2.ResponseWrapper() details_response.ParseFromString(response.content) version = details_response.payload.detailsResponse.docV2.details.appDetails.versionCode if not version: raise RuntimeError('Could not get version-code') return version
def get_download_url(self, package_name, version_code): headers = { 'X-DFE-Device-Id': self.androidid, 'X-DFE-Client-Id': 'am-android-google', 'Accept-Encoding': '', 'Host': 'android.clients.google.com', 'Authorization': 'GoogleLogin Auth=' + self.auth } data = {'doc': package_name, 'ot': '1', 'vc': version_code} response = self.session.get(GOOGLE_DELIVERY_URL, params=data, headers=headers, allow_redirects=True) delivery_response = apkfetch_pb2.ResponseWrapper() delivery_response.ParseFromString(response.content) url = delivery_response.payload.deliveryResponse.appDeliveryData.downloadUrl return url
def fetch(self, package_name, apk_fn=None): headers = {'X-DFE-Device-Id': self.androidid, 'X-DFE-Client-Id': 'am-android-google', 'Accept-Encoding': '', 'Host': 'android.clients.google.com', 'Authorization': 'GoogleLogin ' + self.auth} data = {'doc': package_name, 'ot': '1', 'vc': self.version(package_name), 'tok': 'dummy-token'} response = self.session.post(GOOGLE_PURCHASE_URL, data=data, headers=headers, allow_redirects=True) # Extract URL from response buy_response = apkfetch_pb2.ResponseWrapper() buy_response.ParseFromString(response.content) url = buy_response.payload.buyResponse.purchaseStatusResponse.appDeliveryData.downloadUrl error = buy_response.commands.displayErrorMessage if error or not url: raise RuntimeError(error or 'Could not get download URL') # Extract MarketDA value marketda = None for c in buy_response.payload.buyResponse.purchaseStatusResponse.appDeliveryData.downloadAuthCookie: if c.name == 'MarketDA': marketda = c.value response = self.session.get(url, headers={'User-Agent': DOWNLOAD_USER_AGENT}, cookies={'MarketDA': marketda}, stream=True, allow_redirects=True) apk_fn = apk_fn or (package_name + '.apk') if os.path.exists(apk_fn): os.remove(apk_fn) with open(apk_fn, 'wb') as fp: for chunk in response.iter_content(chunk_size=5*1024): if chunk: fp.write(chunk) fp.flush() return os.path.exists(apk_fn)