Python Flask构建新闻网站案例 - SEO优化版本
# -*- coding: utf-8 -*-
# 导入必要的库
import flask # 用于创建Web应用
from flask_sqlalchemy import SQLAlchemy # 用于操作数据库
import datetime # 用于处理日期时间
import os # 用于操作文件系统
from sqlalchemy import or_, and_ # 用于构造复杂的数据库查询
from flask_babelex import Babel # 用于本地化和翻译
# 创建Flask应用程序实例
app = flask.Flask(__name__)
# 实例化Babel对象,用于本地化和翻译应用程序
babel = Babel(app)
# 设定本地环境为中文
app.config['BABEL_DEFAULT_LOCALE'] = 'zh_CN'
# 配置MySQL数据库连接参数
host = '127.0.0.1' # 数据库主机地址
user = 'root' # 数据库用户名
password = 'admit' # 数据库密码
database = 'xingwen' # 数据库名
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://%s:%s@%s:3306/%s' % (user, password, host, database)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 关闭对模型修改的追踪
app.config['SECRET_KEY'] = 'xingwen' # 设置密钥,用于session加密
# 在应用程序中创建SQLAlchemy实例
db = SQLAlchemy(app)
# 定义User模型,用于描述用户表结构
class User(db.Model):
# 定义表名
__tablename__ = 'User'
# 定义字段
id = db.Column(db.Integer, unique=True, primary_key=True, autoincrement=True) # 用户ID,主键,自增
name = db.Column(db.String(32), name='用户名') # 用户名
email = db.Column(db.String(32), name='邮箱') # 邮箱
password = db.Column(db.String(32), name='密码') # 密码
user_datetime = db.Column(db.DateTime, nullable=True, default=datetime.datetime.now) # 注册时间
# 建立User和PingLun实体之间的关系,一个用户可以有多条评论
pinglun = db.relationship('PingLun', backref='User')
def __repr__(self):
return '<{}账号>'.format(self.email)
# 定义XinWen模型,用于描述新闻表结构
class XinWen(db.Model):
__tablename__ = 'XinWen'
id = db.Column(db.Integer, unique=True, primary_key=True, autoincrement=True) # 新闻ID,主键,自增
title = db.Column(db.String(124), name='标题') # 新闻标题
media = db.Column(db.String(124), name='来源') # 新闻来源
url = db.Column(db.String(512), name='链接') # 新闻链接
top_time = db.Column(db.String(124), name='发布时间') # 新闻发布时间
content = db.Column(db.TEXT, name='内容') # 新闻内容
xinwen_datetime = db.Column(db.DateTime(), nullable=True, default=datetime.datetime.now) # 新闻抓取时间
# 建立XinWen和PingLun实体之间的关系,一篇新闻可以有多条评论
pinglun = db.relationship('PingLun', backref='XinWen')
def __repr__(self):
return '<{} 新闻信息>'.format(self.title)
# 定义PingLun模型,用于描述评论表结构
class PingLun(db.Model):
__tablename__ = 'PingLun'
id = db.Column(db.Integer, unique=True, primary_key=True) # 评论ID,主键
content = db.Column(db.TEXT, name='评价内容') # 评论内容
user_id = db.Column(db.Integer, db.ForeignKey('User.id')) # 外键,关联用户表
xinwen_id = db.Column(db.Integer, db.ForeignKey('XinWen.id')) # 外键,关联新闻表
dates = db.Column(db.DateTime(), nullable=True, default=datetime.datetime.now) # 评论时间
def __repr__(self):
return '< {} 评价 {} 新闻信息>'.format(self.user_id, self.xinwen_id)
if __name__ == '__main__':
# db.drop_all()#清空数据
db.create_all() # 创建所有表
db.session.add(User(name='admin', email='admin@qq.com', password='root123456')) # 添加管理员用户
db.session.commit() # 提交更改到数据库
import requests # 用于发送HTTP请求
from bs4 import BeautifulSoup # 用于解析HTML页面
import datetime # 用于处理日期时间
import re # 用于正则表达式匹配
import json # 用于处理JSON数据
import models # 导入数据库模型
import traceback # 用于异常处理
headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,ja;q=0.8,ru;q=0.7',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Cookie': 'UOR=www.baidu.com,tousu.sina.com.cn,; SINAGLOBAL=120.230.99.74_1660876060.256283; Apache=120.230.99.28_1663207019.801481; ULV=1663207021426:4:3:2:120.230.99.28_1663207019.801481:1663207018950; rotatecount=2; Hm_lvt_fcf72dc8287d20a78b3dfd301a50cbf8=1663207027; Hm_lpvt_fcf72dc8287d20a78b3dfd301a50cbf8=1663207027',
'Host': 'top.news.sina.com.cn',
'Pragma': 'no-cache',
'Referer': 'http://news.sina.com.cn/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
}
start_datetime = datetime.datetime.strptime('20230309', '%Y%m%d') # 设置起始时间
for i in range(30):
datetime1 = (start_datetime + datetime.timedelta(days=-i)).strftime('%Y%m%d') # 每次减少一天
print(datetime1)
url = 'http://top.news.sina.com.cn/ws/GetTopDataList.php?top_type=day&top_cat=news_world_suda&top_time={}&top_show_num=20&top_order=DESC&js_var=news_'.format(
datetime1) # 构造新闻列表页URL
h = requests.get(url=url, headers=headers) # 发起请求,获取页面源码
# print(h.text)
info_json = re.findall('var news_ = (.*);', h.text) # 解析出数据
info_json1 = json.loads(info_json[0]) # 转为json
for resu in info_json1['data']: # 循环进入一个个新闻获取内容
try:
headers1 = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9,ja;q=0.8,ru;q=0.7',
'cache-control': 'no-cache',
'pragma': 'no-cache',
'sec-ch-ua': '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36',
}
print(resu)
title = resu['title'] # 获取标题
media = resu['media'] # 获取来源
url1 = resu['url'] # 获取新闻链接
top_time = resu['top_time'] # 获取发布时间
h1 = requests.get(url=url1, headers=headers1) # 进入新闻详情页
code = h1.encoding
text = h1.text.encode(code).decode('utf-8') # 转换编码
soup1 = BeautifulSoup(text, 'html.parser')
content = soup1.select('#article')[0].text # 获取新闻内容
print(content)
try:
if not models.XinWen.query.filter(models.XinWen.url == url1).all(): # 检查数据库是否已经存在该新闻,不存在则进行新增
models.db.session.add(
models.XinWen(
title=title,
media=media,
url=url1,
top_time=top_time,
content=content
)
) # 新增数据
models.db.session.commit() # 提交数据库更改
except:
print(traceback.format_exc()) # 打印异常信息
except:
print(traceback.format_exc()) # 打印异常信息
models.db.session.commit() 这句代码是将对数据库的改动提交到数据库中。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from math import sqrt
import operator
# 定义函数loadData,用于加载数据
def loadData(files):
'''
该函数用于加载用户-新闻数据
:param files: 数据文件,每行格式为 '用户,兴趣度,新闻'
:return: 返回用户-新闻字典,格式为 {'用户': {'新闻': 兴趣度}}
'''
data = {}
for line in files:
user, score, item = line.split(',') # 解析每行数据
data.setdefault(user, {})
data[user][item] = score
return data
# 定义函数similarity,用于计算新闻相似度
def similarity(data):
'''
该函数用于计算新闻相似度矩阵
:param data: 用户-新闻字典
:return: 新闻相似度矩阵
'''
# 2.1 构造新闻:新闻的共现矩阵
N = {} # 喜欢新闻i的总人数
C = {} # 喜欢新闻i也喜欢新闻j的人数
for user, item in data.items():
for i, score in item.items():
N.setdefault(i, 0)
N[i] += 1
C.setdefault(i, {})
for j, scores in item.items():
if j not in i:
C[i].setdefault(j, 0)
C[i][j] += 1
# 2.2 计算新闻与新闻的相似矩阵
W = {}
for i, item in C.items():
W.setdefault(i, {})
for j, item2 in item.items():
W[i].setdefault(j, 0)
W[i][j] = C[i][j] / sqrt(N[i] * N[j])
return W
# 定义函数recommandList,用于推荐新闻
def recommandList(data, W, user, k=3, N=10):
'''
该函数用于推荐新闻
:param data: 用户-新闻字典
:param W: 新闻相似度矩阵
:param user: 用户ID
:param k: 取与新闻i最相似的k个新闻
:param N: 推荐的新闻数量
:return: 推荐的新闻列表
'''
rank = {}
for i, score in data[user].items(): # 获得用户user历史记录,如A用户的历史记录为{'a': '1', 'b': '1', 'd': '1'}
for j, w in sorted(W[i].items(), key=operator.itemgetter(1), reverse=True)[0:k]: # 获得与新闻i相似的k个新闻
if j not in data[user].keys(): # 该相似的新闻不在用户user的记录里
rank.setdefault(j, 0)
rank[j] += float(score) * w
return sorted(rank.items(), key=operator.itemgetter(1), reverse=True)[0:N]
if __name__ == '__main__':
# 用户,兴趣度,新闻
uid_score_bid = ['A,1,a', 'A,1,b', 'A,1,d', 'B,1,b', 'B,1,c', 'B,1,e']
# uid_score_bid = ['5,1,5','2,1,5', '2,1,38', '2,1,40', '2,1,44', '2,1,63', '2,1,107', '2,1,6', '2,1,14', '2,1,27', '2,1,32', '2,1,56', '2,1,77', '2,1,89', '2,1,92', '2,1,94', '2,1,111', '2,1,123', '2,1,124', '4,1,9', '4,1,15', '4,1,20', '4,1,22', '4,1,85', '4,1,95', '4,1,99', '4,1,131', '4,1,5', '4,1,38', '4,1,40', '4,1,44', '4,1,63', '4,1,107', '4,1,13', '4,1,17', '4,1,58', '4,1,8', '4,1,18', '4,1,21', '4,1,26', '4,1,34', '4,1,48', '4,1,51', '4,1,64', '4,1,70', '4,1,79', '4,1,84', '4,1,101', '4,1,106', '4,1,116', '4,1,117', '4,1,119', '4,1,126', '2,1,8', '2,1,18', '2,1,21', '2,1,26', '2,1,34', '2,1,48', '2,1,51', '2,1,64', '2,1,70', '2,1,79', '2,1,84', '2,1,101', '2,1,106', '2,1,116', '2,1,117', '2,1,119', '2,1,126']
# uid_score_bid = ['1,4,257', '1,4,62', '2,4,61', '2,4,64', '2,4,68', '2,4,67']
data = loadData(uid_score_bid) # 获得数据
W = similarity(data) # 计算新闻相似矩阵
a = recommandList(data, W, '5', 5, 10) # 推荐
print(a)
一个基于协同过滤算法的新闻推荐系统的代码部分通常包含以下内容:
- 数据处理: 包括加载数据、清洗数据、预处理数据等步骤。
- 用户建模: 使用某种方法对用户进行建模,例如使用用户的历史行为数据构建用户画像。
- 新闻建模: 使用某种方法对新闻进行建模,例如使用新闻的文本内容提取关键词、主题等信息。
- 相似度计算: 计算用户之间、新闻之间、用户与新闻之间的相似度。
- 推荐算法: 使用协同过滤算法或其他推荐算法,根据用户模型、新闻模型和相似度计算结果,为用户推荐新闻。
- 评估指标: 使用一些指标来评估推荐系统的效果,例如准确率、召回率、F1值等。
具体实现时,可以使用一些Python库来简化开发,例如pandas用于数据处理、scikit-learn用于机器学习模型训练、Flask用于构建Web应用等。
原文地址: https://www.cveoy.top/t/topic/jycE 著作权归作者所有。请勿转载和采集!