Added apkmonk scrapper (#324)

This commit is contained in:
Nikhil Badyal
2023-08-26 19:06:39 +05:30
committed by GitHub
parent 716fa3c418
commit a641502ea1
5 changed files with 115 additions and 4 deletions
+6 -3
View File
@@ -202,18 +202,21 @@ You can use any of the following methods to build.
```
You can also provide DL to the clean apk instead of providing DL_SOURCES as mentioned in this [note](#app-dl).
Supported Scrappers are:
1. APKMIRROR - Supports downloading any versions
1. APKMIRROR - Supports downloading any available version
1. Link Format - https://www.apkmirror.com/apk/<organisation-name>/app-name/
2. Example Link - https://www.apkmirror.com/apk/google-inc/youtube/
2. UPTODOWN - Supports downloading any versions
2. UPTODOWN - Supports downloading any available version
1. Link Format - https://<app-name>.en.uptodown.com/android
2. Example Link - https://spotify.en.uptodown.com/android
3. APKSOS - Supports downloading any versions
3. APKSOS - Supports downloading any available version
1. Link Format - https://apksos.com/download-app/<package-name>
2. Example Link - https://apksos.com/download-app/com.expensemanager
4. APKPURE - Supports downloading only latest version
1. Link Format - https://d.apkpure.com/b/APK/<package-name>?version=latest
2. Example Link - https://d.apkpure.com/b/APK/com.google.android.youtube?version=latest
5. APKMonk - Supports downloading any available version
1. Link Format - https://www.apkmonk.com/app/<package-name>/
2. Example Link - https://www.apkmonk.com/app/<package-name>/
<br>Please verify the source of original APKs yourself with links provided. I'm not responsible for any damage
caused.If you know any better/safe source to download clean. Open a discussion.
+93
View File
@@ -0,0 +1,93 @@
"""APK Monk Downloader Class."""
import re
from typing import Any, Self, Tuple
import requests
from bs4 import BeautifulSoup
from src.app import APP
from src.downloader.download import Downloader
from src.downloader.sources import APK_MONK_BASE_URL
from src.downloader.utils import status_code_200
from src.exceptions import APKMonkAPKDownloadError
from src.utils import bs4_parser, request_header
class ApkMonk(Downloader):
"""Files downloader."""
def extract_download_link(self: Self, page: str, app: str) -> Tuple[str, str]:
"""Function to extract the download link from apkmonk html page.
:param page: Url of the page
:param app: Name of the app
"""
file_name = f"{app}.apk"
r = requests.get(page, headers=request_header, allow_redirects=True, timeout=60)
if r.status_code != status_code_200:
msg = f"Unable to connect with {page}.Reason - {r.text}"
raise APKMonkAPKDownloadError(
msg,
url=page,
)
soup = BeautifulSoup(r.text, bs4_parser)
download_scripts = soup.find_all("script", type="text/javascript")
key_value_pattern = r'\{"pkg":"([^"]+)","key":"([^"]+)"\}'
url = None
for script in download_scripts:
if match := re.search(key_value_pattern, script.text):
pkg_value = match.group(1)
key_value = match.group(2)
url = f"{APK_MONK_BASE_URL}/down_file?pkg={pkg_value}&key={key_value}"
break
if not url:
msg = "Unable to scrap link"
raise APKMonkAPKDownloadError(
msg,
url=page,
)
r = requests.get(url, headers=request_header, allow_redirects=True, timeout=60)
if r.status_code != status_code_200:
msg = f"Unable to connect with {page}.Reason - {r.text}"
raise APKMonkAPKDownloadError(
msg,
url=page,
)
final_download_url = r.json()["url"]
self._download(final_download_url, file_name)
return file_name, final_download_url
def specific_version(self: Self, app: APP, version: str, main_page: str = "") -> Tuple[str, str]:
"""Function to download the specified version of app from apkmirror.
:param app: Name of the application
:param version: Version of the application to download
:param main_page: Version of the application to download
:return: Version of downloaded apk
"""
r = requests.get(app.download_source, headers=request_header, allow_redirects=True, timeout=60)
soup = BeautifulSoup(r.text, bs4_parser)
version_table = soup.find_all(class_="striped")
for version_row in version_table:
version_links = version_row.find_all("a")
for link in version_links:
app_version = link.text
if app_version == app.app_version:
download_link = link["href"]
return self.extract_download_link(APK_MONK_BASE_URL + download_link, app.app_name)
msg = "Unable to scrap link"
raise APKMonkAPKDownloadError(
msg,
url=app.download_source,
)
def latest_version(self: Self, app: APP, **kwargs: Any) -> Tuple[str, str]:
"""Function to download whatever the latest version of app from apkmonkP.
:param app: Name of the application
:return: Version of downloaded apk
"""
r = requests.get(app.download_source, headers=request_header, allow_redirects=True, timeout=60)
soup = BeautifulSoup(r.text, bs4_parser)
latest_download_url = soup.find(id="download_button")["href"] # type: ignore[index]
return self.extract_download_link(latest_download_url, app.app_name) # type: ignore[arg-type]
+10 -1
View File
@@ -1,11 +1,18 @@
"""Downloader Factory."""
from src.config import RevancedConfig
from src.downloader.apkmirror import ApkMirror
from src.downloader.apkmonk import ApkMonk
from src.downloader.apkpure import ApkPure
from src.downloader.apksos import ApkSos
from src.downloader.download import Downloader
from src.downloader.github import Github
from src.downloader.sources import APK_MIRROR_BASE_URL, APK_PURE_BASE_URL, APKS_SOS_BASE_URL, GITHUB_BASE_URL
from src.downloader.sources import (
APK_MIRROR_BASE_URL,
APK_MONK_BASE_URL,
APK_PURE_BASE_URL,
APKS_SOS_BASE_URL,
GITHUB_BASE_URL,
)
from src.downloader.uptodown import UptoDown
from src.exceptions import DownloadError
@@ -32,5 +39,7 @@ class DownloaderFactory(object):
return UptoDown(config)
if apk_source.startswith(APK_MIRROR_BASE_URL):
return ApkMirror(config)
if apk_source.startswith(APK_MONK_BASE_URL):
return ApkMonk(config)
msg = "No download factory found."
raise DownloadError(msg)
+2
View File
@@ -15,6 +15,8 @@ APK_COMBO_BASE_URL = "https://apkcombo.com"
APK_COMBO_GENERIC_URL = APK_COMBO_BASE_URL + "/genericApp/{}"
not_found_icon = "https://img.icons8.com/bubbles/500/android-os.png"
revanced_api = "https://releases.revanced.app/patches"
APK_MONK_BASE_URL = "https://www.apkmonk.com"
APK_MONK_APK_URL = APK_MONK_BASE_URL + "/app/{}/"
apk_sources = {
"backdrops": f"{APK_MIRROR_BASE_APK_URL}/backdrops/backdrops-wallpapers/",
"bacon": f"{APK_MIRROR_BASE_APK_URL}/onelouder-apps/baconreader-for-reddit/",
+4
View File
@@ -46,6 +46,10 @@ class APKMirrorAPKDownloadError(APKDownloadError):
"""Exception raised when downloading an APK from apkmirror failed."""
class APKMonkAPKDownloadError(APKDownloadError):
"""Exception raised when downloading an APK from apkmonk failed."""
class APKMirrorAPKNotFoundError(APKDownloadError):
"""Exception raised when apk doesn't exist on APKMirror."""