[crawler]

This commit is contained in:
LASTA_DEV01\lasta
2026-05-08 17:41:15 +09:00
commit 4158789869
54 changed files with 4355 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
"""Ontology definitions and mapping helpers."""

View File

@@ -0,0 +1,130 @@
from __future__ import annotations
from dataclasses import dataclass, field
@dataclass(slots=True)
class Ontology:
domain: str
entity_types: list[str]
predicates: list[str]
attributes: list[str]
aliases: dict[str, str] = field(default_factory=dict)
COMMON_ONTOLOGY = Ontology(
domain="common",
entity_types=[
"Source",
"Page",
"Entity",
"Attribute",
"Relation",
"Claim",
"Evidence",
"Extraction",
"Confidence",
"UpdatePolicy",
],
predicates=[
"mentions",
"hasAttribute",
"relatedTo",
"sameAs",
"soldBy",
"hasPrice",
],
attributes=["name", "source_url", "updated_at", "confidence"],
)
DOMAIN_ONTOLOGIES: dict[str, Ontology] = {
"perfume": Ontology(
domain="perfume",
entity_types=[
"Perfume",
"Brand",
"Note",
"Accord",
"Mood",
"Season",
"Occasion",
"Review",
"Price",
"ProductPage",
],
predicates=[
"hasBrand",
"hasTopNote",
"hasMiddleNote",
"hasBaseNote",
"hasAccord",
"evokesMood",
"suitableForSeason",
"suitableForOccasion",
"similarTo",
"soldBy",
"hasPrice",
"hasReviewKeyword",
],
attributes=[
"name",
"brand",
"gender_bias",
"longevity",
"sillage",
"price_range",
"popularity_score",
"review_count",
"source_url",
"updated_at",
],
aliases={
"top_notes": "hasTopNote",
"middle_notes": "hasMiddleNote",
"heart_notes": "hasMiddleNote",
"base_notes": "hasBaseNote",
"accords": "hasAccord",
"mood_tags": "evokesMood",
"season_tags": "suitableForSeason",
"occasion_tags": "suitableForOccasion",
"review_keywords": "hasReviewKeyword",
"price": "hasPrice",
},
),
"tea": Ontology(
domain="tea",
entity_types=["Tea", "Ingredient", "Flavor", "Effect", "CaffeineLevel", "MoodState"],
predicates=["hasIngredient", "hasFlavor", "hasEffect", "suitableForCondition"],
attributes=["name", "origin", "caffeine_level", "price_range"],
),
"coffee": Ontology(
domain="coffee",
entity_types=["CoffeeBean", "Origin", "RoastLevel", "FlavorNote", "BrewMethod"],
predicates=["hasOrigin", "hasRoastLevel", "hasFlavorNote", "recommendedForBrewMethod"],
attributes=["name", "origin", "roast_level", "process", "price_range"],
),
"candle": Ontology(
domain="candle",
entity_types=["ScentProduct", "ScentNote", "SpaceType", "Mood", "Season"],
predicates=["suitableForSpace", "evokesMood", "hasScentNote"],
attributes=["name", "burn_time", "volume", "price_range"],
),
"supplement": Ontology(
domain="supplement",
entity_types=["Supplement", "Ingredient", "HealthGoal", "Symptom", "Dosage"],
predicates=["hasIngredient", "supportsGoal", "recommendedForCondition"],
attributes=["name", "dosage", "warnings", "price_range"],
),
"gift": Ontology(
domain="gift",
entity_types=["GiftProduct", "RecipientType", "Relationship", "Occasion", "PersonalityTag"],
predicates=["suitableForRecipient", "suitableForOccasion", "matchesPersonality"],
attributes=["name", "price_range", "availability", "gift_wrap_available"],
),
}
def ontology_for_domain(domain: str) -> Ontology:
return DOMAIN_ONTOLOGIES.get(domain, COMMON_ONTOLOGY)

View File

@@ -0,0 +1,27 @@
from __future__ import annotations
from typing import Any
def normalize_predicate(predicate: str, ontology: dict[str, Any] | None) -> str:
if not ontology:
return predicate
aliases = ontology.get("aliases", {})
return aliases.get(predicate, predicate)
def is_allowed_predicate(predicate: str, ontology: dict[str, Any] | None) -> bool:
if not ontology or not ontology.get("predicates"):
return True
return predicate in ontology["predicates"]
def ontology_to_dict(domain_ontology) -> dict[str, Any]:
return {
"domain": domain_ontology.domain,
"entity_types": domain_ontology.entity_types,
"predicates": domain_ontology.predicates,
"attributes": domain_ontology.attributes,
"aliases": domain_ontology.aliases,
}