用python爬取历史天气数据的方法示例

某天气网站(www.数字.com)存有2011年至今的天气数据,有天看到一本爬虫教材提到了爬取这些数据的方法,学习之,并加以改进。

准备爬的历史天气

爬之前先分析url。左上有年份、月份的下拉选择框,按F12,进去看看能否找到真正的url:

很容易就找到了,左边是储存月度数据的js文件,右边是文件源代码,貌似json格式。

双击左边js文件,地址栏内出现了url:http://tianqi.数字.com/t/wea_history/js/54511_20161.js

url中的“54511”是城市代码,“20161”是年份和月份代码。下一步就是找到城市代码列表,按城市+年份+月份构造url列表,就能开始遍历爬取了。

城市代码也很诚实,很快就找到了:

下一步得把城市名称和代码提取出来,构造一个“城市名称:城市代码”的字典,或者由元组(城市名称,城市代码)组成的列表,供爬取时遍历。考虑到正则提取时,构造元组更便捷,就不做成字典了。

def getCity():
  html = reqs.get('https://tianqi.2345.com/js/citySelectData.js').content
  text = html.decode('gbk')
  city = re.findall('([1-5]\d{4})\-[A-Z]\s(.*?)\-\d{5}',text)  #只提取了地级市及以上城市的名称和代码,5以上的是县级市
  city = list(set(city))                    #去掉重复城市数据
  print('城市列表获取成功')
  return city

接下来是构造url列表,感谢教材主编的提醒,这里避免了一个大坑。原来2017年之前的url结构和后面的不一样,在这里照搬了主编的构造方法:

def getUrls(cityCode):
  urls = []
  for year in range(2011,2020):
    if year <= 2016:
      for month in range(1, 13):
        urls.append('https://tianqi.数字.com/t/wea_history/js/%s_%s%s.js' % (cityCode,year, month))
    else:
      for month in range(1,13):
        if month<10:
          urls.append('https://tianqi.数字.com/t/wea_history/js/%s0%s/%s_%s0%s.js' %(year,month,cityCode,year,month))
        else:
          urls.append('https://tianqi.数字.com/t/wea_history/js/%s%s/%s_%s%s.js' %(year,month,cityCode,year,month))
  return urls

接下来定义一个爬取页面的函数getHtml(),这个是常规操作,用requests模块就行了:

def getHtml(url):
  header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1',
       'Referer': '******'}
  request = reqs.get(url,headers = header)
  text = request.content.decode('gbk') #经试解析,这里得用gbk模式
  time.sleep(random.randint(1,3))    #随机暂停,减轻服务器压力
  return text

然后就是重点部分了,数据解析与提取。

试了试json解析,发现效果不好,因为页面文本里面含杂质。

还是用正则表达式吧,能够提取有效数据,尽可能少浪费机器时间。

2016年开始的数据和之前年份不一样,多了PM2.5污染物情况,因此构造正则表达式时,还不能用偷懒模式。

str1 = "{ymd:'(.*?)',bWendu:'(.*?)℃',yWendu:'(.*?)℃',tianqi:'(.*?)',fengxiang:'(.*?)',fengli:'(.*?)',aqi:'(.*?)',aqiInfo:'(.*?)',aqiLevel:'(.*?)'.*?}"
str2 = "{ymd:'(.*?)',bWendu:'(.*?)℃',yWendu:'(.*?)℃',tianqi:'(.*?)',fengxiang:'(.*?)',fengli:'(.*?)'.*?}"

#这个就是偷懒模式,取出来的内容直接存入元组中

如果严格以2016年为界,用一下偷懒模式还行,但本人在这里遇坑了,原来个别城市的污染物信息是时有时无的,搞不清在某年某月的某天就出现了,因此还得构造一个通用版的,把数据都提出来,再把无用的字符去掉。

