Facility: 086109
Sheridan Storage
- Facility ID
- 086109
- Name
- Sheridan Storage
- URL
- https://www.sheridanstorage.us/self-storage-sheridan-wy-f2632
- Address
- N/A
- Platform
- custom_facility_086109
- Parser File
- src/parsers/custom/facility_086109_parser.py
- Last Scraped
- 2026-03-23 03:18:37.897946
- Created
- 2026-03-06 23:45:35.865957
- Updated
- 2026-03-23 03:18:37.905021
- Parser Status
- ✓ Working
- Status Reason
- N/A
- Last Healing Attempt
- Not attempted
Parser Source (src/parsers/custom/facility_086109_parser.py)
"""Parser for Sheridan Self Storage (Sheridan, WY).
This is a StorEdge/RentNow-powered site that renders unit listings
as a table inside a #unitstable div. Each row has three meaningful
columns: size, unit details (address + amenity tags), and price.
"""
from __future__ import annotations
from bs4 import BeautifulSoup
from src.parsers.base import BaseParser, ParseResult, UnitResult
class Facility086109Parser(BaseParser):
"""Extract storage units from Sheridan Self Storage (sheridanstorage.us).
Unit data lives in a <table> inside ``#unitstable``. Each ``<tr>``
in the ``<tbody>`` represents one unit type with columns:
- td[0]: size (e.g. "5'x10'")
- td[1]: unit details (address and optional amenity labels separated
by commas, e.g. "1818 Terra Ave, Interior, Heated")
- td[2]: monthly price (e.g. "$80")
"""
platform = "custom_facility_086109"
# CSS selectors derived from the rendered snapshot
_SIZE_SEL = "._2MVARJZtZDaHzpMVh0UAfo"
_PRICE_SEL = "._3V2N9w-4bQvYJ9lUWBSkHt"
def parse(self, html: str, url: str = "") -> ParseResult:
soup = BeautifulSoup(html, "lxml")
result = ParseResult(platform=self.platform, parser_name=self.__class__.__name__)
units_table = soup.find(id="unitstable")
if not units_table:
result.warnings.append("No #unitstable element found on page")
return result
table = units_table.find("table")
if not table:
result.warnings.append("#unitstable found but contains no <table>")
return result
tbody = table.find("tbody")
if not tbody:
result.warnings.append("Table has no <tbody>")
return result
rows = tbody.find_all("tr")
if not rows:
result.warnings.append("No <tr> rows found in table body")
return result
for row in rows:
cells = row.find_all("td")
if len(cells) < 3:
continue
unit = UnitResult()
# --- Size ---
size_el = cells[0].select_one(self._SIZE_SEL)
if size_el:
raw_size = size_el.get_text(strip=True)
unit.size = raw_size
w, ln, sq = self.normalize_size(raw_size)
if w is not None:
unit.metadata = {"width": w, "length": ln, "sqft": sq}
# --- Description (address + amenity labels) ---
desc_text = cells[1].get_text(separator=", ", strip=True)
if desc_text:
unit.description = desc_text
# Derive amenity flags for metadata
lower = desc_text.lower()
amenities: list[str] = []
if "heated" in lower or "climate" in lower:
amenities.append("climate_control")
if "interior" in lower or "indoor" in lower:
amenities.append("interior")
if "rv" in lower or "parking" in lower or "uncovered" in lower:
amenities.append("vehicle_parking")
if amenities:
meta = unit.metadata or {}
meta["amenities"] = amenities
unit.metadata = meta
# --- Price ---
price_el = cells[2].select_one(self._PRICE_SEL)
if price_el:
unit.price = self.normalize_price(price_el.get_text(strip=True))
if unit.size or unit.price:
result.units.append(unit)
if not result.units:
result.warnings.append("No units found on page")
return result
Scrape Runs (5)
-
exported Run #14722026-03-23 03:18:34.658298 | 5 units | Facility086109Parser | View Data →
-
exported Run #9792026-03-21 19:11:28.205131 | 5 units | Facility086109Parser | View Data →
-
exported Run #5322026-03-14 16:54:03.007653 | 7 units | Facility086109Parser | View Data →
-
exported Run #1342026-03-14 01:05:44.766251 | 6 units | Facility086109Parser | View Data →
-
exported Run #532026-03-13 21:37:25.974995 | 6 units | Facility086109Parser | View Data →
Run #532 Details
- Status
- exported
- Parser Used
- Facility086109Parser
- Platform Detected
- storageunitsoftware
- Units Found
- 7
- Stage Reached
- exported
- Timestamp
- 2026-03-14 16:54:03.007653
Timing
| Stage | Duration |
|---|---|
| Fetch | 2770ms |
| Detect | 24ms |
| Parse | 11ms |
| Export | 14ms |
Snapshot: 086109_20260314T165405Z.html · Show Snapshot · Open in New Tab
Parsed Units (7)
5'x10'
$80.00/mo
5'x10'
$100.00/mo
10'x10'
$90.00/mo
10'x15'
$100.00/mo
12'x25'
$70.00/mo
12'x35'
$80.00/mo
12'x45'
$90.00/mo