import datetime import io from pathlib import Path import re import shutil import time import zipfile from selenium import webdriver def apk_from_xapk(xapk_data, app_id): """This is necessary because on apkpure.com uses a custom package format xapk for some apps.""" with io.BytesIO(xapk_data) as stream: with zipfile.ZipFile(stream) as zip: with zip.open(f"{app_id}.apk", 'r') as f: return f.read() def get(app_id): dl_url = f"https://apkpure.com/_/{app_id}/download?from=details" options = webdriver.FirefoxOptions() options.add_argument("--headless") profile = webdriver.FirefoxProfile() profile.set_preference("browser.download.folderList", 2) profile.set_preference("browser.helperApps.alwaysAsk.force", False) profile.set_preference("browser.download.manager.showWhenStarting",False) profile.set_preference("browser.download.dir", "/tmp/tempapk/") profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/vnd.android.package-archive, application/xapk-package-archive" ) try: shutil.rmtree('/tmp/tempapk/') except FileNotFoundError: pass with webdriver.Firefox(options=options, firefox_profile=profile) as driver: driver.get(dl_url) dl_page = driver.page_source t = datetime.datetime.now() while True: p = Path('/tmp/tempapk/') p = list(p.iterdir()) if len(p) == 1: break elif datetime.datetime.now()-t > datetime.timedelta(seconds=60): raise RuntimeError('Download failed') time.sleep(1) with open(p[0], 'rb') as f: apk_data = f.read() shutil.rmtree('/tmp/tempapk/') # check if xapk match = re.search(r'_v.+_apkpure.com.(x?)apk', dl_page) xapk = bool(match.groups()[0]) if xapk: apk_data = apk_from_xapk(apk_data, app_id) return apk_data