Facility: 017878
ABC Storage LLC MT
- Facility ID
- 017878
- Name
- ABC Storage LLC MT
- URL
- https://www.abcstoragellcmt.com/available-units
- Address
- N/A
- Platform
- custom_facility_017878
- Parser File
- src/parsers/custom/facility_017878_parser.py
- Last Scraped
- 2026-03-23 03:21:36.959191
- Created
- 2026-03-06 23:45:35.865957
- Updated
- 2026-03-23 03:21:36.959191
- Parser Status
- ⚠ Needs Fix
- Status Reason
- Parser returned 0 units
- Last Healing Attempt
- Not attempted
Parser Source (src/parsers/custom/facility_017878_parser.py)
"""Parser for ABC Storage LLC (Ballantine, MT) — Squarespace site.
Unit data is embedded as h3 headings inside Squarespace HTML content blocks
with the format: "<WxL> Storage Unit (<sqft> sq. ft.) - $<price> / mo"
"""
from __future__ import annotations
import re
from bs4 import BeautifulSoup
from src.parsers.base import BaseParser, ParseResult, UnitResult
class Facility017878Parser(BaseParser):
"""Extract storage units from ABC Storage LLC Squarespace site.
Unit headings follow the pattern:
7x12 Storage Unit (84 sq. ft.) - $43 / mo
"""
platform = "custom_facility_017878"
# Matches: "7x12 Storage Unit (84 sq. ft.) - $43 / mo"
# Groups: (width, length, sqft, price)
_UNIT_RE = re.compile(
r"(\d+(?:\.\d+)?)\s*[xX\u00d7]\s*(\d+(?:\.\d+)?)" # WxL dimensions
r".*?" # "Storage Unit"
r"\((\d+(?:\.\d+)?)\s*sq\.?\s*ft\.?\)" # (sqft sq. ft.)
r".*?\$" # " - $"
r"([\d,]+(?:\.\d+)?)" # price digits
r"\s*/\s*mo", # " / mo"
re.IGNORECASE | re.DOTALL,
)
def parse(self, html: str, url: str = "") -> ParseResult:
soup = BeautifulSoup(html, "lxml")
result = ParseResult(platform=self.platform, parser_name=self.__class__.__name__)
# Find all Squarespace HTML content blocks
content_blocks = soup.find_all("div", class_="sqs-html-content")
for block in content_blocks:
# Look for h3 headings that contain unit listings
for heading in block.find_all(re.compile(r"h[1-6]")):
heading_text = heading.get_text(strip=True)
match = self._UNIT_RE.search(heading_text)
if not match:
continue
width = float(match.group(1))
length = float(match.group(2))
sqft = float(match.group(3))
price_str = match.group(4).replace(",", "")
price = float(price_str)
size_label = f"{int(width)}' x {int(length)}'"
# Collect description from sibling <p> tags in the same block
description_parts = []
for sibling in heading.find_next_siblings(["p", "ul"]):
sibling_text = sibling.get_text(separator=" ", strip=True)
if sibling_text:
description_parts.append(sibling_text)
description = " ".join(description_parts) if description_parts else None
unit = UnitResult(
size=size_label,
price=price,
description=description,
metadata={
"width": width,
"length": length,
"sqft": sqft,
},
)
result.units.append(unit)
if not result.units:
result.warnings.append("No unit headings found matching expected pattern")
return result
Scrape Runs (5)
-
exported Run #14982026-03-23 03:21:32.974980 | Facility017878Parser
-
exported Run #10052026-03-21 19:14:52.505487 | Facility017878Parser
-
exported Run #5582026-03-14 16:56:26.938503 | Facility017878Parser
-
exported Run #1632026-03-14 05:00:24.048068 | Facility017878Parser
-
exported Run #862026-03-14 01:02:03.615218 | Facility017878Parser
Run #86 Details
- Status
- exported
- Parser Used
- Facility017878Parser
- Platform Detected
- table_layout
- Units Found
- 0
- Stage Reached
- exported
- Timestamp
- 2026-03-14 01:02:03.615218
Timing
| Stage | Duration |
|---|---|
| Fetch | 3256ms |
| Detect | 10ms |
| Parse | 5ms |
| Export | 12ms |
Snapshot: 017878_20260314T010206Z.html · Show Snapshot · Open in New Tab
No units found in this run.
All Failures for this Facility (5)
parse
_WarningAsException
scraper
no_units_extracted
warning
Run #N/A | 2026-03-23 03:21:36.953966
No units extracted for 017878
Stack trace
src.reporting.failure_reporter._WarningAsException: No units extracted for 017878
parse
_WarningAsException
scraper
no_units_extracted
warning
Run #N/A | 2026-03-21 19:14:56.273587
No units extracted for 017878
Stack trace
src.reporting.failure_reporter._WarningAsException: No units extracted for 017878
parse
_WarningAsException
scraper
no_units_extracted
warning
Run #N/A | 2026-03-14 16:56:30.195770
No units extracted for 017878
Stack trace
src.reporting.failure_reporter._WarningAsException: No units extracted for 017878
parse
_WarningAsException
scraper
no_units_extracted
warning
Run #N/A | 2026-03-14 05:00:28.003501
No units extracted for 017878
Stack trace
src.reporting.failure_reporter._WarningAsException: No units extracted for 017878
parse
_WarningAsException
scraper
no_units_extracted
warning
Run #N/A | 2026-03-14 01:02:06.929500
No units extracted for 017878
Stack trace
src.reporting.failure_reporter._WarningAsException: No units extracted for 017878