使用Python+requests+BeautifulSoup定位HTML标签获取10天天气遇阻
Hey there! Let's break down what's going wrong with your Bing weather scraping code and get that 10-day forecast working properly.
First, Fix the Class Name Mismatch
You mentioned the HTML uses classes like wtr-weekday, wtr-high, wtr-low, and wtr-precip (with hyphens), but your code is searching for underscore versions (wtr_weekday, wtr_high, etc.). That's a common typo that'll prevent BeautifulSoup from finding any elements—so we need to fix those class names first to match the actual page markup.
Next, Fix the find_all() vs find() Problem
find_all() returns a list of elements, not a single element. So when you try to call .text directly on the result of find_all(), you'll hit an error because lists don't have a .text method. Since each forecast day card only has one of each element (one weekday, one high temp, etc.), we should use find() instead—it returns the first matching element, which is exactly what we need here.
Corrected Code Example
Here's the revised code that should work with the Bing weather page you linked:
# Assuming you've already fetched the page and parsed it with BeautifulSoup forecast_container = soup.find("div", class_="wtr_innerScroll") if forecast_container: day_tabs = forecast_container.find_all("div", class_="wtr_forecastDay wtr_noselect") for day in day_tabs: # Extract each field using find() instead of find_all() weekday = day.find("div", class_="wtr-weekday") temp_high = day.find("div", class_="wtr-high") temp_low = day.find("div", class_="wtr-low") precip = day.find("div", class_="wtr-precip") # Handle cases where an element might be missing (to avoid AttributeError) weekday_text = weekday.text.strip() if weekday else "N/A" high_text = temp_high.text.strip() if temp_high else "N/A" low_text = temp_low.text.strip() if temp_low else "N/A" precip_text = precip.text.strip() if precip else "N/A" # Print the formatted forecast print(f"{weekday_text}\nHigh: {high_text} | Low: {low_text}\nPrecipitation: {precip_text}\n---") else: print("Could not find the 10-day forecast container.")
Key Changes Explained
- Swapped underscores for hyphens in all class names to match the actual HTML structure.
- Used
find()instead offind_all()for individual fields since each day only has one of each element. - Added conditional checks to handle missing elements (Bing might tweak their markup occasionally, so this makes your code more robust).
- Used f-strings for cleaner formatting, and
.strip()to remove extra whitespace from the extracted text.
Quick Note on Element Locating
I checked the test URL you provided, and your initial container selection (wtr_innerScroll) was spot-on—it's the correct parent for the 10-day forecast cards. The wtr_forecastDay wtr_noselect class also correctly targets each individual day's card, so you were already on the right path with your initial setup!
内容的提问来源于stack exchange,提问作者joon_bug

