bugfix + postprocessing
This commit is contained in:
@ -54,12 +54,15 @@ class CraftFacade:
|
|||||||
all_links: set[str] = set()
|
all_links: set[str] = set()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
links = simple_extractor.extract_crafts(soup, storage)
|
links = simple_extractor.extract_crafts(soup, storage)
|
||||||
all_links.update(links)
|
all_links.update(links)
|
||||||
links = device_extractor.extract_crafts(soup, storage)
|
|
||||||
all_links.update(all_links)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f'Ошибка в парсере: {e}')
|
logger.error(f'Ошибка в простом парсере: {e}')
|
||||||
|
try:
|
||||||
|
links = device_extractor.extract_crafts(soup, storage)
|
||||||
|
all_links.update(all_links)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'Ошибка в машинном парсере: {e}')
|
||||||
|
|
||||||
logger.info(f'Готово: {url}')
|
logger.info(f'Готово: {url}')
|
||||||
|
|
||||||
|
|||||||
@ -21,31 +21,36 @@ def extract_crafts(soup: BeautifulSoup, storage: CraftStorage) -> set[str]:
|
|||||||
if(is_hidden):
|
if(is_hidden):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
output_item = parse_craft_item(container)
|
output_items = parse_craft_items(container)
|
||||||
# Получаем список рецептов (может быть несколько для печи)
|
for output_item in output_items:
|
||||||
recipes_list = parse_craft_components_and_recipe(
|
# Получаем список рецептов (может быть несколько для печи)
|
||||||
container, output_item.item.name, output_item.amount
|
if(output_item is None):
|
||||||
)
|
logger.error(f'ошибка для: \n{container}\n не удалось получить продукт машинного рецепта')
|
||||||
|
continue
|
||||||
|
|
||||||
for recipe_input in recipes_list: # Обрабатываем каждый рецепт отдельно
|
recipes_list = parse_craft_components_and_recipe(
|
||||||
if not storage.try_add_recipe_signature(
|
container, output_item.item.name, output_item.amount
|
||||||
output_item.item.name,
|
)
|
||||||
recipe_input.components,
|
|
||||||
recipe_input.recipe.craft_type
|
|
||||||
):
|
|
||||||
continue # Дубликат
|
|
||||||
|
|
||||||
storage.add_item(output_item.item)
|
for recipe_input in recipes_list: # Обрабатываем каждый рецепт отдельно
|
||||||
for input_item in recipe_input.items:
|
if not storage.try_add_recipe_signature(
|
||||||
storage.add_item(input_item)
|
output_item.item.name,
|
||||||
|
recipe_input.components,
|
||||||
|
recipe_input.recipe.craft_type
|
||||||
|
):
|
||||||
|
continue # Дубликат
|
||||||
|
|
||||||
recipe_id = storage.add_recipe(recipe_input.recipe)
|
storage.add_item(output_item.item)
|
||||||
for component in recipe_input.components:
|
for input_item in recipe_input.items:
|
||||||
component.recipe_id = recipe_id
|
storage.add_item(input_item)
|
||||||
storage.add_component(component)
|
|
||||||
|
|
||||||
logger.info(f'Добавлен рецепт машинного крафта для {output_item.item.name} '
|
recipe_id = storage.add_recipe(recipe_input.recipe)
|
||||||
f'(ингредиент: {recipe_input.components[0].input_item})')
|
for component in recipe_input.components:
|
||||||
|
component.recipe_id = recipe_id
|
||||||
|
storage.add_component(component)
|
||||||
|
|
||||||
|
logger.info(f'Добавлен рецепт машинного крафта для {output_item.item.name} '
|
||||||
|
f'(ингредиент: {recipe_input.components[0].input_item})')
|
||||||
|
|
||||||
return src_links
|
return src_links
|
||||||
|
|
||||||
@ -55,36 +60,40 @@ def check_is_hidden(container : BeautifulSoup) -> bool:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def parse_craft_item(container) -> ParsedItem|None:
|
def parse_craft_items(container : BeautifulSoup) -> list[ParsedItem]|None:
|
||||||
output_span = container.find('span', class_='gt-output')
|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
output_span : BeautifulSoup = container.find('span', class_='gt-output')
|
||||||
if(output_span is None):
|
if(output_span is None):
|
||||||
logger.error(f'ошибка для \n{container}\n: не найдено ячейки с результатом!')
|
logger.error(f'ошибка для \n{container}\n: не найдено ячейки с результатом!')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
output_span_name_container = output_span.find('span', class_='invslot-item')
|
output_span_name_containers = output_span.find_all('span', class_='invslot-item')
|
||||||
if(output_span_name_container is None):
|
if(output_span_name_containers is None or output_span_name_containers.__len__ == 0):
|
||||||
logger.error(f'ошибка для \n{output_span}\n: не найден текстовый контейнер!')
|
logger.error(f'ошибка для \n{output_span}\n: не найдено ни одного текстового контейнера!')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
for output_span_name_container in output_span_name_containers:
|
||||||
|
data_from_span = extract_data_from_sprite_span(output_span_name_container)
|
||||||
|
if(data_from_span is not None):
|
||||||
|
output_item_title = data_from_span.title
|
||||||
|
output_item_img_shift = data_from_span.shift
|
||||||
|
output_item_img_url = data_from_span.img_url
|
||||||
|
output_amount = data_from_span.amount
|
||||||
|
else:
|
||||||
|
data_from_img = extract_data_from_sprite_img(output_span_name_container)
|
||||||
|
if(data_from_img is None):
|
||||||
|
logger.error(f'ошибка для \n{output_span_name_container}\n: не удалось извлечь картинку и заголовок ни одним из способов')
|
||||||
|
continue
|
||||||
|
output_item_title = data_from_img.title
|
||||||
|
output_item_img_shift = data_from_img.shift
|
||||||
|
output_item_img_url = data_from_img.img_url
|
||||||
|
output_amount = 1
|
||||||
|
|
||||||
data_from_span = extract_data_from_sprite_span(output_span_name_container)
|
item = CraftItem(output_item_title, output_item_img_url, output_item_img_shift)
|
||||||
if(data_from_span is not None):
|
result.append(ParsedItem(item=item, amount=output_amount))
|
||||||
output_item_title = data_from_span.title
|
return result
|
||||||
output_item_img_shift = data_from_span.shift
|
|
||||||
output_item_img_url = data_from_span.img_url
|
|
||||||
output_amount = data_from_span.amount
|
|
||||||
else:
|
|
||||||
data_from_img = extract_data_from_sprite_img(output_span_name_container)
|
|
||||||
if(data_from_img is None):
|
|
||||||
logger.error(f'ошибка для \n{output_span_name_container}\n: не удалось извлечь картинку и заголовок ни одним из способов')
|
|
||||||
return None
|
|
||||||
output_item_title = data_from_img.title
|
|
||||||
output_item_img_shift = data_from_img.shift
|
|
||||||
output_item_img_url = data_from_img.img_url
|
|
||||||
output_amount = 1
|
|
||||||
|
|
||||||
item = CraftItem(output_item_title, output_item_img_url, output_item_img_shift)
|
|
||||||
return ParsedItem(item=item, amount=output_amount)
|
|
||||||
|
|
||||||
def parse_craft_components_and_recipe(container, output_item_name: str, output_item_count: int) -> list[ParsedRecipeInput]:
|
def parse_craft_components_and_recipe(container, output_item_name: str, output_item_count: int) -> list[ParsedRecipeInput]:
|
||||||
input_span = container.find('span', class_='gt-input')
|
input_span = container.find('span', class_='gt-input')
|
||||||
@ -178,6 +187,7 @@ def extract_data_from_sprite_img(input_span_name_container) -> SpriteData|None:
|
|||||||
logger.error(f'ошибка для \n{input_span_name_container}\n: не найден url картинки!')
|
logger.error(f'ошибка для \n{input_span_name_container}\n: не найден url картинки!')
|
||||||
return None
|
return None
|
||||||
return SpriteData(
|
return SpriteData(
|
||||||
|
amount=1,
|
||||||
title=title,
|
title=title,
|
||||||
shift=(0, 0),
|
shift=(0, 0),
|
||||||
img_url=url,
|
img_url=url,
|
||||||
|
|||||||
@ -6,10 +6,10 @@ from craft_storage import CraftStorage
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
url = 'https://ru.minecraft.wiki/w/IndustrialCraft_2/Термальная_центрифуга'
|
url = 'https://ru.minecraft.wiki/w/IndustrialCraft_2/Квантовая_броня'
|
||||||
storage = CraftStorage()
|
storage = CraftStorage()
|
||||||
facade = CraftFacade()
|
facade = CraftFacade()
|
||||||
facade.extract(url, storage, recursive=False)
|
facade.extract(url, storage, recursive=True)
|
||||||
storage.save()
|
storage.save()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,42 +7,45 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"import requests\n",
|
"import pandas as pd"
|
||||||
"from bs4 import BeautifulSoup\n",
|
|
||||||
"from collections import defaultdict, deque\n",
|
|
||||||
"from urllib.parse import urljoin, urlparse\n",
|
|
||||||
"\n",
|
|
||||||
"from craft import CraftComponent, CraftItem, CraftRecipe\n",
|
|
||||||
"from craft_storage import CraftStorage\n",
|
|
||||||
"from collections import Counter\n",
|
|
||||||
"import simple_extractor\n"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 20,
|
||||||
"id": "6189c095",
|
"id": "6189c095",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" name img_url is_base img_shift\n",
|
||||||
|
"0 Квантовый шлем industrialcraft-2-inv... False (-384, -192)\n",
|
||||||
|
"1 Укреплённое стекло industrialcraft-2-inv... False (-192, -128)\n",
|
||||||
|
"2 Нановолоконный шлем industrialcraft-2-inv... False (-64, -192)\n",
|
||||||
|
"3 Иридиевый композит /images/Grid_%D0%98%D... False (0, 0)\n",
|
||||||
|
"4 Лазуротроновый кристалл industrialcraft-2-inv... False (-352, -384)\n",
|
||||||
|
"5 Улучшенная электросхема industrialcraft-2-inv... False (-480, -320)\n",
|
||||||
|
"6 Шлем-акваланг industrialcraft-2-inv... False (-864, -160)\n",
|
||||||
|
"7 Квантовый жилет industrialcraft-2-inv... False (-416, -192)\n",
|
||||||
|
"8 Композит industrialcraft-2-inv... False (-512, -320)\n",
|
||||||
|
"9 Нановолоконный жилет industrialcraft-2-inv... False (-96, -192)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"def get_page_content(url):\n",
|
"df_items = pd.read_csv('../data/items.csv')\n",
|
||||||
" \"\"\"Загружает HTML-контент страницы.\"\"\"\n",
|
"df_recipe_components = pd.read_csv('../data/recipe_components.csv')\n",
|
||||||
" try:\n",
|
"df_recipes = pd.read_csv('../data/recipes.csv')\n",
|
||||||
" response = requests.get(url)\n",
|
"pd.set_option('display.max_colwidth', 25) # строки длиннее 50 символов будут усечены\n",
|
||||||
" response.raise_for_status()\n",
|
"\n",
|
||||||
" return response.text\n",
|
"print(df_items.head(10))"
|
||||||
" except requests.RequestException as e:\n",
|
|
||||||
" print(f\"Ошибка при загрузке страницы: {e}\")\n",
|
|
||||||
" return None\n",
|
|
||||||
" \n",
|
|
||||||
"def get_soup(content):\n",
|
|
||||||
" soup = BeautifulSoup(content, \"html.parser\")\n",
|
|
||||||
" return soup"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 4,
|
"execution_count": null,
|
||||||
"id": "3ea684bc",
|
"id": "3ea684bc",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@ -50,151 +53,413 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Анализирую https://ru.minecraft.wiki/w/IndustrialCraft_2/Квантовая_броня....\n",
|
" name img_url is_base img_shift\n",
|
||||||
"Укреплённое стекло уже есть в датасете, скипаю\n",
|
"44 Композитный слиток industrialcraft-2-inv... False (-608, -256)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"46 Свинцовый слиток industrialcraft-2-inv... False (-704, -256)\n",
|
||||||
"Улучшенная электросхема уже есть в датасете, скипаю\n",
|
"58 Железный слиток https://minecraft.wik... False (0, 0)\n",
|
||||||
"Добавлен рецепт крафта для предмета Квантовый шлем\n",
|
"110 Медный слиток industrialcraft-2-inv... False (-672, -256)\n",
|
||||||
"Композит уже есть в датасете, скипаю\n",
|
"111 Оловянный слиток industrialcraft-2-inv... False (-800, -256)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"112 Бронзовый слиток industrialcraft-2-inv... False (-640, -256)\n",
|
||||||
"Лазуротроновый кристалл уже есть в датасете, скипаю\n",
|
"113 Золотой слиток https://minecraft.wik... False (0, 0)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"125 Слиток очищенного железа /images/Grid_%D0%A1%D... False (0, 0)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"700 Стальной слиток industrialcraft-2-inv... False (-768, -256)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"941 Серебряный слиток /images/Grid_%D0%A1%D... False (0, 0)\n",
|
||||||
"Добавлен рецепт крафта для предмета Квантовый жилет\n",
|
"942 Электрумовый слиток /images/Grid_%D0%AD%D... False (0, 0)\n",
|
||||||
"Лазуротроновый кристалл уже есть в датасете, скипаю\n",
|
" name img_url is_base img_shift\n",
|
||||||
"Основной корпус машины уже есть в датасете, скипаю\n",
|
"44 Композитный слиток industrialcraft-2-inv... True (-608, -256)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"46 Свинцовый слиток industrialcraft-2-inv... True (-704, -256)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"58 Железный слиток https://minecraft.wik... True (0, 0)\n",
|
||||||
"Светопыль уже есть в датасете, скипаю\n",
|
"110 Медный слиток industrialcraft-2-inv... True (-672, -256)\n",
|
||||||
"Добавлен рецепт крафта для предмета Квантовые поножи\n",
|
"111 Оловянный слиток industrialcraft-2-inv... True (-800, -256)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"112 Бронзовый слиток industrialcraft-2-inv... True (-640, -256)\n",
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
"113 Золотой слиток https://minecraft.wik... True (0, 0)\n",
|
||||||
"Лазуротроновый кристалл уже есть в датасете, скипаю\n",
|
"125 Слиток очищенного железа /images/Grid_%D0%A1%D... True (0, 0)\n",
|
||||||
"Резиновые ботинки уже есть в датасете, скипаю\n",
|
"700 Стальной слиток industrialcraft-2-inv... True (-768, -256)\n",
|
||||||
"Добавлен рецепт крафта для предмета Квантовые ботинки\n",
|
"941 Серебряный слиток /images/Grid_%D0%A1%D... True (0, 0)\n",
|
||||||
"Квантовый шлем уже есть в датасете, скипаю\n",
|
"942 Электрумовый слиток /images/Grid_%D0%AD%D... True (0, 0)\n"
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Лазуротроновый кристалл уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Улучшенная электросхема уже есть в датасете, скипаю\n",
|
|
||||||
"Укреплённое стекло уже есть в датасете, скипаю\n",
|
|
||||||
"Улучшенная электросхема уже есть в датасете, скипаю\n",
|
|
||||||
"Добавлен рецепт крафта для предмета Квантовый шлем\n",
|
|
||||||
"Квантовый жилет уже есть в датасете, скипаю\n",
|
|
||||||
"Композит уже есть в датасете, скипаю\n",
|
|
||||||
"Композит уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Лазуротроновый кристалл уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Композит уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Добавлен рецепт крафта для предмета Квантовый жилет\n",
|
|
||||||
"Квантовые поножи уже есть в датасете, скипаю\n",
|
|
||||||
"Основной корпус машины уже есть в датасете, скипаю\n",
|
|
||||||
"Лазуротроновый кристалл уже есть в датасете, скипаю\n",
|
|
||||||
"Основной корпус машины уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Светопыль уже есть в датасете, скипаю\n",
|
|
||||||
"Светопыль уже есть в датасете, скипаю\n",
|
|
||||||
"Добавлен рецепт крафта для предмета Квантовые поножи\n",
|
|
||||||
"Квантовые ботинки уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Иридиевый композит уже есть в датасете, скипаю\n",
|
|
||||||
"Резиновые ботинки уже есть в датасете, скипаю\n",
|
|
||||||
"Лазуротроновый кристалл уже есть в датасете, скипаю\n",
|
|
||||||
"Резиновые ботинки уже есть в датасете, скипаю\n",
|
|
||||||
"Добавлен рецепт крафта для предмета Квантовые ботинки\n",
|
|
||||||
"Закончен поиск по странице https://ru.minecraft.wiki/w/IndustrialCraft_2/Квантовая_броня\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "stderr",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n",
|
|
||||||
"d:\\Development\\Python\\craft_calc\\craft_storage.py:56: FutureWarning: In a future version, object-dtype columns with all-bool values will not be included in reductions with bool_only=True. Explicitly cast to bool dtype instead.\n",
|
|
||||||
" self.items_df = pd.concat(\n"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"url = 'https://ru.minecraft.wiki/w/IndustrialCraft_2/Квантовая_броня'\n",
|
"## слитки\n",
|
||||||
"content = get_page_content(url)\n",
|
"print(df_items[df_items['name'].str.contains('слиток', case=False, na=False)])\n",
|
||||||
"soup = get_soup(content)\n",
|
"df_items.loc[df_items['name'].str.contains('слиток', case=False, na=False), 'is_base'] = True\n",
|
||||||
"storage = CraftStorage()\n",
|
"print(df_items[df_items['name'].str.contains('слиток', case=False, na=False)])\n"
|
||||||
"simple_extractor.extract_crafts(soup,url,storage)"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": null,
|
||||||
"id": "df4b0ee0",
|
"id": "76f8d069",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
" recipe_id input_item count\n",
|
" name img_url is_base img_shift\n",
|
||||||
"0 1 Укреплённое стекло 2\n",
|
"132 Дубовые доски inv-sprite False (-192, -896)\n",
|
||||||
"1 1 Иридиевый композит 2\n",
|
"133 Еловые доски inv-sprite False (0, -928)\n",
|
||||||
"2 1 Улучшенная электросхема 2\n",
|
"134 Берёзовые доски inv-sprite False (-832, -832)\n",
|
||||||
"3 1 Нановолоконный шлем 1\n",
|
"135 Джунглевые доски inv-sprite False (-992, -864)\n",
|
||||||
"4 1 Лазуротроновый кристалл 1\n",
|
"136 Акациевые доски inv-sprite False (-672, -832)\n",
|
||||||
"5 1 Шлем-акваланг 1\n",
|
"137 Доски из тёмного дуба inv-sprite False (-512, -864)\n",
|
||||||
"6 2 Иридиевый композит 4\n",
|
"138 Мангровые доски inv-sprite False (-320, -576)\n",
|
||||||
"7 2 Композит 2\n",
|
"139 Вишнёвые доски inv-sprite False (-928, -1152)\n",
|
||||||
"8 2 Нановолоконный жилет 1\n",
|
"140 Доски из бледного дуба https://minecraft.wik... False (0, 0)\n",
|
||||||
"9 2 Лазуротроновый кристалл 1\n",
|
"141 Бамбуковые доски inv-sprite False (-832, -640)\n",
|
||||||
"10 2 Электрический реактивный ранец 1\n",
|
"142 Багровые доски inv-sprite False (-544, -128)\n",
|
||||||
"11 3 Основной корпус машины 2\n",
|
"143 Искажённые доски inv-sprite False (-576, -128)\n",
|
||||||
"12 3 Иридиевый композит 2\n",
|
"951 Доски inv-sprite False (-192, -896)\n",
|
||||||
"13 3 Светопыль 2\n",
|
" name img_url is_base img_shift\n",
|
||||||
"14 3 Лазуротроновый кристалл 1\n",
|
"132 Дубовые доски inv-sprite True (-192, -896)\n",
|
||||||
"15 3 Нановолоконные поножи 1\n",
|
"133 Еловые доски inv-sprite True (0, -928)\n",
|
||||||
"16 4 Иридиевый композит 2\n",
|
"134 Берёзовые доски inv-sprite True (-832, -832)\n",
|
||||||
"17 4 Резиновые ботинки 2\n",
|
"135 Джунглевые доски inv-sprite True (-992, -864)\n",
|
||||||
"18 4 Нановолоконные ботинки 1\n",
|
"136 Акациевые доски inv-sprite True (-672, -832)\n",
|
||||||
"19 4 Лазуротроновый кристалл 1\n"
|
"137 Доски из тёмного дуба inv-sprite True (-512, -864)\n",
|
||||||
|
"138 Мангровые доски inv-sprite True (-320, -576)\n",
|
||||||
|
"139 Вишнёвые доски inv-sprite True (-928, -1152)\n",
|
||||||
|
"140 Доски из бледного дуба https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"141 Бамбуковые доски inv-sprite True (-832, -640)\n",
|
||||||
|
"142 Багровые доски inv-sprite True (-544, -128)\n",
|
||||||
|
"143 Искажённые доски inv-sprite True (-576, -128)\n",
|
||||||
|
"951 Доски inv-sprite True (-192, -896)\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"print(storage.components_df.head(20))"
|
"## доски\n",
|
||||||
|
"print(df_items[df_items['name'].str.contains('доски', case=False, na=False)])\n",
|
||||||
|
"df_items.loc[df_items['name'].str.contains('доски', case=False, na=False), 'is_base'] = True\n",
|
||||||
|
"print(df_items[df_items['name'].str.contains('доски', case=False, na=False)])\n",
|
||||||
|
"\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 46,
|
||||||
|
"id": "66da5670",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" name img_url is_base img_shift\n",
|
||||||
|
"239 Белая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"240 Оранжевая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"241 Сиреневая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"242 Голубая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"243 Жёлтая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"244 Лаймовая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"245 Розовая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"246 Серая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"247 Светло-серая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"248 Бирюзовая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"249 Фиолетовая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"250 Синяя шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"251 Коричневая шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"252 Зелёная шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"253 Красная шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
"254 Чёрная шерсть https://minecraft.wik... False (0, 0)\n",
|
||||||
|
" name img_url is_base img_shift\n",
|
||||||
|
"239 Белая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"240 Оранжевая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"241 Сиреневая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"242 Голубая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"243 Жёлтая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"244 Лаймовая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"245 Розовая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"246 Серая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"247 Светло-серая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"248 Бирюзовая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"249 Фиолетовая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"250 Синяя шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"251 Коричневая шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"252 Зелёная шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"253 Красная шерсть https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"254 Чёрная шерсть https://minecraft.wik... True (0, 0)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"## шерсть\n",
|
||||||
|
"print(df_items[df_items['name'].str.contains('шерсть', case=False, na=False)])\n",
|
||||||
|
"df_items.loc[df_items['name'].str.contains('шерсть', case=False, na=False), 'is_base'] = True\n",
|
||||||
|
"print(df_items[df_items['name'].str.contains('шерсть', case=False, na=False)])\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "df4b0ee0",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"#Базовые айтемы, не включенные в список выше\n",
|
||||||
|
"BASE_ITEMS = [\n",
|
||||||
|
" ##блоки\n",
|
||||||
|
" \"земля\", \"мицелий\", \"камень\", \"булыжник\", \"гранит\", \"диорит\", \"андезит\", \"туф\",\"песок\",\n",
|
||||||
|
" ##Почти вся еда\n",
|
||||||
|
" \"тыква\", \"арбуз\", \"пшеница\", \"сырая свинина\", \"яблоко\", \"гнилая плоть\", \n",
|
||||||
|
" #\"сырой лосось\", \"сырая треска\", \"сырая рыба\", \"сырая курица\",\n",
|
||||||
|
" \"сырой картофель\",\n",
|
||||||
|
" \"яйцо\",\n",
|
||||||
|
"\n",
|
||||||
|
" ##драг. камни и пыль\n",
|
||||||
|
" \"изумруд\", \"красная пыль\", \"алмаз\", \"лазурит\", \"уголь\", \"древесный уголь\", \"кварц\",\n",
|
||||||
|
"\n",
|
||||||
|
" ##прочее\n",
|
||||||
|
" \"снежок\", \"ведро воды\", \"ведро лавы\", \"слизь\",\n",
|
||||||
|
" ]"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 36,
|
||||||
|
"id": "1e0e8c1b",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def search_item_in_df(item, df, column_name):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Ищет `item` в столбце `column_name` датасета `df`.\n",
|
||||||
|
" Проверяет:\n",
|
||||||
|
" 1. Точное совпадение (регистронезависимо).\n",
|
||||||
|
" 2. Подстроку (регистронезависимо).\n",
|
||||||
|
" 3. Укорачивание `item` до 3+ символов и поиск подстроки.\n",
|
||||||
|
" Возвращает:\n",
|
||||||
|
" - строку из датасета, если найдено;\n",
|
||||||
|
" - None, если не найдено.\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" item_lower = item.lower().strip()\n",
|
||||||
|
" if not item_lower:\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" # Получаем все значения столбца как строки, очищенные и в нижнем регистре\n",
|
||||||
|
" values = df[column_name].dropna().astype(str).str.strip().str.lower()\n",
|
||||||
|
"\n",
|
||||||
|
" # 1. Точное совпадение\n",
|
||||||
|
" if item_lower in values.values:\n",
|
||||||
|
" original = df.loc[values == item_lower, column_name].iloc[0]\n",
|
||||||
|
" return str(original)\n",
|
||||||
|
"\n",
|
||||||
|
" # 2. Поиск как подстроки в любом значении столбца\n",
|
||||||
|
" for val in values:\n",
|
||||||
|
" if item_lower in val:\n",
|
||||||
|
" original = df.loc[df[column_name].astype(str).str.strip().str.lower() == val, column_name].iloc[0]\n",
|
||||||
|
" return str(original)\n",
|
||||||
|
"\n",
|
||||||
|
" # 3. Укорачиваем item до 3+ символов и ищем подстроку\n",
|
||||||
|
" for length in range(len(item_lower), 2, -1):\n",
|
||||||
|
" if length < 3:\n",
|
||||||
|
" break\n",
|
||||||
|
" prefix = item_lower[:length]\n",
|
||||||
|
" for val in values:\n",
|
||||||
|
" if prefix in val:\n",
|
||||||
|
" original = df.loc[df[column_name].astype(str).str.strip().str.lower() == val, column_name].iloc[0]\n",
|
||||||
|
" return str(original)\n",
|
||||||
|
"\n",
|
||||||
|
" return None # ничего не найдено\n",
|
||||||
|
"\n",
|
||||||
|
"def process_base_items(df, column_name, base_items):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Для каждого элемента из `base_items` ищет соответствие в столбце `column_name` датасета `df`.\n",
|
||||||
|
" Выводит результат.\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" print(\"Начало поиска элементов из BASE_ITEMS в датасете...\\n\")\n",
|
||||||
|
"\n",
|
||||||
|
" for item in base_items:\n",
|
||||||
|
" match = search_item_in_df(item, df, column_name)\n",
|
||||||
|
"\n",
|
||||||
|
" if match:\n",
|
||||||
|
" if item.lower() == match.lower():\n",
|
||||||
|
" print(f\"'{item}' → найдено точное совпадение: '{match}'\")\n",
|
||||||
|
" else:\n",
|
||||||
|
" print(f\"'{item}' не найден точно, но найдено как подстрока/укороченное: '{match}'\")\n",
|
||||||
|
" else:\n",
|
||||||
|
" print(f\"'{item}' не найден даже после укорочения до 3 символов\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 41,
|
||||||
|
"id": "b4c186ba",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Начало поиска элементов из BASE_ITEMS в датасете...\n",
|
||||||
|
"\n",
|
||||||
|
"'земля' → найдено точное совпадение: 'Земля'\n",
|
||||||
|
"'трава' не найден точно, но найдено как подстрока/укороченное: 'Оседающее зелье отравления'\n",
|
||||||
|
"'подзол' не найден точно, но найдено как подстрока/укороченное: 'Накладная пластина под реактивный ранец'\n",
|
||||||
|
"'мицелий' → найдено точное совпадение: 'Мицелий'\n",
|
||||||
|
"'камень' → найдено точное совпадение: 'Камень'\n",
|
||||||
|
"'булыжник' → найдено точное совпадение: 'Булыжник'\n",
|
||||||
|
"'гранит' → найдено точное совпадение: 'Гранит'\n",
|
||||||
|
"'диорит' → найдено точное совпадение: 'Диорит'\n",
|
||||||
|
"'андезит' → найдено точное совпадение: 'Андезит'\n",
|
||||||
|
"'туф' → найдено точное совпадение: 'Туф'\n",
|
||||||
|
"'натёчный камень' не найден точно, но найдено как подстрока/укороченное: 'Натяжной датчик'\n",
|
||||||
|
"'губка' не найден даже после укорочения до 3 символов\n",
|
||||||
|
"'песок' → найдено точное совпадение: 'Песок'\n",
|
||||||
|
"'тыква' → найдено точное совпадение: 'Тыква'\n",
|
||||||
|
"'арбуз' не найден даже после укорочения до 3 символов\n",
|
||||||
|
"'пшеница' → найдено точное совпадение: 'Пшеница'\n",
|
||||||
|
"'сырая свинина' не найден даже после укорочения до 3 символов\n",
|
||||||
|
"'яблоко' → найдено точное совпадение: 'Яблоко'\n",
|
||||||
|
"'гнилая плоть' не найден точно, но найдено как подстрока/укороченное: 'Магний'\n",
|
||||||
|
"'сырой картофель' не найден даже после укорочения до 3 символов\n",
|
||||||
|
"'яйцо' → найдено точное совпадение: 'Яйцо'\n",
|
||||||
|
"'изумруд' не найден даже после укорочения до 3 символов\n",
|
||||||
|
"'красная пыль' → найдено точное совпадение: 'Красная пыль'\n",
|
||||||
|
"'алмаз' → найдено точное совпадение: 'Алмаз'\n",
|
||||||
|
"'лазурит' → найдено точное совпадение: 'Лазурит'\n",
|
||||||
|
"'уголь' → найдено точное совпадение: 'Уголь'\n",
|
||||||
|
"'древесный уголь' → найдено точное совпадение: 'Древесный уголь'\n",
|
||||||
|
"'кварц' не найден точно, но найдено как подстрока/укороченное: 'Кварцевая плита'\n",
|
||||||
|
"'снежок' → найдено точное совпадение: 'Снежок'\n",
|
||||||
|
"'ведро воды' → найдено точное совпадение: 'Ведро воды'\n",
|
||||||
|
"'ведро лавы' → найдено точное совпадение: 'Ведро лавы'\n",
|
||||||
|
"'слизь' → найдено точное совпадение: 'Слизь'\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"# Запускаем обработку\n",
|
||||||
|
"process_base_items(df_items, \"name\", BASE_ITEMS)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 53,
|
||||||
|
"id": "513d74a7",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" name img_url is_base \\\n",
|
||||||
|
"44 Композитный слиток industrialcraft-2-inv... True \n",
|
||||||
|
"46 Свинцовый слиток industrialcraft-2-inv... True \n",
|
||||||
|
"58 Железный слиток https://minecraft.wik... True \n",
|
||||||
|
"110 Медный слиток industrialcraft-2-inv... True \n",
|
||||||
|
"111 Оловянный слиток industrialcraft-2-inv... True \n",
|
||||||
|
"112 Бронзовый слиток industrialcraft-2-inv... True \n",
|
||||||
|
"113 Золотой слиток https://minecraft.wik... True \n",
|
||||||
|
"125 Слиток очищенного железа /images/Grid_%D0%A1%D... True \n",
|
||||||
|
"132 Дубовые доски inv-sprite True \n",
|
||||||
|
"133 Еловые доски inv-sprite True \n",
|
||||||
|
"134 Берёзовые доски inv-sprite True \n",
|
||||||
|
"135 Джунглевые доски inv-sprite True \n",
|
||||||
|
"136 Акациевые доски inv-sprite True \n",
|
||||||
|
"137 Доски из тёмного дуба inv-sprite True \n",
|
||||||
|
"138 Мангровые доски inv-sprite True \n",
|
||||||
|
"139 Вишнёвые доски inv-sprite True \n",
|
||||||
|
"140 Доски из бледного дуба https://minecraft.wik... True \n",
|
||||||
|
"141 Бамбуковые доски inv-sprite True \n",
|
||||||
|
"142 Багровые доски inv-sprite True \n",
|
||||||
|
"143 Искажённые доски inv-sprite True \n",
|
||||||
|
"239 Белая шерсть https://minecraft.wik... True \n",
|
||||||
|
"240 Оранжевая шерсть https://minecraft.wik... True \n",
|
||||||
|
"241 Сиреневая шерсть https://minecraft.wik... True \n",
|
||||||
|
"242 Голубая шерсть https://minecraft.wik... True \n",
|
||||||
|
"243 Жёлтая шерсть https://minecraft.wik... True \n",
|
||||||
|
"244 Лаймовая шерсть https://minecraft.wik... True \n",
|
||||||
|
"245 Розовая шерсть https://minecraft.wik... True \n",
|
||||||
|
"246 Серая шерсть https://minecraft.wik... True \n",
|
||||||
|
"247 Светло-серая шерсть https://minecraft.wik... True \n",
|
||||||
|
"248 Бирюзовая шерсть https://minecraft.wik... True \n",
|
||||||
|
"249 Фиолетовая шерсть https://minecraft.wik... True \n",
|
||||||
|
"250 Синяя шерсть https://minecraft.wik... True \n",
|
||||||
|
"251 Коричневая шерсть https://minecraft.wik... True \n",
|
||||||
|
"252 Зелёная шерсть https://minecraft.wik... True \n",
|
||||||
|
"253 Красная шерсть https://minecraft.wik... True \n",
|
||||||
|
"254 Чёрная шерсть https://minecraft.wik... True \n",
|
||||||
|
"700 Стальной слиток industrialcraft-2-inv... True \n",
|
||||||
|
"941 Серебряный слиток /images/Grid_%D0%A1%D... True \n",
|
||||||
|
"942 Электрумовый слиток /images/Grid_%D0%AD%D... True \n",
|
||||||
|
"951 Доски inv-sprite True \n",
|
||||||
|
"\n",
|
||||||
|
" img_shift \n",
|
||||||
|
"44 (-608, -256) \n",
|
||||||
|
"46 (-704, -256) \n",
|
||||||
|
"58 (0, 0) \n",
|
||||||
|
"110 (-672, -256) \n",
|
||||||
|
"111 (-800, -256) \n",
|
||||||
|
"112 (-640, -256) \n",
|
||||||
|
"113 (0, 0) \n",
|
||||||
|
"125 (0, 0) \n",
|
||||||
|
"132 (-192, -896) \n",
|
||||||
|
"133 (0, -928) \n",
|
||||||
|
"134 (-832, -832) \n",
|
||||||
|
"135 (-992, -864) \n",
|
||||||
|
"136 (-672, -832) \n",
|
||||||
|
"137 (-512, -864) \n",
|
||||||
|
"138 (-320, -576) \n",
|
||||||
|
"139 (-928, -1152) \n",
|
||||||
|
"140 (0, 0) \n",
|
||||||
|
"141 (-832, -640) \n",
|
||||||
|
"142 (-544, -128) \n",
|
||||||
|
"143 (-576, -128) \n",
|
||||||
|
"239 (0, 0) \n",
|
||||||
|
"240 (0, 0) \n",
|
||||||
|
"241 (0, 0) \n",
|
||||||
|
"242 (0, 0) \n",
|
||||||
|
"243 (0, 0) \n",
|
||||||
|
"244 (0, 0) \n",
|
||||||
|
"245 (0, 0) \n",
|
||||||
|
"246 (0, 0) \n",
|
||||||
|
"247 (0, 0) \n",
|
||||||
|
"248 (0, 0) \n",
|
||||||
|
"249 (0, 0) \n",
|
||||||
|
"250 (0, 0) \n",
|
||||||
|
"251 (0, 0) \n",
|
||||||
|
"252 (0, 0) \n",
|
||||||
|
"253 (0, 0) \n",
|
||||||
|
"254 (0, 0) \n",
|
||||||
|
"700 (-768, -256) \n",
|
||||||
|
"941 (0, 0) \n",
|
||||||
|
"942 (0, 0) \n",
|
||||||
|
"951 (-192, -896) \n",
|
||||||
|
" name img_url is_base img_shift\n",
|
||||||
|
"29 Алмаз https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"34 Красная пыль inv-sprite True (-224, -3520)\n",
|
||||||
|
"42 Камень https://minecraft.wik... True (0, 0)\n",
|
||||||
|
"44 Композитный слиток industrialcraft-2-inv... True (-608, -256)\n",
|
||||||
|
"46 Свинцовый слиток industrialcraft-2-inv... True (-704, -256)\n",
|
||||||
|
".. ... ... ... ...\n",
|
||||||
|
"813 Ведро лавы inv-sprite True (-320, -3136)\n",
|
||||||
|
"941 Серебряный слиток /images/Grid_%D0%A1%D... True (0, 0)\n",
|
||||||
|
"942 Электрумовый слиток /images/Grid_%D0%AD%D... True (0, 0)\n",
|
||||||
|
"951 Доски inv-sprite True (-192, -896)\n",
|
||||||
|
"967 Мицелий inv-sprite True (-256, -3360)\n",
|
||||||
|
"\n",
|
||||||
|
"[62 rows x 4 columns]\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"print(df_items[df_items['is_base']==True])\n",
|
||||||
|
"\n",
|
||||||
|
"mask = df_items['name'].str.fullmatch('|'.join(BASE_ITEMS), case=False, na=False)\n",
|
||||||
|
"df_items.loc[mask, 'is_base'] = True\n",
|
||||||
|
"print(df_items[df_items['is_base']==True])"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "778bb886",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"df_items.to_csv('items_processed.csv')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -80,7 +80,7 @@ def parse_craft_item(container) -> ParsedItem|None:
|
|||||||
item = CraftItem(output_item_title, output_item_img_url, output_item_img_shift)
|
item = CraftItem(output_item_title, output_item_img_url, output_item_img_shift)
|
||||||
return ParsedItem(item=item, amount=output_amount)
|
return ParsedItem(item=item, amount=output_amount)
|
||||||
|
|
||||||
def parse_craft_components_and_recipe(container, output_item_name: str, output_count = 1) -> ParsedRecipeInput|None:
|
def parse_craft_components_and_recipe(container : BeautifulSoup, output_item_name: str, output_count = 1) -> ParsedRecipeInput|None:
|
||||||
input_span = container.find('span', class_='mcui-input')
|
input_span = container.find('span', class_='mcui-input')
|
||||||
if(input_span is None):
|
if(input_span is None):
|
||||||
logger.error(f'ошибка для \n{container}\n: не найдено рецепта крафта')
|
logger.error(f'ошибка для \n{container}\n: не найдено рецепта крафта')
|
||||||
@ -98,6 +98,9 @@ def parse_craft_components_and_recipe(container, output_item_name: str, output_c
|
|||||||
#existing_items = set()
|
#existing_items = set()
|
||||||
|
|
||||||
for input_span_name_container in input_span_name_containers:
|
for input_span_name_container in input_span_name_containers:
|
||||||
|
if(input_span_name_container.contents is None or input_span_name_container.contents.__len__() == 0):
|
||||||
|
logger.warning('Пустая ячейка, скипаю')
|
||||||
|
continue
|
||||||
|
|
||||||
if(input_span_name_container is None):
|
if(input_span_name_container is None):
|
||||||
logger.error('ошибка для набора контейнеров: не найден текстовый контейнер!')
|
logger.error('ошибка для набора контейнеров: не найден текстовый контейнер!')
|
||||||
|
|||||||
Reference in New Issue
Block a user