Facility: 001590

Dash Storage

Stale Data Warning: This facility has not been successfully scraped in 26 days (threshold: 3 days). Data may be outdated.
Facility Information active
Facility ID
001590
Name
Dash Storage
URL
https://www.dashstorage.com/storage/
Address
1035 W Coulter Ave, Powell, WY 82435, USA, Powell, Wyoming 82435
Platform
custom_facility_001590
Parser File
src/parsers/custom/facility_001590_parser.py
Last Scraped
2026-03-27 13:48:16.178551
Created
2026-03-14 16:21:53.706708
Updated
2026-03-27 13:48:16.206871
Parser & Healing Diagnosis working
Parser Status
✓ Working
Status Reason
N/A
Last Healing Attempt
Not attempted
Parser Source (src/parsers/custom/facility_001590_parser.py)
"""Parser for Dash Storage (dashstorage.com/storage/)."""

from __future__ import annotations

import re

from bs4 import BeautifulSoup

from src.parsers.base import BaseParser, ParseResult, UnitResult


class Facility001590Parser(BaseParser):
    """Extract storage units from Dash Storage.

    The site lists unit sizes (e.g. 5'x10', 10'x20') in <h2> tags within
    .fl-rich-text divs under a "Styles Available" section. Each size is
    paired with a description of what fits. No prices are published.
    """

    platform = "custom_facility_001590"

    # Matches sizes like 5'x10', 10'x20', 12'x40', 14'x40'
    _SIZE_RE = re.compile(
        r"(\d+)\s*['\u2032]?\s*[xX\u00d7]\s*(\d+)\s*['\u2032]?"
    )

    def parse(self, html: str, url: str = "") -> ParseResult:
        soup = BeautifulSoup(html, "lxml")
        result = ParseResult(platform=self.platform, parser_name=self.__class__.__name__)

        for tag in soup.find_all(["script", "style"]):
            tag.decompose()

        seen: set[str] = set()

        # Unit sizes appear in <h2> tags within .fl-rich-text divs inside
        # nested column groups under the "Styles Available" heading.
        for h2 in soup.find_all("h2"):
            text = h2.get_text(strip=True)
            m = self._SIZE_RE.search(text)
            if not m:
                continue

            width = int(m.group(1))
            length = int(m.group(2))

            # Skip implausible sizes (e.g. image dimensions)
            if width < 3 or length < 3:
                continue

            size_str = f"{width}'x{length}'"
            if size_str in seen:
                continue
            seen.add(size_str)

            # Look for description in the sibling column
            description = ""
            col_group = h2.find_parent(class_="fl-col-group-nested")
            if col_group:
                desc_div = col_group.find("p")
                if desc_div:
                    description = desc_div.get_text(separator=" ", strip=True)

            unit = UnitResult()
            unit.size = size_str
            w, ln, sq = self.normalize_size(size_str)
            if w is not None:
                unit.metadata = {"width": w, "length": ln, "sqft": sq}
            unit.price = None
            unit.description = description[:200] if description else size_str
            result.units.append(unit)

        if not result.units:
            result.warnings.append("No units found on page")
        else:
            result.warnings.append("No pricing published on this site")

        return result

Scrape Runs (5)

Run #185 Details

Status
exported
Parser Used
Facility001590Parser
Platform Detected
table_layout
Units Found
14
Stage Reached
exported
Timestamp
2026-03-14 16:23:24.412614
Timing
Stage Duration
Fetch2910ms
Detect25ms
Parse14ms
Export17ms

Snapshot: 001590_20260314T162327Z.html · Show Snapshot · Open in New Tab

Parsed Units (14)

5'x10'

No price

10'x10'

No price

10'x15'

No price

10'x20'

No price

10'x25'

No price

10'x30'

No price

10'x35'

No price

12'x10'

No price

12'x15'

No price

12'x20'

No price

12'x25'

No price

12'x30'

No price

12'x40'

No price

14'x40'

No price

← Back to dashboard