我用Python实现了一个小说网站雏形

发布日期:2019-07-02

前言

前段时间做了一个爬取妹子套图的小功能,小伙伴们似乎很有兴趣,为了还特意组建了一个Python兴趣学习小组,来一起学习。十个python九个爬,在大家的印象中好像Python只能做爬虫。然而并非如此,Python 也可以做Web开发,接下来给大家展示一下如何做一个小说站点。

相关软件

软件版本功能地址
Python3.7.1脚本语言https://www.python.org/
Django2.1.3Web框架https://www.djangoproject.com/
PyCharm2018.2.4可视化开发工具http://www.jetbrains.com/pycharm/

环境搭建说明:

http://www.runoob.com/python3/python3-install.html

爬取数据

做一个小说网站,内容是必须的,首先我们爬取一本小说《星辰变》到数据库。

创建一个简单的数据库表:

CREATE TABLE `novel` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT "自增主键", `title` varchar(100) NOT NULL COMMENT "标题", `content` text NOT NULL COMMENT "内容", PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

安装数据库驱动以及连接池:

# 数据库驱动pip install pymysql# 数据库连接池pip install DBUtils

代码实现:

# -*- coding: UTF-8 -*-# 导入requests库import requests# 导入文件操作库import codecsfrom bs4 import BeautifulSoupimport sysimport mysql_DBUtilsfrom mysql_DBUtils import MyPymysqlPoolimport importlibimportlib.reload(sys)# 给请求指定一个请求头来模拟chrome浏览器headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}server = "http://www.biquge.cm"# 星辰变地址book = "http://www.biquge.cm/2/2042/"# 定义DBmysql = MyPymysqlPool("dbMysql")# 获取章节内容def get_contents(chapter): req = requests.get(url=chapter) html = req.content html_doc = str(html, "gbk") bf = BeautifulSoup(html_doc, "html.parser") texts = bf.find_all("div", id="content") # 获取div标签id属性content的内容 xa0 是不间断空白符   content = texts[0].text.replace("xa0" * 4, "") return content# 写入数据库def write_db(chapter, content): sql = "INSERT INTO novel (title, content) VALUES(%(title)s, %(content)s);" param = {"title": chapter, "content": content} mysql.insert(sql, param)# 主方法def main(): res = requests.get(book, headers=headers) html = res.content html_doc = str(html, "gbk") # 使用自带的html.parser解析 soup = BeautifulSoup(html_doc, "html.parser") # 获取所有的章节 a = soup.find("div", id="list").find_all("a") print("总章节数: %d " % len(a)) for each in a: try: chapter = server + each.get("href") content = get_contents(chapter) chapter = each.string write_db(chapter, content) except Exception as e: print(e) mysql.dispose()if __name__ == "__main__": main()

更多代码详见:

https://gitee.com/52itstyle/Python/tree/master/Day04

Web实现

Django 是一个开放源代码的Web应用框架,由 Python 写成。采用了 MVC 的框架模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。

Django 框架的核心组件有:

用于创建模型的对象关系映射为最终用户设计的完美管理界面一流的 URL 设计设计者友好的模板语言缓存系统

创建项目

pip install Django# 创建一个项目python django-admin.py startproject itstyle# 切换目录cd itstyle# 创建Apppython manage.py startapp novel

一般一个项目有多个app, 当然通用的app也可以在多个项目中使用,然后启动服务:

# 默认端口是8000python manage.py runserver

如果提示端口被占用,可以用其它端口:

python manage.py runserver 8001

项目结构

最终代码,如下:

│ manage.py│ ├─novel│ │ settings.py # 基础配置│ │ urls.py # URL映射│ │ wsgi.py│ │ __init__.py│ │ │ ├─templates # 相关页面│ novel.html # 章节│ novel_list.html # 小说首页├─utils│ │ dbMysqlConfig.cnf # 数据库配置参数│ │ encoder.py # 编码类│ │ mysql_DBUtils.py # 数据库连接池└─view │ index.py # 后台业务

要点备注

RESTful 风格

控制器 urls.py

from django.conf.urls import urlfrom django.urls import pathfrom view import indexurlpatterns = [ # 《星辰变》首页List path("", index.main), # new # 章节页面 正则匹配 path("chapter/<int:novel_id>/", index.chapter), # new]

代码实现:

from django.http import HttpResponsefrom django.shortcuts import renderfrom utils.mysql_DBUtils import mysql# 《星辰变》章节列表def main(request): sql = "SELECT id,title FROM novel LIMIT 10;" result = mysql.getAll(sql) # result = json.dumps(result, cls=MyEncoder, ensure_ascii=False, indent=4) # result = json.loads(result) context = {"novel_list": result} return render(request, "novel_list.html", context)# def chapter(request):# id = request.GET["id"]# sql = "SELECT content FROM novel where id = %(id)s;"# param = {"id": id}# result = mysql.getOne(sql, param)# context = {"novel": result}# return render(request, "novel.html", context)"""单个章节此处 novel_id 对应 urls.py 中的 <int:novel_id>你可以访问:http://localhost:8000/chapter/1/"""def chapter(request, novel_id): sql = "SELECT title,content FROM novel where id = %(id)s;" param = {"id": novel_id} result = mysql.getOne(sql, param) context = {"novel": result} return render(request, "novel.html", context)

列表展示

基于后端返回的数据,在前台进行展示,这里你可以把它想象成Java中的Struts2标签或者JSTL标签,当然也有点Vue的意思:

{% for novel in novel_list %} <a href="/chapter/{{novel.id}} "><li>{{ novel.title }}</li></a>{% endfor %}

小结

至此,一个简单的Web项目雏形已经完成,当然还有很多需要优化的地方,小伙伴们可以关注从零学 Python,持续更新。

源码:https://gitee.com/52itstyle/Python/tree/master/Day06/novel