pyaterochka-api 0.1.2__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/PKG-INFO +12 -3
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/README.md +11 -2
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api/__init__.py +2 -2
- pyaterochka_api-0.1.3/pyaterochka_api/api.py +146 -0
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api/manager.py +31 -10
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api.egg-info/PKG-INFO +12 -3
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/setup.py +1 -1
- pyaterochka_api-0.1.2/pyaterochka_api/api.py +0 -116
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/LICENSE +0 -0
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api.egg-info/SOURCES.txt +0 -0
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api.egg-info/dependency_links.txt +0 -0
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api.egg-info/requires.txt +0 -0
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api.egg-info/top_level.txt +0 -0
- {pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyaterochka_api
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: A Python API client for Pyaterochka store catalog
|
5
5
|
Home-page: https://github.com/Open-Inflation/pyaterochka_api
|
6
6
|
Author: Miskler
|
@@ -32,13 +32,22 @@ async def main():
|
|
32
32
|
# RUS: Выводит список всех товаров выбранной категории (ограничение 100 элементов, если превышает - запрашивайте через дополнительные страницы)
|
33
33
|
# ENG: Outputs a list of all items in the selected category (limiting to 100 elements, if exceeds - request through additional pages)
|
34
34
|
# Страниц не сущетвует, использовать желаемый лимит (до 499) / Pages do not exist, use the desired limit (up to 499)
|
35
|
-
|
35
|
+
items = await pyaterochka_api.products_list(catalog[0]['id'], limit=5)
|
36
|
+
print(f"Items list output: {items!s:.100s}...\n")
|
36
37
|
|
37
38
|
# RUS: Выводит основной конфиг сайта (очень долгая функция, рекомендую сохранять в файл и переиспользовать)
|
38
39
|
# ENG: Outputs the main config of the site (large function, recommend to save in a file and re-use it)
|
40
|
+
print(f"Main config: {await pyaterochka_api.get_config()!s:.100s}...\n")
|
41
|
+
|
39
42
|
# RUS: Если требуется, можно настроить вывод логов в консоль
|
40
43
|
# ENG: If required, you can configure the output of logs in the console
|
41
|
-
|
44
|
+
pyaterochka_api.set_debug(True)
|
45
|
+
|
46
|
+
# RUS: Скачивает картинку товара (возвращает BytesIO или None)
|
47
|
+
# ENG: Downloads the product image (returns BytesIO or None)
|
48
|
+
image = await pyaterochka_api.download_image(url=items['products'][0]['image_links']['normal'][0])
|
49
|
+
with open(image.name, 'wb') as f:
|
50
|
+
f.write(image.getbuffer())
|
42
51
|
|
43
52
|
|
44
53
|
if __name__ == '__main__':
|
@@ -17,13 +17,22 @@ async def main():
|
|
17
17
|
# RUS: Выводит список всех товаров выбранной категории (ограничение 100 элементов, если превышает - запрашивайте через дополнительные страницы)
|
18
18
|
# ENG: Outputs a list of all items in the selected category (limiting to 100 elements, if exceeds - request through additional pages)
|
19
19
|
# Страниц не сущетвует, использовать желаемый лимит (до 499) / Pages do not exist, use the desired limit (up to 499)
|
20
|
-
|
20
|
+
items = await pyaterochka_api.products_list(catalog[0]['id'], limit=5)
|
21
|
+
print(f"Items list output: {items!s:.100s}...\n")
|
21
22
|
|
22
23
|
# RUS: Выводит основной конфиг сайта (очень долгая функция, рекомендую сохранять в файл и переиспользовать)
|
23
24
|
# ENG: Outputs the main config of the site (large function, recommend to save in a file and re-use it)
|
25
|
+
print(f"Main config: {await pyaterochka_api.get_config()!s:.100s}...\n")
|
26
|
+
|
24
27
|
# RUS: Если требуется, можно настроить вывод логов в консоль
|
25
28
|
# ENG: If required, you can configure the output of logs in the console
|
26
|
-
|
29
|
+
pyaterochka_api.set_debug(True)
|
30
|
+
|
31
|
+
# RUS: Скачивает картинку товара (возвращает BytesIO или None)
|
32
|
+
# ENG: Downloads the product image (returns BytesIO or None)
|
33
|
+
image = await pyaterochka_api.download_image(url=items['products'][0]['image_links']['normal'][0])
|
34
|
+
with open(image.name, 'wb') as f:
|
35
|
+
f.write(image.getbuffer())
|
27
36
|
|
28
37
|
|
29
38
|
if __name__ == '__main__':
|
@@ -1,3 +1,3 @@
|
|
1
|
-
from .manager import PurchaseMode, categories_list, products_list, get_config
|
1
|
+
from .manager import PurchaseMode, categories_list, products_list, get_config, download_image, PyaterochkaAPI, set_debug
|
2
2
|
|
3
|
-
__all__ = ['PurchaseMode', 'categories_list', 'products_list', 'get_config']
|
3
|
+
__all__ = ['PurchaseMode', 'categories_list', 'products_list', 'get_config', 'download_image', 'PyaterochkaAPI', 'set_debug']
|
@@ -0,0 +1,146 @@
|
|
1
|
+
import aiohttp
|
2
|
+
from fake_useragent import UserAgent
|
3
|
+
from enum import Enum
|
4
|
+
import re
|
5
|
+
from tqdm.asyncio import tqdm
|
6
|
+
|
7
|
+
|
8
|
+
class PyaterochkaAPI:
|
9
|
+
"""
|
10
|
+
Класс для загрузки JSON/image и парсинга JavaScript-конфигураций из удаленного источника.
|
11
|
+
"""
|
12
|
+
|
13
|
+
class Patterns(Enum):
|
14
|
+
JS = r'\s*let\s+n\s*=\s*({.*});\s*' # let n = {...};
|
15
|
+
STR = r'(\w+)\s*:\s*"([^"\\]*(?:\\.[^"\\]*)*)"' # key: "value"
|
16
|
+
DICT = r'(\w+)\s*:\s*{(.*?)}' # key: {...}
|
17
|
+
LIST = r'(\w+)\s*:\s*\[([^\[\]]*(?:\[.*?\])*)\]' # key: [value]
|
18
|
+
FIND = r'\{.*?\}|\[.*?\]' # {} or []
|
19
|
+
|
20
|
+
def __init__(self, debug: bool = False):
|
21
|
+
self._debug = False
|
22
|
+
|
23
|
+
def set_debug(self, debug: bool):
|
24
|
+
"""Устанавливает режим дебага для экземпляра класса."""
|
25
|
+
self._debug = debug
|
26
|
+
|
27
|
+
async def fetch(self, url: str) -> tuple[bool, dict | None | str, str]:
|
28
|
+
"""
|
29
|
+
Выполняет HTTP-запрос к указанному URL и возвращает результат.
|
30
|
+
|
31
|
+
:param url: URL для запроса.
|
32
|
+
:param is_json: Ожидать ли JSON в ответе.
|
33
|
+
:return: Кортеж (успех, данные или None).
|
34
|
+
"""
|
35
|
+
async with aiohttp.ClientSession() as session:
|
36
|
+
|
37
|
+
if self._debug:
|
38
|
+
print(f"Requesting \"{url}\"...", flush=True)
|
39
|
+
|
40
|
+
async with session.get(
|
41
|
+
url=url,
|
42
|
+
headers={"User-Agent": UserAgent().random},
|
43
|
+
) as response:
|
44
|
+
if self._debug:
|
45
|
+
print(f"Response status: {response.status}", flush=True)
|
46
|
+
|
47
|
+
if response.status == 200:
|
48
|
+
if response.headers['content-type'] == 'application/json':
|
49
|
+
output_response = response.json()
|
50
|
+
elif response.headers['content-type'] == 'image/jpeg':
|
51
|
+
output_response = response.read()
|
52
|
+
else:
|
53
|
+
output_response = response.text()
|
54
|
+
|
55
|
+
return True, await output_response, response.headers['content-type']
|
56
|
+
elif response.status == 403:
|
57
|
+
if self._debug:
|
58
|
+
print("Anti-bot protection. Use Russia IP address and try again.", flush=True)
|
59
|
+
return False, None, ''
|
60
|
+
else:
|
61
|
+
if self._debug:
|
62
|
+
print(f"Unexpected error: {response.status}", flush=True)
|
63
|
+
raise Exception(f"Response status: {response.status} (unknown error/status code)")
|
64
|
+
|
65
|
+
async def _parse_js(self, js_code: str) -> dict | None:
|
66
|
+
"""
|
67
|
+
Парсит JavaScript-код и извлекает данные из переменной "n".
|
68
|
+
|
69
|
+
:param js_code: JS-код в виде строки.
|
70
|
+
:return: Распарсенные данные в виде словаря или None.
|
71
|
+
"""
|
72
|
+
matches = re.finditer(self.Patterns.JS.value, js_code)
|
73
|
+
match_list = list(matches)
|
74
|
+
|
75
|
+
if self._debug:
|
76
|
+
print(f"Found matches {len(match_list)}")
|
77
|
+
progress_bar = tqdm(total=33, desc="Parsing JS", position=0)
|
78
|
+
|
79
|
+
async def parse_match(match: str) -> dict:
|
80
|
+
result = {}
|
81
|
+
|
82
|
+
if self._debug:
|
83
|
+
progress_bar.set_description("Parsing strings")
|
84
|
+
|
85
|
+
# Парсинг строк
|
86
|
+
string_matches = re.finditer(self.Patterns.STR.value, match)
|
87
|
+
for m in string_matches:
|
88
|
+
key, value = m.group(1), m.group(2)
|
89
|
+
result[key] = value.replace('\"', '"').replace('\\', '\\')
|
90
|
+
|
91
|
+
if self._debug:
|
92
|
+
progress_bar.update(1)
|
93
|
+
progress_bar.set_description("Parsing dictionaries")
|
94
|
+
|
95
|
+
# Парсинг словарей
|
96
|
+
dict_matches = re.finditer(self.Patterns.DICT.value, match)
|
97
|
+
for m in dict_matches:
|
98
|
+
key, value = m.group(1), m.group(2)
|
99
|
+
if not re.search(self.Patterns.STR.value, value):
|
100
|
+
result[key] = await parse_match(value)
|
101
|
+
|
102
|
+
if self._debug:
|
103
|
+
progress_bar.update(1)
|
104
|
+
progress_bar.set_description("Parsing lists")
|
105
|
+
|
106
|
+
# Парсинг списков
|
107
|
+
list_matches = re.finditer(self.Patterns.LIST.value, match)
|
108
|
+
for m in list_matches:
|
109
|
+
key, value = m.group(1), m.group(2)
|
110
|
+
if not re.search(self.Patterns.STR.value, value):
|
111
|
+
result[key] = [await parse_match(item.group(0)) for item in re.finditer(self.Patterns.FIND.value, value)]
|
112
|
+
|
113
|
+
if self._debug:
|
114
|
+
progress_bar.update(1)
|
115
|
+
|
116
|
+
return result
|
117
|
+
|
118
|
+
if match_list and len(match_list) >= 1:
|
119
|
+
if self._debug:
|
120
|
+
print("Starting to parse match")
|
121
|
+
result = await parse_match(match_list[1].group(0))
|
122
|
+
if self._debug:
|
123
|
+
progress_bar.close()
|
124
|
+
return result
|
125
|
+
else:
|
126
|
+
if self._debug:
|
127
|
+
progress_bar.close()
|
128
|
+
raise Exception("N variable in JS code not found")
|
129
|
+
|
130
|
+
async def download_config(self, config_url: str) -> dict | None:
|
131
|
+
"""
|
132
|
+
Загружает и парсит JavaScript-конфигурацию с указанного URL.
|
133
|
+
|
134
|
+
:param config_url: URL для загрузки конфигурации.
|
135
|
+
:return: Распарсенные данные в виде словаря или None.
|
136
|
+
"""
|
137
|
+
is_success, js_code, _response_type = await self.fetch(url=config_url)
|
138
|
+
|
139
|
+
if not is_success:
|
140
|
+
if self._debug:
|
141
|
+
print("Failed to fetch JS code")
|
142
|
+
return None
|
143
|
+
elif self._debug:
|
144
|
+
print("JS code fetched successfully")
|
145
|
+
|
146
|
+
return await self._parse_js(js_code=js_code)
|
@@ -1,5 +1,7 @@
|
|
1
|
-
from .api import
|
1
|
+
from .api import PyaterochkaAPI as ClassPyaterochkaAPI
|
2
2
|
from enum import Enum
|
3
|
+
from io import BytesIO
|
4
|
+
|
3
5
|
|
4
6
|
CATALOG_URL = "https://5d.5ka.ru/api/catalog/v2/stores"
|
5
7
|
HARDCODE_JS_CONFIG = "https://prod-cdn.5ka.ru/scripts/main.a0c039ea81eb8cf69492.js" # TODO сделать не хардкодным имя файла
|
@@ -9,11 +11,13 @@ class PurchaseMode(Enum):
|
|
9
11
|
DELIVERY = "delivery"
|
10
12
|
|
11
13
|
|
14
|
+
PyaterochkaAPI = ClassPyaterochkaAPI(debug=False)
|
15
|
+
|
16
|
+
|
12
17
|
async def categories_list(
|
13
18
|
subcategories: bool = False,
|
14
19
|
mode: PurchaseMode = PurchaseMode.STORE,
|
15
|
-
sap_code_store_id: str = "Y232"
|
16
|
-
debug: bool = False
|
20
|
+
sap_code_store_id: str = "Y232"
|
17
21
|
) -> dict | None:
|
18
22
|
"""
|
19
23
|
Asynchronously retrieves a list of categories from the Pyaterochka API.
|
@@ -32,16 +36,14 @@ async def categories_list(
|
|
32
36
|
"""
|
33
37
|
|
34
38
|
request_url = f"{CATALOG_URL}/{sap_code_store_id}/categories?mode={mode.value}&include_subcategories={1 if subcategories else 0}"
|
35
|
-
|
39
|
+
_is_success, response, _response_type = await PyaterochkaAPI.fetch(url=request_url)
|
36
40
|
return response
|
37
41
|
|
38
|
-
|
39
42
|
async def products_list(
|
40
43
|
category_id: int,
|
41
44
|
mode: PurchaseMode = PurchaseMode.STORE,
|
42
45
|
sap_code_store_id: str = "Y232",
|
43
|
-
limit: int = 30
|
44
|
-
debug: bool = False
|
46
|
+
limit: int = 30
|
45
47
|
) -> dict | None:
|
46
48
|
"""
|
47
49
|
Asynchronously retrieves a list of products from the Pyaterochka API for a given category.
|
@@ -64,11 +66,25 @@ async def products_list(
|
|
64
66
|
raise ValueError("Limit must be between 1 and 499")
|
65
67
|
|
66
68
|
request_url = f"{CATALOG_URL}/{sap_code_store_id}/categories/{category_id}/products?mode={mode.value}&limit={limit}"
|
67
|
-
|
69
|
+
_is_success, response, _response_type = await PyaterochkaAPI.fetch(url=request_url)
|
68
70
|
return response
|
69
71
|
|
72
|
+
async def download_image(url: str) -> BytesIO | None:
|
73
|
+
is_success, image_data, response_type = await PyaterochkaAPI.fetch(url=url)
|
74
|
+
|
75
|
+
if not is_success:
|
76
|
+
if PyaterochkaAPI._debug:
|
77
|
+
print("Failed to fetch image")
|
78
|
+
return None
|
79
|
+
elif PyaterochkaAPI._debug:
|
80
|
+
print("Image fetched successfully")
|
70
81
|
|
71
|
-
|
82
|
+
image = BytesIO(image_data)
|
83
|
+
image.name = f'{url.split("/")[-1]}.{response_type.split("/")[-1]}'
|
84
|
+
|
85
|
+
return image
|
86
|
+
|
87
|
+
async def get_config() -> list | None:
|
72
88
|
"""
|
73
89
|
Asynchronously retrieves the configuration from the hardcoded JavaScript file.
|
74
90
|
|
@@ -79,4 +95,9 @@ async def get_config(debug: bool = False) -> list | None:
|
|
79
95
|
list | None: A list representing the configuration if the request is successful, None otherwise.
|
80
96
|
"""
|
81
97
|
|
82
|
-
return await
|
98
|
+
return await PyaterochkaAPI.download_config(config_url=HARDCODE_JS_CONFIG)
|
99
|
+
|
100
|
+
|
101
|
+
def set_debug(debug: bool) -> None:
|
102
|
+
PyaterochkaAPI.set_debug(debug=debug)
|
103
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyaterochka-api
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: A Python API client for Pyaterochka store catalog
|
5
5
|
Home-page: https://github.com/Open-Inflation/pyaterochka_api
|
6
6
|
Author: Miskler
|
@@ -32,13 +32,22 @@ async def main():
|
|
32
32
|
# RUS: Выводит список всех товаров выбранной категории (ограничение 100 элементов, если превышает - запрашивайте через дополнительные страницы)
|
33
33
|
# ENG: Outputs a list of all items in the selected category (limiting to 100 elements, if exceeds - request through additional pages)
|
34
34
|
# Страниц не сущетвует, использовать желаемый лимит (до 499) / Pages do not exist, use the desired limit (up to 499)
|
35
|
-
|
35
|
+
items = await pyaterochka_api.products_list(catalog[0]['id'], limit=5)
|
36
|
+
print(f"Items list output: {items!s:.100s}...\n")
|
36
37
|
|
37
38
|
# RUS: Выводит основной конфиг сайта (очень долгая функция, рекомендую сохранять в файл и переиспользовать)
|
38
39
|
# ENG: Outputs the main config of the site (large function, recommend to save in a file and re-use it)
|
40
|
+
print(f"Main config: {await pyaterochka_api.get_config()!s:.100s}...\n")
|
41
|
+
|
39
42
|
# RUS: Если требуется, можно настроить вывод логов в консоль
|
40
43
|
# ENG: If required, you can configure the output of logs in the console
|
41
|
-
|
44
|
+
pyaterochka_api.set_debug(True)
|
45
|
+
|
46
|
+
# RUS: Скачивает картинку товара (возвращает BytesIO или None)
|
47
|
+
# ENG: Downloads the product image (returns BytesIO or None)
|
48
|
+
image = await pyaterochka_api.download_image(url=items['products'][0]['image_links']['normal'][0])
|
49
|
+
with open(image.name, 'wb') as f:
|
50
|
+
f.write(image.getbuffer())
|
42
51
|
|
43
52
|
|
44
53
|
if __name__ == '__main__':
|
@@ -1,116 +0,0 @@
|
|
1
|
-
import aiohttp
|
2
|
-
from fake_useragent import UserAgent
|
3
|
-
from enum import Enum
|
4
|
-
import re
|
5
|
-
from tqdm.asyncio import tqdm
|
6
|
-
|
7
|
-
|
8
|
-
class Patterns(Enum):
|
9
|
-
JS = r'\s*let\s+n\s*=\s*({.*});\s*'
|
10
|
-
STR = r'(\w+)\s*:\s*"([^"\\]*(?:\\.[^"\\]*)*)"'
|
11
|
-
DICT = r'(\w+)\s*:\s*{(.*?)}'
|
12
|
-
LIST = r'(\w+)\s*:\s*\[([^\[\]]*(?:\[.*?\])*)\]'
|
13
|
-
FIND = r'\{.*?\}|\[.*?\]'
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
async def main_fetch(url: str, debug: bool = False, is_json: bool = True) -> tuple[bool, dict | None]:
|
18
|
-
async with aiohttp.ClientSession() as session:
|
19
|
-
if debug:
|
20
|
-
print(f"Requesting \"{url}\"...", flush=True)
|
21
|
-
|
22
|
-
async with session.get(
|
23
|
-
url=url,
|
24
|
-
headers={"User-Agent": UserAgent().random},
|
25
|
-
) as response:
|
26
|
-
if debug:
|
27
|
-
print(f"Response status: {response.status}", flush=True)
|
28
|
-
|
29
|
-
if response.status == 200: # 200 OK
|
30
|
-
if debug:
|
31
|
-
print("Correct response", flush=True)
|
32
|
-
return True, await response.json() if is_json else await response.text()
|
33
|
-
elif response.status == 403: # 403 Forbidden (сервер воспринял как бота)
|
34
|
-
if debug:
|
35
|
-
print("Anti-bot protection. Use Russia IP address and try again.", flush=True)
|
36
|
-
return False, None
|
37
|
-
else:
|
38
|
-
if debug:
|
39
|
-
print(f"Please, create issue on GitHub", flush=True)
|
40
|
-
raise Exception(f"Response status: {response.status} (unknown error/status code)")
|
41
|
-
|
42
|
-
async def download_hardcode_config(config_url: str, debug: bool = False) -> dict | None:
|
43
|
-
is_success, js_code = await main_fetch(url=config_url, debug=debug, is_json=False)
|
44
|
-
|
45
|
-
if not is_success:
|
46
|
-
if debug:
|
47
|
-
print("Failed to fetch JS code")
|
48
|
-
return None
|
49
|
-
elif debug:
|
50
|
-
print("JS code fetched successfully")
|
51
|
-
|
52
|
-
# Регулярное выражение для извлечения определения переменной n
|
53
|
-
matches = re.finditer(Patterns.JS.value, js_code)
|
54
|
-
|
55
|
-
match_list = list(matches)
|
56
|
-
if debug:
|
57
|
-
print(f"Found matches {len(match_list)}")
|
58
|
-
|
59
|
-
if debug:
|
60
|
-
progress_bar = tqdm(total=33, desc="Parsing JS", position=0) # примерно 33 операции
|
61
|
-
|
62
|
-
async def parse_match(match: str) -> dict:
|
63
|
-
result = {}
|
64
|
-
|
65
|
-
if debug:
|
66
|
-
# Обновление описания прогресса
|
67
|
-
progress_bar.set_description("Parsing strings")
|
68
|
-
|
69
|
-
# Парсинг строк
|
70
|
-
string_matches = re.finditer(Patterns.STR.value, match)
|
71
|
-
for m in string_matches:
|
72
|
-
key, value = m.group(1), m.group(2)
|
73
|
-
result[key] = value.replace('\"', '"').replace('\\\\', '\\')
|
74
|
-
|
75
|
-
if debug:
|
76
|
-
progress_bar.update(1)
|
77
|
-
# Обновление описания прогресса
|
78
|
-
progress_bar.set_description("Parsing dictionaries")
|
79
|
-
|
80
|
-
# Парсинг словарей
|
81
|
-
dict_matches = re.finditer(Patterns.DICT.value, match)
|
82
|
-
for m in dict_matches:
|
83
|
-
key, value = m.group(1), m.group(2)
|
84
|
-
if not re.search(Patterns.STR.value, value):
|
85
|
-
result[key] = await parse_match(value)
|
86
|
-
|
87
|
-
if debug:
|
88
|
-
progress_bar.update(1)
|
89
|
-
# Обновление описания прогресса
|
90
|
-
progress_bar.set_description("Parsing lists")
|
91
|
-
|
92
|
-
# Парсинг списков
|
93
|
-
list_matches = re.finditer(Patterns.LIST.value, match)
|
94
|
-
for m in list_matches:
|
95
|
-
key, value = m.group(1), m.group(2)
|
96
|
-
if not re.search(Patterns.STR.value, value):
|
97
|
-
result[key] = [await parse_match(item.group(0)) for item in re.finditer(Patterns.FIND.value, value)]
|
98
|
-
|
99
|
-
if debug:
|
100
|
-
# Обновление прогресса
|
101
|
-
progress_bar.update(1)
|
102
|
-
|
103
|
-
return result
|
104
|
-
|
105
|
-
if match_list and len(match_list) >= 1: # нужная переменная идет второй из трех
|
106
|
-
if debug:
|
107
|
-
print("Starting to parse match")
|
108
|
-
result = await parse_match(match_list[1].group(0))
|
109
|
-
if debug:
|
110
|
-
progress_bar.close()
|
111
|
-
return result
|
112
|
-
else:
|
113
|
-
if debug:
|
114
|
-
progress_bar.close()
|
115
|
-
raise Exception("N variable in JS code not found")
|
116
|
-
|
File without changes
|
File without changes
|
{pyaterochka_api-0.1.2 → pyaterochka_api-0.1.3}/pyaterochka_api.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|