Python 爬取天气网及3种数据储存方式(MySQL / Mongo / CSV)

今天完成整理一篇学习笔记,有关BeatifulSoup和XPath使用比较。但是由于刚刚学习爬虫不久,许网页元素定位获取的方法和技巧还没有完全掌握,所以今天先按照自己的节奏跳过这篇作业,继续完成爬虫实战,等到对BeatifulSoup和XPath使用熟练后,再做一次深入详细的总结笔记。今天虽然不比较BeatifulSoup和XPath,但是我会在爬取中国天气网数据后,对爬取数据的三种储存方式(MySQL数据库、Mongo数据库和CSV文件)进行简单的比较。
1.作业要求:爬取中国天气网 你所在城市过去一年的历史数据
中国天气网URL:http://www.weather.com.cn/forecast/
2.思路分析:
中国天气网的数据是JS异步加载返回的,需要抓包获取数据,抓包后返回的数据结构是JSON形式,可以直接采用Python的json库中的json.loads()函数进行反序话转换成字典类型进行处理,具体分析步骤如图:
(1)具体获取数据的网址:http://www.weather.com.cn/weather40d/101060201.shtml

中国天气网获取数据网页

(2)点击切换月份按钮,查看不同月份天气,发现网页URL没有变化,判断为js异步加载数据


网页URL.png

(3)按F12查看Network,点击切换月份,发现每次点击都有新的js加载出现:


F12-Network.png

(4)分别查看动态加载的js的Headers和Response查看请求的URL规律和返回值。发现日期的变化包含在Request Url中,返回值即为json格式的天气数据。


Headers_Resquest url.png

Response.png

(5)Copy as cURL使用Postman发送请求测试,发现Headers中不携带Referer将返回403拒绝访问,所以在Headers请求中需携带Referer。


Copy as cURL.png
Postman请求测试.png

(6)程序代码1(存储到MySQL数据库):

import requests
import json
import pymysql
class WeatherSpider(object):
    connect = pymysql.connect(
        host='localhost', 
        user='root', 
        passwd='root',  
        db='test',  
        port=3306,  
        charset='utf8'
        )
    cursor = connect.cursor()
    def __inti__(self):
        pass
    def request(self,url):
        #请求头(不带Referer将返回403,用Postman测试)
        headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
        'Referer': 'http://www.weather.com.cn/weather40d/101060201.shtml'
        }
        return requests.get(url,headers=headers)
    def create_url(self):
        year = '2016'
        for i in range(1,13):
            month = str(i) if i > 9 else "0" + str(i)
            url = "http://d1.weather.com.cn/calendar_new/" + year + "/101060201_" + year + month + ".html"
            self.get_data(url)
        #关闭数据库链接,释放资源
        self.connect.close()
    def get_data(self,url):
        respone = self.request(url).content
        json_str = respone.decode(encoding='utf-8')[11:]
        weathers = json.loads(json_str)
        for weather in weathers:
            self.cursor.execute("use test")
            self.cursor.execute("insert into jilin_weather_tbl (date,week,hmax,hmin,hgl) values(%s,%s,%s,%s,%s)",(weather.get('date'),'星期'+weather.get('wk'),weather.get('hmax'),weather.get('hmin'),weather.get('hgl'))) 
            self.connect.commit()
if __name__ == '__main__':
    jl_weather = WeatherSpider()
    jl_weather.create_url()

实现效果图:


存入MySQL数据库.png

(7)程序代码2(存储到Mongo数据库)

import requests
import json
import pymongo
class WeatherSpider(object):
    client = pymongo.MongoClient('localhost', 27017)
    mydb = client['mydb']
    jilin_weather = mydb['jilin_weather']
    def __inti__(self):
        pass
    def request(self,url):
        #请求头(不带Referer将返回403,用Postman测试)
        headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
        'Referer': 'http://www.weather.com.cn/weather40d/101060201.shtml'
        }
        return requests.get(url,headers=headers)
    def create_url(self):
        year = '2016'
        for i in range(1,13):
            month = str(i) if i > 9 else "0" + str(i)
            url = "http://d1.weather.com.cn/calendar_new/" + year + "/101060201_" + year + month + ".html"
            self.get_data(url)
    def get_data(self,url):
        respone = self.request(url).content
        json_str = respone.decode(encoding='utf-8')[11:]
        weathers = json.loads(json_str)
        for weather in weathers:
            #构建插入Mongo数据库的字典data
            data = {
            '日期': weather.get('date'),
            '星期': weather.get('wk'),
            '最高温度':weather.get('hmax'),
            '最低温度':weather.get('hmin'),
            '降水概率':weather.get('hgl')
            }
            self.jilin_weather.insert_one(data)
if __name__ == '__main__':
    jl_weather = WeatherSpider()
    jl_weather.create_url()

实现效果图:


存入Mongo数据库.png

(8)程序代码3(存储到CSV文件)

import requests
import json
import csv
class WeatherSpider(object):
    #csv文件表头
    with open('jilin_weather.csv', 'w') as f:
        f_csv = csv.writer(f)
        f_csv.writerow(['日期', '星期', '最高温', '最低温', '降水概率'])
    def __inti__(self):
        pass
    def request(self,url):
        #请求头(不带Referer将返回403,用Postman测试)
        headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
        'Referer': 'http://www.weather.com.cn/weather40d/101060201.shtml'
        }
        return requests.get(url,headers=headers)
    def create_url(self):
        year = '2016'
        for i in range(1,13):
            month = str(i) if i > 9 else "0" + str(i) #给一位数前加0
            url = "http://d1.weather.com.cn/calendar_new/" + year + "/101060201_" + year + month + ".html"
            self.get_data(url)
    def get_data(self,url):
        respone = self.request(url).content
        json_str = respone.decode(encoding='utf-8')[11:]
        weathers = json.loads(json_str)
        for weather in weathers:
            #构建插入csv文件的列表data
            data = [weather.get('date'),weather.get('wk'),weather.get('hmax'),weather.get('hmin'),weather.get('hgl')]
            with open('jilin_weather.csv', 'a') as f:   #以a(append)的方式追加写入
                f_csv = csv.writer(f)
                f_csv.writerow(data)
if __name__ == '__main__':
    jl_weather = WeatherSpider()

实现效果图:


保存到CSV文件.png

这三种数据的存储方式,代码分别引用了Python的pymysql库、pymongo库和csv库
1.使用MySQL数据库需要提前建立数据表,并设定好对应存储数据的字段,字段的类型(int、varchat、date......)以及字段的长度。
2.Mongo数据库我也是刚刚使用,但是对这个非关系型数据库比较有好感,因为使用它不必向MySQL数据库那样,要建立数据表和设定字段,给我的感觉就是直接将Python字典型数据直接“怼”进去既可以,比较方便。
3.将数据保存到csv文件的方式比较简单,比较适合没有搭建数据库环境和没有数据库基础的使用者,这种类似Excel表格的文件格式,在获取数据后可以转换为Excel文件,利用VBA和Excel函数进行数据的处理。

以上仅是个人近阶段学习的总结,可能存在着许多片面和理解不到位的地方,还请大家不吝赐教,批评指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容