def getDf(url):
  html = getHtml(url)
  pa = re.compile(r'{(ymd.+?)}')           #用'{ymd'打头,把不是每日天气的其它数据忽略掉
  text = re.findall(pa,html)
  list0 = []
  for item in text:
    s = item.split(',')              #分割成每日数据
    d = [i.split(':') for i in s]         #提取冒号前后的数据名称和数据值
    t = {k:v.strip("'").strip('℃') for k,v in d} #用数据名称和数据值构造字典
    list0.append(t)
  df = pd.DataFrame(list0)              #加入pandas列表中,便于保存
  return df 

数据的保存,这里选择了sqlite3轻便型数据库,可以保存成db文件:

def work(city,url):
  con =sql.connect('d:\\天气.db')
  try:
    df = getDf(url)
    df.insert(0,'城市名称',city)                #新增一列城市名称
    df.to_sql('total', con, if_exists='append', index=False)
    print(url,'下载完成')
  except Exception as e:
    print("出现错误:\n",e)
  finally:
    con.commit()
    con.close()

在这里还有一个小坑,第一次连接数据库文件时,如果文件不存在,会自动添加,后续在写入数据时,如果数据中新增了字段,写入时会报错。可以先把数据库文件字段都设置好,但这样太累,所以本人又搞了个偷懒的方式,即先传入一个2019年某月的单个url搞一下,自动添加好字段,后面再写入时就没问题了。本人觉得这个应该还有更佳的解决办法,目前还在挖掘中。

数据保存后的状态如下:

本来考虑过用多线程爬虫,想想又觉得既然人家没有设置反爬措施,咱们也不能太不厚道了,就单线程吧。

