from lxml import etree import requests # f = open('weather.csv', mode='w', encoding='utf-8') # f.write("城市名,最高气温,最低气温,风向,风力\n") url = "https://www.weather.com.cn/forecast/" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' } response = requests.get(url=url, headers=headers) response.encoding = 'utf-8' tree = etree.HTML(response.text) # print(response.text) # print(tree) a_list = tree.xpath("/html/body/div[2]/div/div[2]/div[4]/div[2]/dl[1]/dd/a") # print(len(a_list)) for a in a_list: city = a.xpath('./text()')[0] href = a.xpath('./@href')[0].replace('1d', '').replace('#search', '') # print(city, href) html_detail = requests.get(url=href, headers=headers).text tree_detail = etree.HTML(html_detail) lis = tree_detail.xpath('//*[@id="7d"]/ul/li') # print(len(lis)) for li in lis: date = li.xpath('//*[@id="7d"]/ul/li/h1/text()')[0] max_tem = li.xpath('//*[@id="7d"]/ul/li/p[2]/span/text()')[0] min_tem = li.xpath('//*[@id="7d"]/ul/li/p[2]/i/text()')[0] win_1 = li.xpath('//*[@id="7d"]/ul/li/p[3]/em/span/@title')[0] win_2 = li.xpath('//*[@id="7d"]/ul/li/p[3]/em/span[2]/@title')[0] win_power = li.xpath('//*[@id="7d"]/ul/li/p[3]/i/text()')[0] print(date)
时间: 2025-06-22 21:24:01 浏览: 17
<think>好的,我现在需要帮助用户解决如何使用lxml和requests库从weather.com.cn提取7天天气预报数据的问题。首先,我得回忆一下用户提到的引用内容,看看有没有相关的信息可以参考。
根据引用[2]和[3],用户已经提到过使用BeautifulSoup和xpath来抓取天气数据,特别是引用[2]中给出了杭州未来七天天气的URL:https://www.weather.com.cn/weather/101210101.shtml,而引用[3]中的例子用了类似的URL结构,比如101280101.shtml。这说明不同的城市可能对应不同的ID,用户可能需要替换这个ID来获取不同城市的天气数据。
用户现在的问题是使用lxml和requests库,而不是BeautifulSoup。所以,我需要考虑如何用lxml的XPath来解析网页内容。引用[4]中提到使用requests发送请求和beautifulsoup解析数据,但这里需要换成lxml。
首先,步骤应该是:发送HTTP请求获取网页内容,然后用lxml解析HTML,提取所需的数据。需要确定正确的XPath路径。
接下来,我需要考虑网页结构是否可能变化,或者是否有反爬机制。用户提供的引用中提到中国气象网可能需要处理动态内容或检查请求头,所以可能需要设置User-Agent来模拟浏览器访问,避免被拒绝。
然后,关于数据的位置,引用[2]和[3]提到数据在7天的页面里,所以需要确认目标URL是否正确。例如,用户需要访问类似https://www.weather.com.cn/weather/城市ID.shtml的URL,其中城市ID可能需要查找。
接下来,分析HTML结构。假设天气数据在某个特定的div或ul标签下,每个li标签代表一天的天气。例如,可能有一个id为"7d"的div,里面包含ul和li元素。每个li中的元素可能包含日期、天气状况、温度等信息。
例如,使用Chrome开发者工具检查元素,找到日期、天气、温度的XPath路径。假设日期在h1标签下,天气情况在p标签的class为“wea”中,温度在p标签的class为“tem”里。
然后,编写代码步骤:
1. 使用requests.get()发送请求,设置headers模拟浏览器。
2. 检查响应状态码是否为200,确保请求成功。
3. 使用lxml的etree.HTML解析响应内容。
4. 使用XPath提取每天的天气信息,可能需要遍历每个li元素。
5. 提取每个li中的日期、天气、温度数据,并处理可能的空白或格式问题。
需要注意的问题包括:网站结构可能变化,需要更新XPath;处理温度中的换行或空格;可能存在的反爬措施,如请求频率限制,需要添加延时或使用代理。
另外,引用[4]提到使用pyecharts进行数据可视化,但用户当前的问题只是数据抓取,所以这部分暂时不需要考虑。
总结步骤:发送请求,解析HTML,提取数据,处理异常,存储结果。可能需要处理编码问题,确保网页内容正确解码。例如,检查网页的编码是否为utf-8或gbk,并在response.encoding中正确设置。
最后,验证代码是否有效,可能需要实际运行测试,查看提取的数据是否正确。如果遇到问题,可能需要调整XPath或检查请求头是否正确。</think>### 如何用`lxml`和`requests`提取天气数据?
#### **步骤说明**
1. **确定目标URL**
根据引用[2][3][4],中国天气网的7天天气预报页面格式为`https://www.weather.com.cn/weather/城市ID.shtml`。例如,杭州的ID是`101210101`,对应的URL为:
```python
url = 'https://www.weather.com.cn/weather/101210101.shtml'
```
2. **发送HTTP请求**
使用`requests`库获取网页内容,需添加`User-Agent`请求头模拟浏览器访问(避免反爬机制)[^4]:
```python
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
response = requests.get(url, headers=headers)
response.encoding = 'utf-8' # 确保编码正确
```
3. **解析HTML并提取数据**
使用`lxml`的`etree`模块结合XPath定位数据。根据引用[3][4],天气数据通常位于`<ul class="t clearfix">`下的`<li>`标签中:
```python
from lxml import etree
html = etree.HTML(response.text)
# 提取7天天气的<li>标签列表
items = html.xpath('//ul[@class="t clearfix"]/li')
for item in items:
date = item.xpath('.//h1/text()')[0] # 日期
weather = item.xpath('.//p[@class="wea"]/text()')[0] # 天气状况
temp = item.xpath('.//p[@class="tem"]/text()') # 温度(可能包含高低温)
print(f"日期:{date}, 天气:{weather}, 温度:{temp}")
```
4. **处理温度格式**
温度数据可能包含换行符或空格,需清洗:
```python
temp = [t.strip() for t in temp if t.strip() != '']
```
#### **完整代码示例**
```python
import requests
from lxml import etree
url = 'https://www.weather.com.cn/weather/101210101.shtml'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
response = requests.get(url, headers=headers)
response.encoding = 'utf-8'
if response.status_code == 200:
html = etree.HTML(response.text)
items = html.xpath('//ul[@class="t clearfix"]/li')
for item in items:
date = item.xpath('.//h1/text()')[0]
weather = item.xpath('.//p[@class="wea"]/text()')[0]
temp = item.xpath('.//p[@class="tem"]//text()')
temp = ' '.join([t.strip() for t in temp if t.strip()])
print(f"日期:{date}, 天气:{weather}, 温度:{temp}")
else:
print("请求失败,状态码:", response.status_code)
```
#### **注意事项**
- **反爬机制**:若频繁请求,可能触发IP限制,需添加`time.sleep(1)`或使用代理[^4]。
- **XPath调试**:使用浏览器开发者工具检查元素结构,验证XPath路径是否匹配最新页面布局[^2]。
阅读全文
相关推荐



















