使用Python查询任意地区历史天气并生成气温走势折线图

查看 97|回复 11
作者:zz443470785   
说明

有时候我们想查询一个地方的历史气温用来预测今年的气温,自己去互联网查询又太麻烦,闲来无事写了个查询代码
  • 本代码为本人原创,转载请注明出处。
  • 仅限论坛学习交流使用,请勿滥用,谢谢!
  • 代码并未做全面测试,有问题请在评论区留言。


    源代码如下
    第一步,运行一次下面的代码,用于获取地区对应的代码,会自动保存为 “city_data.csv” 文件,用于第二步的文件调用
    import os
    import csv
    import requests
    from lxml import etree
    # 目标主网址
    main_url = "https://lishi.tianqi.com/"
    # 设置请求头
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0',
    }
    if not os.path.exists('city_data.csv'):
        # 获取不同城市对应的网址
        try:
            response = requests.get(url=main_url, headers=headers)
            html = etree.HTML(response.text)
            city_name_list = html.xpath("//td/ul/li/a/text()")
            city_url_list = html.xpath("//td/ul/li/a/@href")
            with open('city_data.csv', mode='w', encoding='utf-8-sig', newline='') as f:
                writer = csv.writer(f)
                writer.writerow(['城市', '代码'])
                for n, u in zip(city_name_list, city_url_list):
                    writer.writerow([n, u.split('/')[0]])
                    print(n, u.split('/')[0])
        except Exception as e:
            print(e)
    else:
        print('城市数据已存在')
    第二步:输入地区名和日期,开始查询
    代码运行结束之后,会在同目录下生成一个html文件,在浏览器打开即可看见折线图
    import requests
    import csv
    import re
    import os
    from lxml import etree
    import pyecharts.options as opts
    from pyecharts.charts import Line
    # 设置请求头
    headers= {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0',
    }
    def input_data():
        """输入地点,时间"""
        city = input("请输入查询城市:")
        month = input("请输入查询月份(格式:202307):")
        return city, month
    def get_date_url(city, month):
        """获取当月日期地址"""
        if os.path.exists('city_data.csv'):
            with open('city_data.csv', mode='r', encoding='utf-8') as f:
                reader = csv.reader(f)
                for row in reader:
                    if city == row[0]:
                        city_id = row[1]
        month_url = f"https://lishi.tianqi.com/{city_id}/{month}.html"
        return month_url
    def extract_numbers(string):
        """提取字符串中的数字"""
        numbers = re.findall(r'-?\d+', string)[0]
        return float(numbers)
    def spider_weather(date_url, city, month):
        try:
            response = requests.get(url=date_url, headers=headers)
            html = etree.HTML(response.text)
            tree = html.xpath('/html/body/div[7]/div[1]/div[4]/ul/li')
            date_name_list = []
            high_temperatures = []
            low_temperatures = []
            weathers = []
            for i in tree:
                date = i.xpath('./div[1]/text()')[0].split(' ')[0]
                high_temperature = extract_numbers(i.xpath('./div[2]/text()')[0])
                low_temperature = extract_numbers(i.xpath('./div[3]/text()')[0])
                weather = i.xpath('./div[4]/text()')[0]
                wind = i.xpath('./div[5]/text()')[0]
                print(date, high_temperature, low_temperature, weather, wind)
                date_name_list.append(date)
                high_temperatures.append(high_temperature)
                low_temperatures.append(low_temperature)
                weathers.append(weather)
            line = (
                Line(init_opts=opts.InitOpts(width="1200px", height="600px",page_title='月份气温折线图'))
                .add_xaxis(xaxis_data=date_name_list)
                .add_yaxis(
                    series_name="最高气温",
                    y_axis=high_temperatures,
                    markpoint_opts=opts.MarkPointOpts(
                        data=[
                            opts.MarkPointItem(type_="max", name="最大值"),
                        ]
                    ),
                    markline_opts=opts.MarkLineOpts(
                        data=[opts.MarkLineItem(type_="average", name="平均值")]
                    ),
                )
                .add_yaxis(
                    series_name="最低气温",
                    y_axis=low_temperatures,
                    markpoint_opts=opts.MarkPointOpts(
                        data=[opts.MarkPointItem(type_="min", name="最小值")]
                    ),
                    markline_opts=opts.MarkLineOpts(
                        data=[
                            opts.MarkLineItem(type_="average", name="平均值"),
                        ]
                    ),
                )
                .set_global_opts(
                    # 设置主副标题
                    title_opts=opts.TitleOpts(title=f"{city}地区{month[0:4]}年{month[4:]}月气温走势折线图", subtitle=f"{city}"),
                    tooltip_opts=opts.TooltipOpts(trigger="axis"),
                    toolbox_opts=opts.ToolboxOpts(is_show=True, feature=opts.ToolBoxFeatureOpts(save_as_image=opts.ToolBoxFeatureSaveAsImageOpts(pixel_ratio=3, type_='jpg', background_color='#fff'))),
                    xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False, name='日期', min_=0, max_=len(date_name_list), axisline_opts=opts.AxisLineOpts(symbol=['none', 'arrow'])),
                    datazoom_opts=opts.AxisLineOpts(),
                )
            )
            line.render(f"{city}地区{month[0:4]}年{month[4:]}月气温走势折线图.html")
        except Exception as e:
            print(e)
    def main():
        city, month = input_data()
        month_url = get_date_url(city, month)
        spider_weather(month_url, city, month)
    if __name__ == '__main__':
        main()
    效果图如下


    Quicker_20240817_182313.png (386.46 KB, 下载次数: 0)
    下载附件
    输入查询地区和日期
    2024-8-17 18:24 上传



    北京地区2023年09月气温走势折线图.jpg (251.13 KB, 下载次数: 0)
    下载附件
    生成的气温折线图
    2024-8-17 18:24 上传

    气温, 代码

  • zz443470785
    OP
      

    考虑到一些朋友没有python运行环境,所以我将代码用 pyinstaller 打包成了一个exe文件,由于打包pyecharts库比较麻烦,所以将其更换为了matplotlib。
    软件下载地址:https://www.123pan.com/s/SFzojv-ma79A?提取码:52pj
    1634091415   

    温度为零下温度时,统计图不正确
    ice2flash   

    厉害,给你点赞
    sp0770   

    这个不错啊,楼主,有没有成品,不会用代码,工作中需要用到
    jwzb   

    楼主,有没有打包的文件
    firethunder   

    谢谢楼主分享!!!
    SepSerendipity   

    谢谢大佬分享!
    zz443470785
    OP
      


    SepSerendipity 发表于 2024-8-17 19:31
    谢谢大佬分享!

    互相学习
    zz443470785
    OP
      


    sp0770 发表于 2024-8-17 19:07
    这个不错啊,楼主,有没有成品,不会用代码,工作中需要用到

    那我打包一个,稍等
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部