python爬取中国天气网天气图标

python爬取中国天气网天气图标

准备工作

  • 天气预报图例网址:http://www.weather.com.cn/static/html/legend.shtml
  • 安装requests:pip install requests

网页分析

  • 打开网页,可以看到图标有很多,而且分白天和夜间,我们要把图标保存到本地,并且图标名字要对应

在这里插入图片描述
- 右键查看网页源代码,发现图标和名称都放到 <td width="12%" ...td 标签下,而我们要做的就是提取其中的图片和名称
在这里插入图片描述

编写代码

爬取网页

import requests
url = 'http://www.weather.com.cn/static/html/legend.shtml'
def getPage():
  # 请求头
  headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5383.400 QQBrowser/10.0.1313.400"}
  res = requests.get(url, headers)
  # 手动指定字符编码为utf-8
  res.encoding = 'utf-8'
  print(res.text)
  return res.text
if __name__ == "__main__":
  getPage()
  • requests库的使用方法非常简单,requests.get(网页url) 就可以拿到网页内容了,但是为了模拟浏览器请求,最好还是加上请求头headers

  • requests响应内容:
    res.encoding:可以拿到当前的编码格式,也可以设置编码格式
    res.text:字符串响应体,这里就是网页的源代码
    res.content:二进制的响应体,如果是图片需要用到

    r.encoding                       #获取当前的编码
    r.encoding = 'utf-8'             #设置编码
    r.text                           #以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字符编码进行解码。
    r.content                        #以字节形式(二进制)返回。字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩。
    r.headers                        #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None
    r.status_code                    #响应状态码
    r.raw                            #返回原始响应体,也就是 urllib 的 response 对象,使用 r.raw.read()   
    r.ok                             # 查看r.ok的布尔值便可以知道是否登陆成功
    r.json()                         #Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常
    r.raise_for_status()             #失败请求(非200响应)抛出异常
    
  • 爬取下来的网页,打印出来时发现中文乱码了,因此需要指定编码方式为 utf-8

提取图片和名称

import re

# td正则
wrapReg = r'<td width="12%"[^>]*>.*?</td>'
# 图片url正则
imgReg = r'<img src="(.*?)"'
# 天气名称正则
nameReg = r'<a[^>]*>([^>]*?)</a>'
# 颜色正则
colorReg = r'bgcolor="(.*?)"'

def run():
  # 爬取网页
  text = getPage()
  # 拿到td标签里的内容
  lis = re.findall(wrapReg, text, re.S|re.M)
  for item in lis:
    bgcolor = re.findall(colorReg, item, re.S|re.M)
    imgUrl = re.findall(imgReg, item, re.S|re.M)
    nameStr = re.findall(nameReg, item, re.S|re.M)
    if imgUrl and len(imgUrl) > 0 and nameStr and len(nameStr) > 0 and bgcolor and len(bgcolor) > 0:
      print('------------')
      print(imgUrl[0], nameStr[0], bgcolor[0])
  1. 首先我们拿到网页的源码 res.text

  2. 然后正则匹配包裹图片和名称的 td 标签,这里需要匹配包含 td 元素。为什么?后面会有说明

    re.findall(pattern, string, flags=0)
    返回string中所有与pattern匹配的全部字符串,返回形式为数组

    wrapReg = r'<td width="12%"[^>]*>.*?</td>'
    1.一个 . 就 是匹配除 \n (换行符)以外的任意一个字符
    2.* 前面的字符出现0次或以上
    3..* 贪婪,匹配从.*前面为开始到后面为结束的所有内容
    4..*? 非贪婪,遇到开始和结束就进行截取,因此截取多次符合的结果,中间没有字符也会被截取
    5.(.*?) 非贪婪,与上面一样,只是与上面的相比多了一个括号,只保留括号的内容,在这里,如果加上括号,则只返回td标签的子元素,不返回td标签本身

    修饰符     描述
    re.I      使匹配对大小写不敏感
    re.L	  做本地化识别(locale-aware)匹配
    re.M	  多行匹配,影响 ^ 和 $
    re.S	  使 . 匹配包括换行在内的所有字符
    re.U      根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
    re.X	  该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解
    
  3. 循环 td 标签列表,继续用正则匹配 td 标签里的 图片url天气名称,td 标签下还有 p > a 标签包裹,图片只需要img 标签 src 属性里面的内容,而天气名称是拿整个 a 标签里的内容,这里注意看括号的位置
    在这里插入图片描述
    在这里插入图片描述

  4. 最后就可以根据图片url和天气名称下载保存图片了,但是还有个问题需要注意,把网页拉到下面发现,td 标签里面可能是空的,因此需要判断是否有正确匹配才继续
    在这里插入图片描述

  5. 另外,还需要匹配一个 td 的属性,bgcolor ,这个也会在后面说明

