Featured image of post Python Web开发学习(三):使用输入框和API

Python Web开发学习(三):使用输入框和API

使用输入框获取用户输入,使用API获取网络上的信息

简介

这是本系列文章的第三篇,主要介绍如何使用输入框获取用户输入,以及如何使用API获取网络上的信息。

前置条件

获取用户输入

添加输入框

首先,我们可以在HTML页面中使用<input>标签来创建输入框。例如,我们可以在templates/index.html中添加一个表单,让用户输入一个城市:

1
2
3
4
5
6
7
8
9
<section class="top-banner">
    <div class="container">
        <h1 class="heading">Weather App</h1>
        <form method="post">
            <input type="text" name="city" placeholder="Enter a city" autocomplete="off" required>
            <button type="submit">Search</button>
        </form>
    </div>
</section>

其中输入框的样式来自style.css文件。这个样式文件来自于https://webdesign.tutsplus.com/build-a-simple-weather-app-with-vanilla-javascript–cms-33893t,其中输入框的效果如下所示:

输入框

获取用户输入

当用户在输入框中输入城市名称并点击“Search”按钮或敲击回车时,用户的输入会传递到<input>标签中name定义的名称中。我们可以在app.py中添加一个POST请求的路由,用来处理用户的输入。由于我们之前已经为/路径添加了路由,这里只需要为/路径添加一个POST的请求:

1
2
3
4
5
6
7
@app.route('/', methods=['POST', 'GET'])
def index():
    if request.method == 'POST':
        city_name = request.form.get('city')
    else:
        #for default name 
        city_name = 'Beijing'

这里我们使用request.form.get('city')来获取用户输入的城市名称,将其赋值给变量city_name

使用API获取天气信息

OpenWeather API

OpenWeather是一个提供天气信息的网站,用户在注册账户后,可以使用OpenWeather提供的API来获取天气信息。我们可以在https://openweathermap.org/注册一个账户,然后在https://home.openweathermap.org/api_keys页面获取API Key。这里我们使用的是免费版的API Key,每分钟最多可以发送60个请求,每天最多可以发送1000个请求。免费版对我来说已经够用了。

通过API获取天气信息

在通过输入框获取了city_name之后,我们就可以使用OpenWeather提供的API来获取天气信息了。我们可以在https://openweathermap.org/current页面查看API的使用方法。这里我们使用的是By city name的API,即通过城市名称来获取天气信息。我们可以在app.py中添加一个函数,用来获取天气信息:

1
2
3
4
def get_weather(city_name):
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid={}'.format(city_name, API_KEY)
    response = urlopen(url).read()
    return json.loads(response)

注意

  • 这里的API_KEY是我们在OpenWeather网站上获取的API Key,需要将其赋值给变量API_KEY

  • 在之前获取的城市名称中,可能包含空格,但是OpenWeather的API不支持空格,OpenWeather API中的空格都是用+替代的。因此我们需要将城市名称中的空格替换为+,并将城市名称转换为小写。例如New York会被转换为new+york。我们可以使用如下的正则表达式来实现这个功能:

    1
    
    re.sub(r"\s+", '+', str(city_name).lower())
    

处理获取的天气信息

上一步中,我们通过OpenWeather的API获取了天气信息,但是这些信息是以JSON格式返回的。在Python中,我们可以以字典的形式来取用JSON中的数据,并将其存储到数据库中。至于JSON中的天气信息内容,可以在https://openweathermap.org/current#current_JSON

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
data = get_weather(city_name)

db.session.add(Weather(
    name = data['name'],
    country = data['sys']['country'],
    temp = round(data['main']['temp']),
    feels_like = round(data['main']['feels_like']),
    icon = data['weather'][0]['icon'],
    description = data['weather'][0]['description'],
))
db.session.commit()

其他部分跟之前的代码一样,从数据库获取想要展示的天气信息,然后传递给模板就行了。效果如下: 天气信息

展示最新的天气信息

最后我们再加入一点儿稍微复杂的数据库操作,例如展示最新的天气信息。我们可以在app.py中添加一段代码,在数据库中选择最新的4条天气信息,然后在页面中展示出来:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
subquery = (
    db.session.query(
        Weather.name,
        func.max(Weather.time).label('max_time')
    )
    .group_by(Weather.name)
    .order_by(func.max(Weather.time).desc())
    .limit(4)
    .subquery()
)

query = (
    db.session.query(Weather)
    .join(subquery, and_(
        Weather.name == subquery.c.name,
        Weather.time == subquery.c.max_time
    ))
    .order_by(Weather.time.desc())
)

wd = query.all()

注意,这里我们用了SQLAlchemy的子查询,因此需要导入from sqlalchemy.sql import func, and_。最后,我们在运行整个应用程序时,先创建数据库,如果数据库已存在,则不会创建:

1
2
3
4
5
6
7
if __name__ == '__main__':
    with app.app_context():
        try:
            db.create_all()
        except ProgrammingError:
            pass
        app.run()

这里同样需要导入相关的模块from sqlalchemy.exc import ProgrammingError

Licensed under CC BY-NC-SA 4.0
最后更新于 Nov 21, 2023 00:00 UTC
comments powered by Disqus