最终爬了334个城市,100多万条数据。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • python爬取拉勾网职位数据的方法

    今天写的这篇文章是关于python爬虫简单的一个使用,选取的爬取对象是著名的招聘网站--拉钩网,由于和大家的职业息息相关,所以爬取拉钩的数据进行分析,对于职业规划和求职时的信息提供有很大的帮助. 完成的效果 爬取数据只是第一步,怎样使用和分析数据也是一大重点,当然这不是本次博客的目的,由于本次只是一个上手的爬虫程序,所以我们的最终目的只是爬取到拉钩网的职位信息,然后保存到Mysql数据库中.最后中的效果示意图如下: 控制台输入 数据库显示 准备工作 首先需要安装python,这个网上已经有很多的

  • python爬取安居客二手房网站数据(实例讲解)

    是小打小闹 哈哈,现在开始正式进行爬虫书写首先,需要分析一下要爬取的网站的结构:作为一名河南的学生,那就看看郑州的二手房信息吧! 在上面这个页面中,我们可以看到一条条的房源信息,从中我们发现了什么,发现了连郑州的二手房都是这么的贵,作为即将毕业的学生狗惹不起啊惹不起 还是正文吧!!!由上可以看到网页一条条的房源信息,点击进去后就会发现: 房源的详细信息.OK!那么我们要干嘛呢,就是把郑州这个地区的二手房房源信息都能拿到手,可以保存到数据库中,用来干嘛呢,作为一个地理人,还是有点用处的,这次就不说

  • python爬虫爬取网页表格数据

    用python爬取网页表格数据,供大家参考,具体内容如下 from bs4 import BeautifulSoup import requests import csv import bs4 #检查url地址 def check_link(url): try: r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: print('无法链接服务器!!!')

  • Python爬虫实例_城市公交网络站点数据的爬取方法

    爬取的站点:http://beijing.8684.cn/ (1)环境配置,直接上代码: # -*- coding: utf-8 -*- import requests ##导入requests from bs4 import BeautifulSoup ##导入bs4中的BeautifulSoup import os headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,

  • python如何爬取网站数据并进行数据可视化

    前言 爬取拉勾网关于python职位相关的数据信息,并将爬取的数据已csv各式存入文件,然后对csv文件相关字段的数据进行清洗,并对数据可视化展示,包括柱状图展示.直方图展示.词云展示等并根据可视化的数据做进一步的分析,其余分析和展示读者可自行发挥和扩展包括各种分析和不同的存储方式等..... 一.爬取和分析相关依赖包 Python版本: Python3.6 requests: 下载网页 math: 向上取整 time: 暂停进程 pandas:数据分析并保存为csv文件 matplotlib:

  • Python爬取数据并写入MySQL数据库的实例

    首先我们来爬取 http://html-color-codes.info/color-names/ 的一些数据. 按 F12 或 ctrl+u 审查元素,结果如下: 结构很清晰简单,我们就是要爬 tr 标签里面的 style 和 tr 下几个并列的 td 标签,下面是爬取的代码: #!/usr/bin/env python # coding=utf-8 import requests from bs4 import BeautifulSoup import MySQLdb print('连接到m

  • python爬取网站数据保存使用的方法

    编码问题因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这个机会算是彻底搞清楚了.问题要从文字的编码讲起.原本的英文编码只有0~255,刚好是8位1个字节.为了表示各种不同的语言,自然要进行扩充.中文的话有GB系列.可能还听说过Unicode和UTF-8,那么,它们之间是什么关系呢?Unicode是一种编码方案,又称万国码,可见其包含之广.但是具体存储到计算机上,并不用这种编码,可以说它起着一个中间人的作用.你可以再把Unicode编码(encode)为UTF-8,或者GB,再存储到计算机

  • python爬取淘宝商品详情页数据

    在讲爬取淘宝详情页数据之前,先来介绍一款 Chrome 插件:Toggle JavaScript (它可以选择让网页是否显示 js 动态加载的内容),如下图所示: 当这个插件处于关闭状态时,待爬取的页面显示的数据如下: 当这个插件处于打开状态时,待爬取的页面显示的数据如下:   可以看到,页面上很多数据都不显示了,比如商品价格变成了划线价格,而且累计评论也变成了0,说明这些数据都是动态加载的,以下演示真实价格的找法(评论内容找法类似),首先检查页面元素,然后点击Network选项卡,刷新页面,可

  • 一个月入门Python爬虫学习,轻松爬取大规模数据

    Python爬虫为什么受欢迎 如果你仔细观察,就不难发现,懂爬虫.学习爬虫的人越来越多,一方面,互联网可以获取的数据越来越多,另一方面,像 Python这样的编程语言提供越来越多的优秀工具,让爬虫变得简单.容易上手. 利用爬虫我们可以获取大量的价值数据,从而获得感性认识中不能得到的信息,比如: 知乎:爬取优质答案,为你筛选出各话题下最优质的内容. 淘宝.京东:抓取商品.评论及销量数据,对各种商品及用户的消费场景进行分析. 安居客.链家:抓取房产买卖及租售信息,分析房价变化趋势.做不同区域的房价分

  • 实例讲解Python爬取网页数据

    一.利用webbrowser.open()打开一个网站: >>> import webbrowser >>> webbrowser.open('http://i.firefoxchina.cn/?from=worldindex') True 实例:使用脚本打开一个网页. 所有Python程序的第一行都应以#!python开头,它告诉计算机想让Python来执行这个程序.(我没带这行试了试,也可以,可能这是一种规范吧) 1.从sys.argv读取命令行参数:打开一个新的文

  • 利用Python爬取微博数据生成词云图片实例代码

    前言 在很早之前写过一篇怎么利用微博数据制作词云图片出来,之前的写得不完整,而且只能使用自己的数据,现在重新整理了一下,任何的微博数据都可以制作出来,一年一度的虐汪节,是继续蹲在角落默默吃狗粮还是主动出击告别单身汪加入散狗粮的行列就看你啦,七夕送什么才有心意,程序猿可以试试用一种特别的方式来表达你对女神的心意.有一个创意是把她过往发的微博整理后用词云展示出来.本文教你怎么用Python快速创建出有心意词云,即使是Python小白也能分分钟做出来.下面话不多说了,来一起看看详细的介绍吧. 准备工作

随机推荐