网页爬取中山近15天天气高低温度,将数据处理结果保存进入mysql,然后用pyecharts处理结果可视化,最后用flask联通前后端,额外添加首页界面(bootstrap),登录界面
时间: 2023-10-01 14:07:30 浏览: 119
这是一个比较复杂的项目,需要分步骤来完成。下面是大致的流程:
1. 网页爬取中山近15天天气高低温度
使用 Python 的 requests 库和 BeautifulSoup 库来爬取中山天气的网页信息。可以使用以下代码:
```python
import requests
from bs4 import BeautifulSoup
url = "http://www.weather.com.cn/weather15d/101281701.shtml"
html = requests.get(url).text
soup = BeautifulSoup(html, 'html.parser')
```
然后,需要通过分析网页的 HTML 结构,找到包含天气信息的标签,并提取出需要的信息。例如,以下代码可以得到中山近15天的天气信息:
```python
weather_list = soup.find('div', {'id': '15d'}).find_all('li')
for weather in weather_list:
date = weather.find('h1').text
high_temp = weather.find('span', {'class': 'tem-H'}).text
low_temp = weather.find('span', {'class': 'tem-L'}).text
print(date, high_temp, low_temp)
```
2. 将数据处理结果保存进入 MySQL
使用 Python 的 pymysql 库链接 MySQL 数据库,并将天气信息保存到数据库中。可以使用以下代码:
```python
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='password', database='weather_db')
cursor = conn.cursor()
create_table_sql = '''CREATE TABLE IF NOT EXISTS weather (
date VARCHAR(20) NOT NULL,
high_temp VARCHAR(10) NOT NULL,
low_temp VARCHAR(10) NOT NULL,
PRIMARY KEY (date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci'''
cursor.execute(create_table_sql)
for weather in weather_list:
date = weather.find('h1').text
high_temp = weather.find('span', {'class': 'tem-H'}).text
low_temp = weather.find('span', {'class': 'tem-L'}).text
insert_sql = "INSERT INTO weather (date, high_temp, low_temp) VALUES (%s, %s, %s)"
cursor.execute(insert_sql, (date, high_temp, low_temp))
conn.commit()
cursor.close()
conn.close()
```
3. 用 pyecharts 处理结果可视化
使用 Python 的 pyecharts 库来制作天气信息的可视化图表。例如,可以使用以下代码来制作折线图:
```python
from pyecharts.charts import Line
from pyecharts import options as opts
conn = pymysql.connect(host='localhost', user='root', password='password', database='weather_db')
cursor = conn.cursor()
select_sql = "SELECT date, high_temp, low_temp FROM weather"
cursor.execute(select_sql)
dates = []
high_temps = []
low_temps = []
for row in cursor.fetchall():
dates.append(row[0])
high_temps.append(int(row[1].replace('℃', '')))
low_temps.append(int(row[2].replace('℃', '')))
line_chart = Line()
line_chart.add_xaxis(dates)
line_chart.add_yaxis("最高温度", high_temps, markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]))
line_chart.add_yaxis("最低温度", low_temps, markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="min")]))
line_chart.set_global_opts(title_opts=opts.TitleOpts(title="中山近15天天气"), xaxis_opts=opts.AxisOpts(name="日期"), yaxis_opts=opts.AxisOpts(name="温度(℃)"))
line_chart.render("weather.html")
```
4. 用 Flask 联通前后端
使用 Python 的 Flask 框架来实现前后端的联通。可以使用以下代码:
```python
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/weather")
def weather():
return render_template("weather.html")
if __name__ == "__main__":
app.run(debug=True)
```
其中,`render_template` 函数可以渲染 HTML 模板文件。在这个例子中,需要创建两个模板文件:`index.html` 和 `weather.html`。`index.html` 文件是首页界面,可以使用 Bootstrap 来美化界面;`weather.html` 文件则是展示天气信息的可视化图表。
5. 额外添加登录界面
添加登录界面可以增加项目的安全性。可以使用 Python 的 Flask 框架来实现登录功能。这里只给出一个简单的例子:
```python
from flask import Flask, render_template, request, session, redirect, url_for
app = Flask(__name__)
app.secret_key = "super_secret_key"
@app.route("/")
def index():
if "username" in session:
return render_template("index.html")
else:
return redirect(url_for("login"))
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
if username == "admin" and password == "admin":
session["username"] = username
return redirect(url_for("index"))
else:
return render_template("login.html", message="用户名或密码错误")
else:
return render_template("login.html")
@app.route("/logout")
def logout():
session.pop("username", None)
return redirect(url_for("index"))
if __name__ == "__main__":
app.run(debug=True)
```
其中,`session` 变量用于存储登录状态。在登录成功后,将用户名保存到 `session` 中;在访问首页时,检查 `session` 是否存在用户名,如果存在则允许访问,否则跳转到登录界面。在退出登录时,需要将 `session` 中的用户名删除。登录界面可以使用以下代码实现:
```html
{% extends "base.html" %}
{% block content %}
<form method="post" action="{{ url_for('login') }}">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
{% if message %}
<div class="alert alert-danger">{{ message }}</div>
{% endif %}
<button type="submit" class="btn btn-primary">登录</button>
</form>
{% endblock %}
```
其中,`{% if message %}` 语句用于显示错误信息。如果登录失败,将错误信息传递给模板文件。`base.html` 文件是一个基础模板文件,可以在其中添加 Bootstrap 样式,然后在其他模板文件中继承该文件。例如:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">天气预报</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/weather">天气图表</a>
</li>
</ul>
</div>
{% if session.username %}
<div class="navbar-text">
欢迎,{{ session.username }}
<a href="/logout" class="btn btn-sm btn-outline-primary">退出</a>
</div>
{% endif %}
</nav>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>
```
其中,{% block title %}{% endblock %} 和 {% block content %}{% endblock %} 是模板文件的占位符,可以在其他模板文件中继承并填充这些内容。`{% if session.username %}` 语句用于判断用户是否登录,如果已登录则显示欢迎信息和退出按钮。
阅读全文