在我阅读《红楼梦》的时候,遇到的一个重大的阅读障碍就是要去认识《红楼梦》中大量的人物,而《红楼梦》中大概出现过多少人物呢?大概出现了有400多位,当然,这四百多位不必全部认识,一百多位认识了也不错,但是这一百多位的人名对我一个亲戚盲来说记住就很不容易。而且不只是人名,人物之间的关系也要有了解。看完《红楼梦》我就有了一个想法,不如做个查询《红楼梦》中人物关系的查询的APP或者是网站。最终做出来的效果
人物关系查询
这个想法已经产生了一段时间了,终于在周末闲的蛋疼,花一天时间给实现了。其实也是因为很多条件已经具备了,比如Django框架已经可以较为熟练的运用了,还有有属于自己的服务器了,还有就是docker的部署也会用了。条件都具备了,剩下的事情就顺其自然了。
第一步要做的就是找出《红楼梦》中出现的人物。
这个参考的是维基百科上的内容,本来我开始打算把这些人物一一复制到我的Django中自带的sqlite数据库中,但是复制了几个,就发现很麻烦。后来打开开发者工具查看网页,发现内容基本上在td标签中,想到之前做的一个爬虫项目,结构有些类似,应该把代码拿过来改改就能用。于是,
import urllib2
import BeautifulSoup
import re
User_Agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0'
header = {}
header['User-Agent'] = User_Agent
url = 'https://zh.wikipedia.org/wiki/%E7%BA%A2%E6%A5%BC%E6%A2%A6%E4%BA%BA%E7%89%A9%E5%88%97%E8%A1%A8'
req = urllib2.Request(url,headers=header)
res = urllib2.urlopen(req).read()
soup = BeautifulSoup.BeautifulSoup(res)
ips = soup.findAll('tr')
# f = open("test.txt","w")
f = open("red.txt","w")
for x in range(1,len(ips)):
ip = ips[x]
tds = ip.findAll("td")
# ip_temp = tds[1].contents[0]+"\t"+tds[2].contents[0]+"\n"
#
if tds!=[]:
try:
b = str(tds[0])
match = re.search('">(.*?)</a>', b)
c=str(match.group(1))
d=str(tds[1])
#去除html标签
p = re.compile('<[^>]+>')
e= p.sub("", d)
total=c+"\t"+e+"\n"
f.write(total)
except:
a = str(tds[0])
match = re.search('>(.*?)</td>', a)
c = str(match.group(1))
d = str(tds[1])
p = re.compile('<[^>]+>')
e = p.sub("", d)
total=c + "\t" + e+"\n"
f.write(total)
else:
pass
之所以与之前写的那个爬取ip的那篇文章的代码有些区别是因为,维基百科中的td标签所包裹的内容并不是那么“干净”,其中有些是超链接,所以这就又涉及到了另一个知识点Python通过正则表达式获取,去除(过滤)或者替换HTML标签的几种方法
关于用ECharts
ECharts是一个开源的js包,用于更加便捷的生成各种图表,我直接用的是这种图表
这个表的用法比较简单,直接按照它的例子准备数据就好了,文章在此与例子中不同的地方在此,我的init_data和link_data是由Django传入的,格式和例子中的差不多。
data:init_data,
links:link_data,
也就是在js中加入
var init_data={{init_data | safe}};
var link_data={{link_data | safe}};
关于sqlite数据库的使用
之前没在django中使用数据库,但是听说django使用数据库的操作的便捷性已经成为一个有区别于其他框架的一个优点了。用起来也是很简单。
新建一个表,比如说我如下代码,就是在新建的app中的Model文件中,新建了一个包含name,symbolSize,des,color的名为mdata的表。Django创建sqlite数据表的基础使用
class mdata(models.Model):
name = models.CharField(max_length=30)
symbolSize = models.IntegerField()
des = models.CharField(max_length=255)
color = models.CharField(max_length=30)
然后还需要用命令
先 cd 进入 manage.py 所在的那个文件夹下,输入下面的命令
# Django 1.6.x 及以下
python manage.py syncdb
# Django 1.7 及以上的版本需要用以下命令
python manage.py makemigrations
python manage.py migrate
这时候就已经生成表了,为了更好的可视化的查看到,我用了navicate这个工具,这个工具可以查看大部分数据库。SQLite 的简单使用(以Navicat为例)
有了数据,如何从代码中读取数据库的值,sqlite为django提供了一套api来方便django来对其进行操作,具体的api可以查看这篇文字python django 数据库查询方法总结
譬如我的示例代码
from relation.models import mdata,mlinks
all_data=mdata.objects.all().values()
for i in range(340):
single_data=all_data[i]
first_data = {"name": single_data['name'], "des": single_data['des'], "symbolSize": single_data['symbolSize'],
"itemStyle": {"normal": {"color": single_data['color']}}}
init_data.append(first_data)
关于部署到海外服务器
要在服务器上下载docker,然后就是把本地的代码放到远程的服务器上,我的笔记本是通过ssh与远程服务器进行连接的,所以这就需要用到一个命令scp。用法参考这篇文章Linux下利用ssh远程文件传输 传输命令 scp
部署用了dockerfile和docker-compose
Dockerfile中的是这样写的:
FROM django:latest
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD . /code/
docker-compose中是这样写的:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
最终的访问地址是http://45.77.203.232:8000/,还没买域名,等打折在买。
用法:
在输入框中输入人名,如“贾宝玉”,然后点击“go”,“贾宝玉”的那个节点就会由绿色变为红色。搜索谁,点击“go”对应的人物就会变红,所以更容易在绿色的海洋中发现那个节点,如果搜索多个人物,就会更容易顺着线来缕清人物的关系。搜索输入框的左侧还有个“C!”按钮,它的作用是还原,把颜色全部变为初始状态的绿色。
参考文章
Python通过正则表达式获取,去除(过滤)或者替换HTML标签的几种方法
EChart例子用法
Django创建sqlite数据表的基础使用
SQLite 的简单使用(以Navicat为例)
Django创建sqlite数据表的基础使用
Linux下利用ssh远程文件传输 传输命令 scp
网友评论