diff --git a/src/linktools/android/adb.py b/src/linktools/android/adb.py index 286d8e8e..a650e939 100644 --- a/src/linktools/android/adb.py +++ b/src/linktools/android/adb.py @@ -30,7 +30,7 @@ import json import re import time -from typing import Any, Generator, List +from typing import Any, Generator, List, Callable, TYPE_CHECKING, TypeVar from .struct import App, UnixSocket, InetSocket, Process from .. import utils, environ @@ -38,10 +38,11 @@ from ..device import BridgeError, Bridge, BaseDevice from ..reactor import Stoppable -_logger = environ.get_logger("android.adb") +if TYPE_CHECKING: + DEVICE_TYPE = TypeVar("DEVICE_TYPE", bound="Device") +_logger = environ.get_logger("android.adb") _agent_output_pattern = re.compile( - r"" r"┌──+──┐[^\n]*\n" r"│[^|]*│[^\n]*\n" r"└──+──┘[^\n]*\n", @@ -138,6 +139,9 @@ def uid(self) -> int: """ return self.get_uid() + def copy(self, type: "Callable[[str, Adb], DEVICE_TYPE]" = None) -> "DEVICE_TYPE": + return (type or Device)(self._id, self._adb) + def popen(self, *args: Any, **kwargs) -> utils.Process: """ 执行命令 @@ -203,7 +207,7 @@ def install(self, path_or_url: str, opts: [str] = (), **kwargs): apk_path = file.download() environ.logger.info(f"Save file to local: {apk_path}") - remote_path = self.get_data_path("apk", f"{int(time.time())}.apk") + remote_path = self.get_data_path("apk", f"installed_{int(time.time())}.apk") try: self.push(apk_path, remote_path, **kwargs) if self.uid >= 10000: diff --git a/src/linktools/assets/browsers.json b/src/linktools/assets/browsers.json new file mode 100644 index 00000000..e9b2c3af --- /dev/null +++ b/src/linktools/assets/browsers.json @@ -0,0 +1,165 @@ +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 Unique/97.7.7239.70", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 Trailer/92.3.3357.27", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 Viewer/99.9.9009.89", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 Trailer/93.3.3695.30", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 GLS/100.10.9850.99", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 GLS/100.10.9979.100", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 Agency/98.8.8188.80", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 GLS/100.10.9415.94", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 AtContent/95.5.5392.49", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36 EdgA/121.0.0.0", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 121.0 Android", "browser": "edge", "version": 121.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 EdgiOS/121.2277.107 Mobile/15E148 Safari/605.1.15", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 121.2277 iOS", "browser": "edge", "version": 121.2277, "os": "ios"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 Herring/95.1.1930.31", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0 Unique/97.7.7286.70", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0", "percent": 100.0, "type": "pc", "system": "Edge 121.0 Windows", "browser": "edge", "version": 121.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0 Config/91.2.2121.13", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0 OpenWave/94.4.4504.39", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Android 8.1.0; Mobile; rv:123.0) Gecko/123.0 Firefox/123.0", "percent": 100.0, "type": "mobile", "system": "Firefox Mobile 123.0 Android", "browser": "firefox", "version": 123.0, "os": "android"} +{"useragent": "Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Linux", "browser": "firefox", "version": 123.0, "os": "linux"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0 Config/92.2.7601.2", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Windows", "browser": "firefox", "version": 123.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Android 11; Mobile; rv:123.0) Gecko/123.0 Firefox/123.0", "percent": 100.0, "type": "mobile", "system": "Firefox Mobile 123.0 Android", "browser": "firefox", "version": 123.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5; rv:123.0esr) Gecko/20100101 Firefox/123.0esr", "percent": 100.0, "type": "pc", "system": "Firefox 123.0 Mac OS X", "browser": "firefox", "version": 123.0, "os": "macos"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/122.0.6261.62 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile iOS 122.0 iOS", "browser": "chrome", "version": 122.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/122.0.6261.62 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile iOS 122.0 iOS", "browser": "chrome", "version": 122.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Mac OS X", "browser": "chrome", "version": 122.0, "os": "macos"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Mac OS X", "browser": "chrome", "version": 122.0, "os": "macos"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Agency/98.8.8175.80", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 11; moto e20 Build/RONS31.267-94-14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.64 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "tablet", "system": "Chrome 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 8.1.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36 PTST/240201.144844", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 8.1.0; C5 2019 Build/OPM2.171019.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.64 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36", "percent": 100.0, "type": "mobile", "system": "Chrome Mobile 122.0 Android", "browser": "chrome", "version": 122.0, "os": "android"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Trailer/93.3.3516.28", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Config/92.2.2788.20", "percent": 100.0, "type": "pc", "system": "Chrome 122.0 Windows", "browser": "chrome", "version": 122.0, "os": "win10"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0.1 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "percent": 100.0, "type": "pc", "system": "Safari 17.0 Mac OS X", "browser": "safari", "version": 17.0, "os": "macos"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0.1 Safari/605.1.15", "percent": 100.0, "type": "pc", "system": "Safari 17.0 Mac OS X", "browser": "safari", "version": 17.0, "os": "macos"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15", "percent": 100.0, "type": "mobile", "system": "DuckDuckGo Mobile 7.0 iOS", "browser": "DuckDuckGo Mobile", "version": 7.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPad; CPU OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0.1 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "tablet", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/121.0.2277.99 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 121.0 iOS", "browser": "edge", "version": 121.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.150 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "tablet", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.141 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15", "percent": 100.0, "type": "mobile", "system": "DuckDuckGo Mobile 7.0 iOS", "browser": "DuckDuckGo Mobile", "version": 7.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/121.0.2277.107 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 121.0 iOS", "browser": "edge", "version": 121.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.126 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPad; CPU OS 17_0_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "tablet", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15", "percent": 100.0, "type": "mobile", "system": "DuckDuckGo Mobile 7.0 iOS", "browser": "DuckDuckGo Mobile", "version": 7.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 DuckDuckGo/7 Safari/605.1.15", "percent": 100.0, "type": "pc", "system": "Safari 17.0 Mac OS X", "browser": "safari", "version": 17.0, "os": "macos"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.150 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) AvastSecureBrowser/5.3.1 Mobile/15E148 Version/17.0 Safari/605.1.15", "percent": 100.0, "type": "mobile", "system": "Mobile Safari UI/WKWebView 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.116 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.86 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/119.0.2151.105 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 119.0 iOS", "browser": "edge", "version": 119.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/119.0.2151.96 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 119.0 iOS", "browser": "edge", "version": 119.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "percent": 100.0, "type": "pc", "system": "Safari 17.0 Mac OS X", "browser": "safari", "version": 17.0, "os": "macos"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1 OPX/2.2.0", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0.3 Mobile/15E148 Safari/604.1 RDDocuments/8.7.2.978", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/117.0.2045.48 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 117.0 iOS", "browser": "edge", "version": 117.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/121.0.2277.107 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 121.0 iOS", "browser": "edge", "version": 121.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "percent": 100.0, "type": "pc", "system": "Safari 17.0 Ubuntu", "browser": "safari", "version": 17.0, "os": "linux"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1 Ddg/17.0", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.86 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/120.0.2210.105 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 120.0 iOS", "browser": "edge", "version": 120.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/119.0.2151.105 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 119.0 iOS", "browser": "edge", "version": 119.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/119.0.2151.78 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 119.0 iOS", "browser": "edge", "version": 119.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/119.0.2151.65 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 119.0 iOS", "browser": "edge", "version": 119.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/118.0.2088.68 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 118.0 iOS", "browser": "edge", "version": 118.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1 OPT/4.3.1", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPad; CPU OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/605.1.15", "percent": 100.0, "type": "tablet", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/116.0.1938.79 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 116.0 iOS", "browser": "edge", "version": 116.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1 OPT/4.2.3", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/116.0.1938.72 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 116.0 iOS", "browser": "edge", "version": 116.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1 OPX/2.1.0", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/116.0.1938.56 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 116.0 iOS", "browser": "edge", "version": 116.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1 OPX/2.0.1", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1 RDDocuments/8.4.8.940", "percent": 100.0, "type": "mobile", "system": "Mobile Safari 17.0 iOS", "browser": "safari", "version": 17.0, "os": "ios"} +{"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/121.0.2277.107 Version/17.0 Mobile/15E148 Safari/604.1", "percent": 100.0, "type": "mobile", "system": "Edge Mobile 121.0 iOS", "browser": "edge", "version": 121.0, "os": "ios"} \ No newline at end of file diff --git a/src/linktools/assets/fake_useragent.json b/src/linktools/assets/fake_useragent.json deleted file mode 100644 index 0cad1e94..00000000 --- a/src/linktools/assets/fake_useragent.json +++ /dev/null @@ -1,52 +0,0 @@ -{"percent": 21.4, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", "system": "Chrome 116.0 Win10", "browser": "chrome", "version": 116.0, "os": "win10"} -{"percent": 9.9, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", "system": "Chrome 116.0 macOS", "browser": "chrome", "version": 116.0, "os": "macos"} -{"percent": 8.8, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", "system": "Chrome 117.0 Win10", "browser": "chrome", "version": 117.0, "os": "win10"} -{"percent": 8.7, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0", "system": "Firefox 117.0 Win10", "browser": "firefox", "version": 117.0, "os": "win10"} -{"percent": 4.1, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", "system": "Chrome 117.0 macOS", "browser": "chrome", "version": 117.0, "os": "macos"} -{"percent": 2.8, "useragent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0", "system": "Firefox 117.0 Linux", "browser": "firefox", "version": 117.0, "os": "linux"} -{"percent": 2.4, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15", "system": "Safari Generic macOS", "browser": "safari", "version": 1.0, "os": "macos"} -{"percent": 2.4, "useragent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", "system": "Chrome 116.0 Linux", "browser": "chrome", "version": 116.0, "os": "linux"} -{"percent": 2.0, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0", "system": "Firefox 117.0 macOS", "browser": "firefox", "version": 117.0, "os": "macos"} -{"percent": 1.5, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0", "system": "Firefox 118.0 Win10", "browser": "firefox", "version": 118.0, "os": "win10"} -{"percent": 1.5, "useragent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", "system": "Chrome 117.0 Linux", "browser": "chrome", "version": 117.0, "os": "linux"} -{"percent": 1.3, "useragent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0", "system": "Firefox 117.0 Linux", "browser": "firefox", "version": 117.0, "os": "linux"} -{"percent": 1.1, "useragent": "Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/117.0", "system": "Firefox 117.0 Win10", "browser": "firefox", "version": 117.0, "os": "win10"} -{"percent": 0.9, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.69", "system": "Edge 116.0 Win10", "browser": "edge", "version": 116.0, "os": "win10"} -{"percent": 0.9, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", "system": "Chrome 109.0 Win10", "browser": "chrome", "version": 109.0, "os": "win10"} -{"percent": 0.8, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 OPR/102.0.0.0", "system": "Chrome 116.0 Win10", "browser": "chrome", "version": 116.0, "os": "win10"} -{"percent": 0.8, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 OPR/101.0.0.0", "system": "Chrome 115.0 Win10", "browser": "chrome", "version": 115.0, "os": "win10"} -{"percent": 0.8, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.76", "system": "Edge 116.0 Win10", "browser": "edge", "version": 116.0, "os": "win10"} -{"percent": 0.7, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36", "system": "Chrome 115.0 macOS", "browser": "chrome", "version": 115.0, "os": "macos"} -{"percent": 0.7, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "system": "Chrome 114.0 Win10", "browser": "chrome", "version": 114.0, "os": "win10"} -{"percent": 0.7, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.31", "system": "Edge 117.0 Win10", "browser": "edge", "version": 117.0, "os": "win10"} -{"percent": 0.7, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36", "system": "Chrome 115.0 Win10", "browser": "chrome", "version": 115.0, "os": "win10"} -{"percent": 0.7, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81", "system": "Edge 116.0 Win10", "browser": "edge", "version": 116.0, "os": "win10"} -{"percent": 0.6, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36", "system": "Edge 117.0 Win10", "browser": "edge", "version": 117.0, "os": "win10"} -{"percent": 0.6, "useragent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36", "system": "Chrome 115.0 Linux", "browser": "chrome", "version": 115.0, "os": "linux"} -{"percent": 0.6, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0", "system": "Firefox 116.0 Win10", "browser": "firefox", "version": 116.0, "os": "win10"} -{"percent": 0.6, "useragent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0", "system": "Firefox 118.0 Linux", "browser": "firefox", "version": 118.0, "os": "linux"} -{"percent": 0.5, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "system": "Safari Generic macOS", "browser": "safari", "version": 1.0, "os": "macos"} -{"percent": 0.5, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.43", "system": "Edge 117.0 Win10", "browser": "edge", "version": 117.0, "os": "win10"} -{"percent": 0.5, "useragent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0", "system": "Firefox 102.0 Linux", "browser": "firefox", "version": 102.0, "os": "linux"} -{"percent": 0.5, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/118.0", "system": "Firefox 118.0 macOS", "browser": "firefox", "version": 118.0, "os": "macos"} -{"percent": 0.4, "useragent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0", "system": "Firefox 116.0 Linux", "browser": "firefox", "version": 116.0, "os": "linux"} -{"percent": 0.4, "useragent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36", "system": "Chrome 77.0 Linux", "browser": "chrome", "version": 77.0, "os": "linux"} -{"percent": 0.4, "useragent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0", "system": "Firefox 115.0 Linux", "browser": "firefox", "version": 115.0, "os": "linux"} -{"percent": 0.4, "useragent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0", "system": "Firefox 115.0 Win7", "browser": "firefox", "version": 115.0, "os": "win7"} -{"percent": 0.4, "useragent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0", "system": "Firefox 102.0 Win10", "browser": "firefox", "version": 102.0, "os": "win10"} -{"percent": 0.4, "useragent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0", "system": "Firefox 116.0 Linux", "browser": "firefox", "version": 116.0, "os": "linux"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "system": "Chrome 114.0 macOS", "browser": "chrome", "version": 114.0, "os": "macos"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0", "system": "Firefox 102.0 Win10", "browser": "firefox", "version": 102.0, "os": "win10"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36", "system": "Chrome 113.0 Win10", "browser": "chrome", "version": 113.0, "os": "win10"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.62", "system": "Edge 116.0 Win10", "browser": "edge", "version": 116.0, "os": "win10"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0", "system": "Firefox 115.0 Win10", "browser": "firefox", "version": 115.0, "os": "win10"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.2 Safari/605.1.15", "system": "Safari Generic macOS", "browser": "safari", "version": 1.0, "os": "macos"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.41", "system": "Edge 117.0 Win10", "browser": "edge", "version": 117.0, "os": "win10"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "system": "Chrome 114.0 Linux", "browser": "chrome", "version": 114.0, "os": "linux"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0", "system": "Firefox 116.0 macOS", "browser": "firefox", "version": 116.0, "os": "macos"} -{"percent": 0.3, "useragent": "Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/118.0", "system": "Firefox 118.0 Win10", "browser": "firefox", "version": 118.0, "os": "win10"} -{"percent": 0.2, "useragent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", "system": "Chrome 109.0 Win7", "browser": "chrome", "version": 109.0, "os": "win7"} -{"percent": 0.2, "useragent": "Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", "system": "Chrome 116.0 ChromeOS", "browser": "chrome", "version": 116.0, "os": "chromeos"} -{"percent": 0.2, "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", "system": "Chrome 112.0 Win10", "browser": "chrome", "version": 112.0, "os": "win10"} -{"percent": 0.2, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15", "system": "Safari Generic macOS", "browser": "safari", "version": 1.0, "os": "macos"} -{"percent": 0.2, "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15", "system": "Safari Generic macOS", "browser": "safari", "version": 1.0, "os": "macos"} diff --git a/src/linktools/cli/commands/android/agent.py b/src/linktools/cli/commands/android/agent.py index 7dac8f90..6aca2d8b 100755 --- a/src/linktools/cli/commands/android/agent.py +++ b/src/linktools/cli/commands/android/agent.py @@ -34,6 +34,22 @@ from linktools.cli import AndroidCommand, CommandError +class AgentDevice(Device): + + def get_agent_path(self, *name: str) -> str: + return self.get_data_path("agent", *name) + + def push_agent_plugin(self, src_path: str = None) -> Optional[str]: + if not src_path: + return None + if not os.path.exists(src_path): + raise CommandError(f"Plugin file not found: {src_path}") + dest_name = os.path.basename(src_path) + dest_path = self.get_agent_path("plugin", dest_name) + self.push(src_path, dest_path) + return dest_path + + class Command(AndroidCommand): """ Debug and interact with android-tools.apk for troubleshooting @@ -53,32 +69,23 @@ def init_arguments(self, parser: ArgumentParser) -> None: parser.add_argument("agent_args", nargs="...", help="agent args") def run(self, args: Namespace) -> Optional[int]: - device = args.device_picker.pick() - - process = device.popen( - *device.make_shell_args( - *device.make_agent_args( - *args.agent_args, - data_path=args.data or device.get_data_path('agent', 'data'), - library_path=args.library, - plugin_path=self._push_plugin(device, args.plugin), - ), - privilege=args.privilege, - user=args.user - ) + device = args.device_picker.pick().copy(AgentDevice) + + agent_args = device.make_agent_args( + *args.agent_args, + data_path=args.data or device.get_agent_path("data"), + library_path=args.library or device.get_agent_path("data", "lib"), + plugin_path=device.push_agent_plugin(args.plugin), ) - return process.call() - @classmethod - def _push_plugin(cls, device: Device, path: str = None) -> Optional[str]: - if not path: - return None - if not os.path.exists(path): - raise CommandError(f"Plugin file not found: {path}") - plugin_name = os.path.basename(path) - plugin_path = device.get_data_path("agent", "plugin", plugin_name) - device.push(path, plugin_path) - return plugin_path + shell_args = device.make_shell_args( + *agent_args, + privilege=args.privilege, + user=args.user + ) + + process = device.popen(*shell_args) + return process.call() command = Command() diff --git a/src/linktools/ios/sib.py b/src/linktools/ios/sib.py index 9e5ad568..bc996119 100644 --- a/src/linktools/ios/sib.py +++ b/src/linktools/ios/sib.py @@ -5,7 +5,7 @@ import subprocess import time from subprocess import TimeoutExpired -from typing import Any, Generator, List +from typing import Any, Generator, List, Callable, Dict, TYPE_CHECKING, TypeVar from .struct import Process, App from .. import utils @@ -14,6 +14,9 @@ from ..device import BridgeError, Bridge, BaseDevice from ..reactor import Stoppable +if TYPE_CHECKING: + DEVICE_TYPE = TypeVar("DEVICE_TYPE", bound="Device") + _logger = environ.get_logger("android.adb") @@ -49,7 +52,7 @@ def list_devices(self, alive: bool = None) -> Generator["Device", None, None]: class Device(BaseDevice): - def __init__(self, id: str = None, info: dict = None, sib: Sib = None): + def __init__(self, id: str = None, info: Dict = None, sib: Sib = None): """ :param id: 设备号 """ @@ -103,6 +106,9 @@ def info(self) -> dict: def detail(self) -> dict: return self.info.get("deviceDetail") + def copy(self, type: "Callable[[str, Dict, Sib], DEVICE_TYPE]" = None) -> "DEVICE_TYPE": + return (type or Device)(self._id, self._info, self._sib) + def popen(self, *args: [Any], **kwargs) -> utils.Process: """ 执行命令 diff --git a/src/linktools/references/fake_useragent/fake.py b/src/linktools/references/fake_useragent/fake.py index 2c508159..be8091dc 100644 --- a/src/linktools/references/fake_useragent/fake.py +++ b/src/linktools/references/fake_useragent/fake.py @@ -7,13 +7,19 @@ class FakeUserAgent: - def __init__( + def __init__( # noqa: PLR0913 self, path, browsers=["chrome", "edge", "firefox", "safari"], - os=["windows", "macos", "linux"], + os=["windows", "macos", "linux", "android", "ios"], + min_version=0.0, min_percentage=0.0, - fallback="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + platforms=["pc", "mobile", "tablet"], + fallback=( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0" + ), safe_attrs=tuple(), ): # Check inputs @@ -34,10 +40,24 @@ def __init__( self.os.append(os_name) assert isinstance( - min_percentage, float - ), "Minimum usage percentage must be float" + min_percentage, (float, int) + ), "Minimum usage percentage must be float or int" + if isinstance(min_percentage, int): + min_percentage = float(min_percentage) self.min_percentage = min_percentage + assert isinstance( + min_version, (float, int) + ), "Minimum version must be float or int" + if isinstance(min_version, int): + min_version = float(min_version) + self.min_version = min_version + + assert isinstance(platforms, (list, str)), "platforms must be list or string" + if isinstance(platforms, str): + platforms = [platforms] + self.platforms = platforms + assert isinstance(fallback, str), "fallback must be string" self.fallback = fallback @@ -56,6 +76,28 @@ def __init__( # Next, load our local data file into memory (browsers.json) self.data_browsers = load(path) + # This method will return a filtered list of user agents. + # The request parameter can be used to specify a browser. + def _filter_useragents(self, request=None): + # filter based on browser, os, platform and version. + filtered_useragents = list( + filter( + lambda x: x["browser"] in self.browsers + and x["os"] in self.os + and x["type"] in self.platforms + and x["version"] >= self.min_version + and x["percent"] >= self.min_percentage, + self.data_browsers, + ) + ) + # filter based on a specific browser request + if request: + filtered_useragents = list( + filter(lambda x: x["browser"] == request, filtered_useragents) + ) + + return filtered_useragents + # This method will return an object # Usage: ua.getBrowser('firefox') def getBrowser(self, request): @@ -71,27 +113,13 @@ def getBrowser(self, request): # And based on OS list # And percentage is bigger then min percentage # And convert the iterator back to a list - filtered_browsers = list( - filter( - lambda x: x["browser"] in self.browsers - and x["os"] in self.os - and x["percent"] >= self.min_percentage, - self.data_browsers, - ) - ) + filtered_browsers = self._filter_useragents() else: # Or when random isn't select, we filter the browsers array based on the 'request' using lamba # And based on OS list # And percentage is bigger then min percentage # And convert the iterator back to a list - filtered_browsers = list( - filter( - lambda x: x["browser"] == request - and x["os"] in self.os - and x["percent"] >= self.min_percentage, - self.data_browsers, - ) - ) + filtered_browsers = self._filter_useragents(request=request) # Pick a random browser user-agent from the filtered browsers # And return the full dict @@ -109,9 +137,9 @@ def getBrowser(self, request): # Return fallback object return { "useragent": self.fallback, - "system": "Chrome 114.0 Win10", + "system": "Chrome 122.0 Win10", "browser": "chrome", - "version": 114.0, + "version": 122.0, "os": "win10", } @@ -124,7 +152,7 @@ def __getitem__(self, attr): # Usage: ua.random def __getattr__(self, attr): if attr in self.safe_attrs: - return super(UserAgent, self).__getattr__(attr) + return super(UserAgent, self).__getattribute__(attr) try: # Handle input value @@ -138,27 +166,13 @@ def __getattr__(self, attr): # And based on OS list # And percentage is bigger then min percentage # And convert the iterator back to a list - filtered_browsers = list( - filter( - lambda x: x["browser"] in self.browsers - and x["os"] in self.os - and x["percent"] >= self.min_percentage, - self.data_browsers, - ) - ) + filtered_browsers = self._filter_useragents() else: # Or when random isn't select, we filter the browsers array based on the 'attr' using lamba # And based on OS list # And percentage is bigger then min percentage # And convert the iterator back to a list - filtered_browsers = list( - filter( - lambda x: x["browser"] == attr - and x["os"] in self.os - and x["percent"] >= self.min_percentage, - self.data_browsers, - ) - ) + filtered_browsers = self._filter_useragents(request=attr) # Pick a random browser user-agent from the filtered browsers # And return the useragent string. diff --git a/src/linktools/references/fake_useragent/settings.py b/src/linktools/references/fake_useragent/settings.py index 1a7fe6ed..137ad65e 100644 --- a/src/linktools/references/fake_useragent/settings.py +++ b/src/linktools/references/fake_useragent/settings.py @@ -1,5 +1,10 @@ +try: + from importlib import metadata +except ImportError: + # Running on pre-3.8 Python; use importlib-metadata package + import importlib_metadata as metadata -__version__ = "1.4.0" +__version__ = "1.5.1" REPLACEMENTS = { " ": "", diff --git a/src/linktools/references/fake_useragent/utils.py b/src/linktools/references/fake_useragent/utils.py index 9599fe3e..82f172c6 100644 --- a/src/linktools/references/fake_useragent/utils.py +++ b/src/linktools/references/fake_useragent/utils.py @@ -1,5 +1,7 @@ import json +from .log import logger + str_types = (str,) @@ -7,11 +9,36 @@ # Returns array of objects def load(path): data, ret = [], None - with open(path) as file: - json_lines = file.read() + try: + with open(path, "rt") as fd: + json_lines = fd.read() for line in json_lines.splitlines(): data.append(json.loads(line)) - ret = data + ret = data + except Exception as exc: + # Empty data just to be sure + data = [] + logger.warning( + "Unable to find local data/json file or could not parse the contents using importlib-resources. Try pkg-resource next.", + exc_info=exc, + ) + try: + from pkg_resources import resource_filename + + with open( + resource_filename("fake_useragent", "data/browsers.json") + ) as file: + json_lines = file.read() + for line in json_lines.splitlines(): + data.append(json.loads(line)) + ret = data + except Exception as exc2: + # Empty data just to be sure + data = [] + logger.warning( + "Could not find local data/json file or could not parse the contents using pkg-resource.", + exc_info=exc2, + ) if not ret: raise FakeUserAgentError("Data list is empty", ret) diff --git a/src/linktools/utils/_utils.py b/src/linktools/utils/_utils.py index 83e887df..fe31ed4a 100755 --- a/src/linktools/utils/_utils.py +++ b/src/linktools/utils/_utils.py @@ -569,7 +569,7 @@ class _UserAgent(UserAgent): def __init__(self): super().__init__( - path=environ.get_asset_path(f"fake_useragent.json"), + path=environ.get_asset_path(f"browsers.json"), fallback=environ.get_config("DEFAULT_USER_AGENT", type=str), )