首页 软件代码

PYTHON初学之API爬取天气预报数据


一直看到python好多人学,终于自己耐不住性子,还是开始学习起来了。
初学python,看到了这个经典的项目,于是就开始进行学习。并进行了相应的改(乱)善(改),将原本项目采用的储存数据库改为mysql,只储存近三天的天气情况,增加定时执行,成功之后邮件提醒等。

import requests
import time
import json
import pymysql
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
from apscheduler.schedulers.blocking import BlockingScheduler 
def mail(nownew,nowup,nowok):
    mailtime=str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))
    ret=True
    my_sender='******@126.com'    # 发件人邮箱账号
    my_pass = '******'              # 发件人邮箱密码
    my_user='halfye@163.com'      # 收件人邮箱账号,我这边发送给自己
    emailtext=("%s,执行结束\n 新增:%s \n现在更新:%s\n 原更新:%s"%(mailtime,str(nownew),str(nowup),str(nowok)))
    try:
        msg=MIMEText(emailtext,'plain','utf-8')
        msg['From']=formataddr(["天气抓取信息",my_sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['To']=formataddr(["半叶子接信人",my_user])              # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['Subject']=("%s天气执行结束"%(mailtime))         # 邮件的主题,也可以说是标题
 
        server=smtplib.SMTP_SSL("smtp.126.com", 465)  # 发件人邮箱中的SMTP服务器,端口是25
        server.login(my_sender, my_pass)  # 括号中对应的是发件人邮箱账号、邮箱密码
        server.sendmail(my_sender,[my_user,],msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()  # 关闭连接
    except Exception:  # 如果 try 中的语句没有执行,则会执行下面的 ret=False
        ret=False
        file2 = open(("%s天气执行结束.txt"%(mailtime)),"w")
        file2.write(emailtext)
        file2.close()
    return ret
 



#链接数据库
def weathers():
    print("执行中")
    nowup=0
    nowok=0
    nownew=0
    tiee=1
    db=pymysql.connect("localhost","py","pythonpy0202","python" )
    cursor = db.cursor()
    #数据库判断是否存在,不存在则创建
    sql = '''CREATE TABLE IF NOT EXISTS `weather`(
            `id` INT,
           `cid` VARCHAR(40) NOT NULL,
           `location` VARCHAR(40) NOT NULL,
           `weatherd1` VARCHAR(40) NOT NULL,
           `weatherd2` VARCHAR(40) NOT NULL,
           `weatherd3` VARCHAR(40) NOT NULL,
           `weathern1` VARCHAR(40) NOT NULL,
           `weathern2` VARCHAR(40) NOT NULL,
           `weathern3` VARCHAR(40) NOT NULL,
           `date` DATE,
           PRIMARY KEY ( `cid` )
        )ENGINE=InnoDB DEFAULT CHARSET=utf8;'''
    #执行sql语句
    cursor.execute(sql)
    db.commit()
    #获取本地时间
    nowtime=time.strftime("%Y-%m-%d", time.localtime())
    #获取城市的cid
    url='https://cdn.heweather.com/china-city-list.txt'
    strhtml=requests.get(url)
    strhtml.encoding = 'utf8' 
    data=strhtml.text
    #以换行符来分割,建立数组
    data1=data.split("\n")
    #删去前五行
    for i in range(6):
        data1.remove(data1[0])
    #初始化id和天气白和天气黑
    id=0
    weatherd=['','','']
    weathern=['','','']
    #进行循环查询
    for it in data1:
        #查询cid是否存在
        sql=("SELECT `cid` FROM `weather` WHERE cid='%s'"%(it[2:13]))
        cursor.execute(sql)
        db.commit()
        exist = cursor.fetchone()
        #如果不存在则执行
        if exist==None:
            nownew+=1
            url='https://free-api.heweather.net/s6/weather?location='+it[2:13]+'&key=cc33b9a52d6e48de852477798980b76e'  
            time.sleep(tiee)
            #获取请求并转为json格式
            strhtml=requests.get(url)
            dic=strhtml.json()
            #判断返回值是否正常,正常则执行
            if dic['HeWeather6'][0]['status']=='ok':
                #获取城市cid和城市名称以及近三天天气情况
                cid=dic['HeWeather6'][0]['basic']['cid']
                location=dic['HeWeather6'][0]['basic']['location']
                i=0
                for it in dic['HeWeather6'][0]['daily_forecast']:
                    weatherd[i]=it['cond_txt_d']
                    weathern[i]=it['cond_txt_n']
                    i+=1
                    if i==3 :
                        break
                # 输出三天天气
                print(id,cid,location,'三白:',weatherd[0],weatherd[1],weatherd[2],'三黑: ',weathern[0],weathern[1],weathern[2])
                strid=str(id)
                sql=("INSERT INTO `weather`(`id`,`cid`, `location`, `weatherd1`, `weatherd2`, `weatherd3`, `weathern1`, `weathern2`, `weathern3`,`date`)VALUES ('%s','%s', '%s', '%s', '%s', '%s','%s', '%s', '%s','%s')"%(strid,cid,location,weatherd[0],weatherd[1],weatherd[2],weathern[0],weathern[1],weathern[2],nowtime))
                cursor.execute(sql)
                db.commit()

            else:
                print("失败,请检查1")
                break
            
        else:
            #查询cid并获取返回的日期
            sql=("SELECT `date` FROM `weather` WHERE cid='%s'"%(it[2:13]))
            cursor.execute(sql)
            db.commit()
            lastday = (cursor.fetchone())[0]
            #如果返回日期和本地时间不同则执行
            if str(lastday)!=nowtime:
                url='https://free-api.heweather.net/s6/weather?location='+it[2:13]+'&key=cc33b9a52d6e48de852477798980b76e'  
                #b70895c4a6e848af86ae320da3cda0e3
                time.sleep(tiee)
                strhtml=requests.get(url)
                dic=strhtml.json()
                if dic['HeWeather6'][0]['status']=='ok':
                    nowup+=1
                    i=0
                    cid=dic['HeWeather6'][0]['basic']['cid']
                    location=dic['HeWeather6'][0]['basic']['location']
                    for it in dic['HeWeather6'][0]['daily_forecast']:
                        weatherd[i]=it['cond_txt_d']
                        weathern[i]=it['cond_txt_n']
                        i+=1
                        if i==3 :
                            break
                    print(id,cid,location,'三白天:',weatherd[0],weatherd[1],weatherd[2],'三黑天: ',weathern[0],weathern[1],weathern[2])
                    sql=("UPDATE `weather` SET `weatherd1`='%s', `weatherd2`='%s', `weatherd3`='%s', `weathern1`='%s', `weathern2`='%s', `weathern3`='%s',`date`='%s' WHERE cid='%s'"%(weatherd[0],weatherd[1],weatherd[2],weathern[0],weathern[1],weathern[2],nowtime,cid))
                    cursor.execute(sql)
                    db.commit()
                else:
                    print("失败,请检查2")
                    break
            else: 
                print(id,"已经最新")
                nowok+=1
        id+=1
    #测试用,方便中断。
        if id==-1:
            break  
    db.close()
    ret=mail(nownew,nowup,nowok)
    if ret:
        print("邮件发送成功")
    else:
        print("邮件发送失败")
        
weathers()
#定时启动,每天早上6点
if __name__ == '__main__':
    scheduler = BlockingScheduler()
    scheduler.add_job(weathers,'cron',day_of_week ='0-6',hour = 6,minute = 00,second = 00)
    print("s1")

    try:
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        pass




文章评论

    TniAsu 访客ChromeWindows
    2020-04-13 18:35   回复

    是大佬啊 |´・ω・) ノ

      半叶子 站长ChromeWindows
      2020-04-13 18:50   回复

      都是书上的代码,自己按照上边自己写的,目前也在努力呀。