fix: use structural selectors for DDG weather to handle advisory banners
The weather extractor used positional CSS selectors (div:first-child, div:nth-child(2)) to locate the header and hourly container within the widget section. When DuckDuckGo inserts advisory banners (e.g. wind advisory), the extra div shifts positions and breaks extraction of current temp, hourly data, humidity, and wind. Replace with structural selectors: - div:not(:has(ul)) for the header (first div without a list) - div:has(> ul) for the hourly container (div with direct ul child) These match elements by their content structure rather than position, so advisory banners no longer break extraction. Fixes #64 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -86,8 +86,10 @@ func extractWeather(doc extractor.Node) (*WeatherData, error) {
|
||||
}
|
||||
|
||||
// Header: condition and location
|
||||
// Structure: section > div:first-child > [div(toggle), p(condition), p(location)]
|
||||
header := section.SelectFirst("div:first-child")
|
||||
// Structure: section > div > [div(toggle), p(condition), p(location)]
|
||||
// Use :not(:has(ul)) to skip the hourly container div and avoid breaking
|
||||
// when advisory banners (e.g. wind advisory) insert extra divs.
|
||||
header := section.SelectFirst("div:not(:has(ul))")
|
||||
if header != nil {
|
||||
ps := header.Select("p")
|
||||
if len(ps) >= 2 {
|
||||
@@ -99,8 +101,10 @@ func extractWeather(doc extractor.Node) (*WeatherData, error) {
|
||||
}
|
||||
|
||||
// Hourly forecast and details
|
||||
// Structure: section > div:nth-child(2) > [ul(hourly items), div(humidity/wind)]
|
||||
hourlyContainer := section.SelectFirst("div:nth-child(2)")
|
||||
// Structure: section > div > [ul(hourly items), div(humidity/wind)]
|
||||
// Use :has(> ul) to find the div containing the hourly list, regardless of
|
||||
// position. This avoids breaking when advisory banners insert extra divs.
|
||||
hourlyContainer := section.SelectFirst("div:has(> ul)")
|
||||
if hourlyContainer != nil {
|
||||
_ = hourlyContainer.ForEach("ul > li", func(n extractor.Node) error {
|
||||
var hour HourlyForecast
|
||||
|
||||
Reference in New Issue
Block a user