Facility: 041635
Valley Storage WY
- Facility ID
- 041635
- Name
- Valley Storage WY
- URL
- https://www.valleystoragewy.net/781-us-highway-14-ranchester-wy-82839
- Address
- N/A
- Platform
- custom_facility_041635
- Parser File
- src/parsers/custom/facility_041635_parser.py
- Last Scraped
- 2026-03-23 03:19:06.172635
- Created
- 2026-03-06 23:45:35.865957
- Updated
- 2026-03-23 03:19:06.178321
- Parser Status
- ✓ Working
- Status Reason
- N/A
- Last Healing Attempt
- Not attempted
Parser Source (src/parsers/custom/facility_041635_parser.py)
"""Parser for Valley Storage (Ranchester, WY) — facility 041635.
This site is built on StorEdge/StorageUnitSoftware. Unit data is embedded
in a JSON-LD <script type="application/ld+json"> block as a @graph of
Product entries. The description field encodes dimensions and price in
the format:
"10x20x8 - $95.00 - 392649 - 1"
{width}x{depth}x{height} - ${price} - {internal_id} - {count}
The offers.category field contains the unit type (e.g. "self storage",
"parking").
"""
from __future__ import annotations
import json
import re
from bs4 import BeautifulSoup
from src.parsers.base import BaseParser, ParseResult, UnitResult
# Matches "10x20x8 - $95.00 - ..." at the start of the description
_DESC_RE = re.compile(
r"^(\d+)x(\d+)x(\d+)\s*-\s*\$([\d,]+(?:\.\d+)?)",
re.IGNORECASE,
)
class Facility041635Parser(BaseParser):
"""Extract storage units from Valley Storage (Ranchester, WY).
Unit data is found in an application/ld+json block structured as a
schema.org @graph of Product nodes. Each Product's description
encodes dimensions and price; its offers.category encodes unit type.
"""
platform = "custom_facility_041635"
def parse(self, html: str, url: str = "") -> ParseResult:
soup = BeautifulSoup(html, "lxml")
result = ParseResult(platform=self.platform, parser_name=self.__class__.__name__)
# Locate the JSON-LD block that contains a @graph list of Products
graph_data: list[dict] = []
for script in soup.find_all("script", type="application/ld+json"):
try:
data = json.loads(script.string or "")
except (json.JSONDecodeError, TypeError):
continue
if isinstance(data, dict) and "@graph" in data:
graph_data = data["@graph"]
break
if not graph_data:
result.warnings.append("No JSON-LD @graph block found on page")
return result
for item in graph_data:
if not isinstance(item, dict):
continue
if item.get("@type") != "Product":
continue
description = item.get("description", "")
offers = item.get("offers", {})
category = offers.get("category", "")
match = _DESC_RE.match(description)
if not match:
continue
width = float(match.group(1))
depth = float(match.group(2))
height = float(match.group(3))
price_raw = match.group(4).replace(",", "")
price = float(price_raw)
# Format size as "10' x 20'"
size_str = f"{int(width)}' x {int(depth)}'"
unit = UnitResult(
size=size_str,
price=price,
description=description,
metadata={
"width": width,
"length": depth,
"height": height,
"sqft": width * depth,
"category": category,
},
)
result.units.append(unit)
if not result.units:
result.warnings.append("JSON-LD @graph found but no Product entries matched")
return result
Scrape Runs (5)
-
exported Run #14772026-03-23 03:19:01.863717 | 5 units | Facility041635Parser | View Data →
-
exported Run #9842026-03-21 19:11:57.334745 | 5 units | Facility041635Parser | View Data →
-
exported Run #5372026-03-14 16:54:25.410307 | 5 units | Facility041635Parser | View Data →
-
exported Run #1392026-03-14 01:06:11.148663 | 5 units | Facility041635Parser | View Data →
-
exported Run #622026-03-13 21:40:40.672023 | 5 units | Facility041635Parser | View Data →
Run #62 Details
- Status
- exported
- Parser Used
- Facility041635Parser
- Platform Detected
- storageunitsoftware
- Units Found
- 5
- Stage Reached
- exported
- Timestamp
- 2026-03-13 21:40:40.672023
Timing
| Stage | Duration |
|---|---|
| Fetch | 6301ms |
| Detect | 34ms |
| Parse | 16ms |
| Export | 18ms |
Snapshot: 041635_20260313T214046Z.html · Show Snapshot · Open in New Tab
Parsed Units (5)
10' x 20'
$95.00/mo
5' x 10'
$50.00/mo
10' x 10'
$65.00/mo
10' x 12'
$75.00/mo
10' x 11'
$45.00/mo