DuckDuckGo's weather widget uses randomized CSS module class names (e.g. wbUB0U7KMDyukXtzMd8Y) that change on every build, so all the BEM-style selectors (.module__current-temp, .forecast-day__name, etc.) return empty results
Replaced all class-based selectors with structural and attribute-based selectors that are resilient to class name changes:
Widget identified via article:has(img[src*='weatherkit'])
All existing unit tests updated and passing (go test ./...)
Verified against live DuckDuckGo weather widget via Playwright (DOM structure confirmed)
Manual test with GetWeather() against live site
## Summary
- DuckDuckGo's weather widget uses randomized CSS module class names (e.g. `wbUB0U7KMDyukXtzMd8Y`) that change on every build, so all the BEM-style selectors (`.module__current-temp`, `.forecast-day__name`, etc.) return empty results
- Replaced all class-based selectors with structural and attribute-based selectors that are resilient to class name changes:
- Widget identified via `article:has(img[src*='weatherkit'])`
- Positional selectors (`div:first-child`, `p:first-of-type`, `div:nth-child(2)`)
- Icon hints extracted from `img[alt]` attributes
- Precipitation parsed from `span > span` structure
- Humidity/Wind identified by text content matching
- `CurrentTemp` now derived from first hourly entry (DDG no longer shows a standalone current temperature element)
- `HighTemp`/`LowTemp` now derived from first daily forecast entry
- Updated all mock tests to match the new DOM structure
Fixes #53
## Test plan
- [x] All existing unit tests updated and passing (`go test ./...`)
- [x] Verified against live DuckDuckGo weather widget via Playwright (DOM structure confirmed)
- [ ] Manual test with `GetWeather()` against live site
DuckDuckGo's weather widget uses randomized CSS module class names that
don't match the BEM-style selectors the extractor was using. Replace all
class-based selectors with structural and attribute-based selectors:
- Identify widget via article:has(img[src*='weatherkit'])
- Use positional selectors (div:first-child, p:first-of-type, etc.)
- Extract icon hints from img[alt] attributes
- Parse precipitation from span > span structure
- Derive CurrentTemp from first hourly entry (no standalone element)
- Derive HighTemp/LowTemp from first daily forecast entry
- Use text-matching for Humidity/Wind labels
Fixes#53
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
wbUB0U7KMDyukXtzMd8Y) that change on every build, so all the BEM-style selectors (.module__current-temp,.forecast-day__name, etc.) return empty resultsarticle:has(img[src*='weatherkit'])div:first-child,p:first-of-type,div:nth-child(2))img[alt]attributesspan > spanstructureCurrentTempnow derived from first hourly entry (DDG no longer shows a standalone current temperature element)HighTemp/LowTempnow derived from first daily forecast entryFixes #53
Test plan
go test ./...)GetWeather()against live site