下载保存图片

# 后缀正则
suffixReg = r'\.([^.]*?)$'
def saveFile(url, name, bgcolor):
  # 获取后缀
  suffix = re.findall(suffixReg, url)
  # 下载文件
  res = requests.get(url)
  # 根据bgcolor区分白天和黑夜文件路径
  filePath = 'day/' if bgcolor == '#FEE6C5' else 'night/'
  print('filePath --> ', filePath)
  # 文件名
  fileName = filePath + name + '.' + suffix[0]
  with open(fileName, 'wb') as f:
    # 保存文件
    f.write(res.content)
    f.close
  • 前面提到,为什么要匹配包含 td 标签以及 bgcolor 有啥用?去掉 td 标签本身不是更简洁?这是因为白天夜间 的天气名称是一样的,如果不分白天夜间,那么保存了白天的图片,程序执行到保存夜间图片的时候,会把白天的图片替换掉。而白天和夜间的图片和名称正则都是相同的,有什么办法来区分白天和黑夜?
  • 回去看源代码,发现了白天和黑夜 td 标签有个属性,白天的 bgcolor="#FEE6C5",而夜间的 bgcolor="#D8E7F8",因此就可以用这个属性来区分,分别将白天图片保存到 day目录下,夜间图片保存到 night目录。需要在当前路径下新建day 和 night 文件夹,否则会报错
  • 另外,保存图片的时候只有图片名称,没有图片后缀,而图片url又刚好有图片的后缀,所以就可以根据图片url的后缀来确定文件的后缀

完整代码

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,您想了解如何用 Python 爬取历史天气数据,是吗? 首先,需要确定您想要爬取哪个地区的历史天气数据。一般来说,可以通过查询该地区的气象局或气象网站获取历史天气数据。 接着,可以使用 Python 中的 requests 库来发送 HTTP 请求,获取页源代码。然后,可以使用 BeautifulSoup 库来解析页源代码,提取出所需的天气数据。 以下是一个简单的示例代码,用于爬取中国天气上北京市 2019 年 1 月份的历史天气数据: ``` python import requests from bs4 import BeautifulSoup url = 'http://www.weather.com.cn/weather/101010100.shtml#dt' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} r = requests.get(url, headers=headers) r.encoding = 'utf-8' soup = BeautifulSoup(r.text, 'html.parser') weather_list = soup.select('.t li') for weather in weather_list: date = weather.select('.time')[0].text weather_detail = weather.select('.temp')[0].text.strip() print(date, weather_detail) ``` 以上代码中,我们首先通过 requests 库发送了一个 GET 请求,获取了北京市天气页源代码。然后,使用 BeautifulSoup 库解析页源代码,提取出了 2019 年 1 月份的天气数据,并打印输出了日期和天气详情。 需要注意的是,不同的网站页结构不同,需要根据具体情况修改代码。同时,需要注意网站的 robots.txt 文件,不要过度访问网站,以免被封 IP 或其他限制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值