本篇文章涉及到的知识点有:Python爬虫,MySQL数据库,html/css/js基础,selenium和phantomjs基础,MVC设计模式,ORM(对象关系映射)框架,django框架(Python的web开发框架),apache服务器,linux(centos 7为例)基本操作。因此适合有以上基础的同学学习。

声明:本博文只是为了纯粹的技术交流,敏感信息本文会有所过滤,大家见谅(由于任何缘故导致长江大学教务处网站出现问题,都与本人无关)。

实现思路:在没有教务处数据接口的前提下(学生的信息安全),那也只有自己写爬虫去模拟登陆教务处,然后爬数据,为了防止教务处网站崩溃,导致爬虫失败,可以进行数据缓存,下次可以直接从自己的数据库中取数据,而我们要做的就是定时更新数据与教务处实现同步。

技术架构:centos 7 + apache2.4 + mariadb5.5 + Python2.7.5 + mod_wsgi 3.4 + django1.11

------------------------------------------------------------------------

一、Python爬虫:

1、先看一下登录入口 

我们这里用FireFox进行抓包分析,我们发现登录是post上去的,并且带有7个参数,发现有验证码,此时有两种解决办法,一种是运用现在很火的技术用DL做图片识别,一种是down下来让用户自己输。第一种成本比较高。。等不忙了可以试一下,记得Python有个库叫Pillow还是PIL可以做图片识别,,暑假用TF试一下。第二种很low就不说了。

2、 还有种高大上的方式,,,可以不用管验证码,这里就不细说了,我们模拟登陆上去:

#coding:utf8
from bs4 import BeautifulSoup
import urllib
import urllib2
import requests
import sys reload(sys)
sys.setdefaultencoding('gbk') loginURL = "教务处登陆地址"
cjcxURL = "http://jwc2.yangtzeu.edu.cn:8080/cjcx.aspx"
html = urllib2.urlopen(loginURL)
soup = BeautifulSoup(html,"lxml")
__VIEWSTATE = soup.find(id="__VIEWSTATE")["value"]
__EVENTVALIDATION = soup.find(id="__EVENTVALIDATION")["value"] data = {
"__VIEWSTATE":__VIEWSTATE,
"__EVENTVALIDATION":__EVENTVALIDATION,
"txtUid":"账号",
"btLogin":"%B5%C7%C2%BC",
"txtPwd":"密码",
"selKind":""
}
header = {
# "Host":"jwc2.yangtzeu.edu.cn:8080",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0;… Gecko/20100101 Firefox/54.0",
"Accept":"text/html,application/xhtml+x…lication/xml;q=0.9,*/*;q=0.8",
"Accept-Language":"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding":"gzip, deflate",
"Content-Type":"application/x-www-form-urlencoded",
# "Content-Length":"644",
"Referer":"http://jwc2.yangtzeu.edu.cn:8080/login.aspx",
# "Cookie":"ASP.NET_SessionId=3zjuqi0cnk5514l241csejgx",
# "Connection":"keep-alive",
# "Upgrade-Insecure-Requests":"1",
} UserSession = requests.session()
Request = UserSession.post(loginURL,data,header)
Response = UserSession.get(cjcxURL,cookies = Request.cookies,headers=header)
soup = BeautifulSoup(Response.content,"lxml")
print soup

接下来我们可以看到:

再来post(此代码接上面):

__VIEWSTATE2 = soup.find(id="__VIEWSTATE")["value"]
__EVENTVALIDATION2 = soup.find(id="__EVENTVALIDATION")["value"] AllcjData = {
"__EVENTTARGET":"btAllcj",
"__EVENTARGUMENT":"",
"__VIEWSTATE":__VIEWSTATE2,
"__EVENTVALIDATION":__EVENTVALIDATION2,
"selYear":"",
"selTerm":"",
# "Button2":"%B1%D8%D0%DE%BF%CE%B3%C9%BC%A8"
}
AllcjHeader = {
# "Host":"jwc2.yangtzeu.edu.cn:8080",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0;… Gecko/20100101 Firefox/54.0",
"Accept":"text/html,application/xhtml+x…lication/xml;q=0.9,*/*;q=0.8",
"Accept-Language":"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding":"gzip, deflate",
"Content-Type":"application/x-www-form-urlencoded",
# "Content-Length":"644",
"Referer":"http://jwc2.yangtzeu.edu.cn:8080/cjcx.aspx",
# "Cookie":,
"Connection":"keep-alive",
"Upgrade-Insecure-Requests":"",
}
Request1 = UserSession.post(cjcxURL,AllcjData,AllcjHeader)
Response1 = UserSession.get(cjcxURL,cookies = Request.cookies,headers=AllcjHeader)
soup = BeautifulSoup(Response1.content,"lxml")
print soup

发现不行。。。这次get的页面还是原来的页面。。。我觉得有两种原因导致这次post失败:一是asp.net的__VIEWSTATE和__EVENTVALIDATION变量导致post失败,二是一个form多个button用了js做判断,导致爬虫失败,对于动态加载的页面,普通爬虫还是不行。。。。

3、再来点高大上的用selenium(web自动化测试工具,可以模拟鼠标点击)+ phantomjs(没有界面的浏览器,比chrome和Firefox都要快)

selenium安装:pip install selenium

phantomjs安装:

(1)地址:http://phantomjs.org/download.html(我下载的是Linux 64位的)

(2)解压缩:tar -jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2 /usr/share/  

(3)安装依赖:yum install fontconfig freetype libfreetype.so.6 libfontconfig.so.1

(4)配置环境变量:export PATH=$PATH:/usr/share/phantomjs-2.1.1-linux-x86_64/bin

(5)shell下输入phantomjs,如果能进入命令行,安装成功。

请忽略我的注释:

#coding:utf8
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import urllib
import urllib2
import sys reload(sys)
sys.setdefaultencoding('utf8') driver = webdriver.PhantomJS();
driver.get("教务处登录地址")
driver.find_element_by_name('txtUid').send_keys('账号')
driver.find_element_by_name('txtPwd').send_keys('密码')
driver.find_element_by_id('btLogin').click()
cookie=driver.get_cookies()
driver.get("http://jwc2.yangtzeu.edu.cn:8080/cjcx.aspx")
#print driver.page_source
#driver.find_element_by_xpath("//input[@name='btAllcj'][@type='button']")
#js = "document.getElementById('btAllcj').onclick=function(){__doPostBack('btAllcj','')}"
#js = "var ob; ob=document.getElementById('btAllcj');ob.focus();ob.click();)"
#driver.execute_script("document.getElementById('btAllcj').click();")
#time.sleep(2) #让操作稍微停一下
#driver.find_element_by_link_text("全部成绩").click() #找到‘登录’按钮并点击
#time.sleep(2)
#js1 = "document.Form1.__EVENTTARGET.value='btAllcj';"
#js2 = "document.Form1.__EVENTARGUMENT.value='';"
#driver.execute_script(js1)
#driver.execute_script(js2)
#driver.find_element_by_name('__EVENTTARGET').send_keys('btAllcj')
#driver.find_element_by_name('__EVENTARGUMENT').send_keys('')
#js = "var input = document.createElement('input');input.setAttribute('type', 'hidden');input.setAttribute('name', '__EVENTTARGET');input.setAttribute('value', '');document.getElementById('Form1').appendChild(input);var input = document.createElement('input');input.setAttribute('type', 'hidden');input.setAttribute('name', '__EVENTARGUMENT');input.setAttribute('value', '');document.getElementById('Form1').appendChild(input);var theForm = document.forms['Form1'];if (!theForm) { theForm = document.Form1;}function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); } }__doPostBack('btAllcj', '')"
#js = "var script = document.createElement('script');script.type = 'text/javascript';script.text='if (!theForm) { theForm = document.Form1;}function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); }}';document.body.appendChild(script);"
#driver.execute_script(js)
driver.find_element_by_name("Button2").click()
html=driver.page_source
soup = BeautifulSoup(html,"lxml")
print soup
tables = soup.findAll("table")
for tab in tables:
  for tr in tab.findAll("tr"):
    print "--------------------"
    for td in tr.findAll("td")[0:3]:
      print td.getText()

现在只能拿到必修课成绩。。。。。因为全部成绩是ASP生成的js触发的。。。而不是直接submit。。。正在寻找解决的办法。下面开始我们数据库的设计。。。

二、Mariadb学生数据库设计,,,这里引用了我们SQL server数据库原理上机的内容。。。

我的建库语句:

create database jwc character set utf8;

use jwc;

create table Student(
Sno char(9) primary key,
Sname varchar(20) unique,
Sdept char(20),
Spwd char(20)
);
create table Course(
Cno char(2) primary key,
Cname varchar(30) unique,
Credit numeric(2,1)
);
create table SC(
Sno char(9) not null,
Cno char(2) not null,
Grade int check(Grade>=0 and Grade<=100),
primary key(Sno,Cno),
foreign key(Sno) references Student(Sno),
foreign key(Cno) references Course(Cno)
);

三、Python web环境的搭建(LAMP):

1、因为这次选的http服务器时apache,所以要安装mod_wsgi(python通用网关接口)来实现apache和Python程序的交互。。。如果用nginx就要安装配置uwsgi。。。类似java的servlet和PHP的php-fpm。

安装:yum install mod_wsgi

配置:vim /etc/httpd/conf/httpd.conf

这个配置花费了我不少心思和时间。。。网上的有很多错误。。。最标准的Python web django开发配置。。。拿走不谢。

#config python web
LoadModule wsgi_module modules/mod_wsgi.so
<VirtualHost *:>
ServerAdmin root@Vito-Yan
ServerName www.yuol.onlne
ServerAlias yuol.online Alias /media/ /var/www/html/jwc/media/
Alias /static/ /var/www/html/jwc/static/
<Directory /var/www/html/jwc/static/>
Require all granted
</Directory> WSGIScriptAlias / /var/www/html/jwc/jwc/wsgi.py
# DocumentRoot "/var/www/html/jwc/jwc"
ErrorLog "logs/www.yuol.online-error_log"
CustomLog "logs/www.yuol.online -access_log" common <Directory "/var/www/html/jwc/jwc">
<Files wsgi.py>
AllowOverride All
Options Indexes FollowSymLinks Includes ExecCGI
Require all granted
</Files>
</Directory>
</VirtualHost>

2、下面来安装django。。。pip install django。。。。搞定。

查看django的版本:python -m django --version

官网地址:https://www.djangoproject.com

新建项目:django-admin.py startproject jwc(我的是在/var/www/html下建的,apache的网站根目录)

3、apcehe的配置:就不贴了,把上面的jwc改成jwc2,然后端口改成9000,然后Listen 9000(为什么用9000呢,第一个项目jwc用的是8080,django自带的服务器用python manage.py runserver可以开启,它的默认端口是8000,所以不用8000,以免冲突,我的jsp项目的tomcat服务器用的是9090端口,以免冲突,最好不用,常见的就9000端口了,其他不敢乱用)。

4、 settings.py的配置:

DEBUG = True 调试开启

ALLOWED_HOSTS = ['192.168.47.128'] 添加主机

5、wsgi.py配置,不要问我为什么。。。我也不知道。。用apache服务器启动django项目这样做就行了。。。如果用django自带的server就不用改了。。。

"""
WSGI config for jwc2 project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
""" #import os #from django.core.wsgi import get_wsgi_application #os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jwc2.settings") #application = get_wsgi_application() import os
from os.path import join,dirname,abspath
PROJECT_DIR = dirname(dirname(abspath(__file__))) import sys
sys.path.insert(0,PROJECT_DIR)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jwc2.settings") from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

然后就大功告成。。。。Python web环境算是搭建完成。。。

四、开启我们的第一个django项目应用。。。

1、新建成绩查询的应用 python manage.py startapp cjcx

2、在settings.py中添加应用

3、在views.py里写下写下第一行代码。。。。

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render # Create your views here. def index(request):
return HttpResponse("Hello,YUOL!")

4、在urls.py下添加url

from django.conf.urls import url
from django.contrib import admin
import cjcx.views as cj urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^cjcx/',cj.index),
]

5、Hello,YUOL!

6、刚刚上面的4还可以换种方法。。。。

在cjcx应用下面新建urls.py

from django.conf.urls import url
from . import views urlpatterns = [
url(r'^$', views.index),
]

修改jwc2下面的urls.py(项目根路径)

from django.conf.urls import url, include
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^cjcx/', include('cjcx.urls')),
]

7、写前端页面。。。。。

在cjcx应用下面新建templates文件夹放我们的html文件(请暂时忽略动态加载的代码,我懒得删了)

<html>

<head>
<title>YUOL成绩查询系统</title>
<style type="text/css">
#border {
margin: 0 auto;
width: 500px;
min-height: 500px;
background-color: #FFFFFF;
border: 1px solid #000000;
} #button {}
</style>
</head> <body style="text-align:center">
<div id="border">
<h1>YUOL成绩查询系统</h1><br/>
<form action="" method="post"> 账号:
<input type="text" id="xuehao" name="Sno" /><br/> 密码:
<input type="password" id="pwd" name="Spwd" /><br/><br/>
<input type="submit" value="查询" id="submit" /><br/>
<div style="text-align:left;padding-left:50px;">
-----------------------------------------------------------<br/>
姓名:{{ student.Sname }}<br/>
学号:{{ student.Sno}}<br/>
班级:{{ student.Sdept }}<br/>
</div>
-----------------------------------------------------------<br/>
<div>
&nbsp;&nbsp; &nbsp;&nbsp;
<br>
<div style="display:inline-block;width:150px;">
科目:<br>
{{ course.Cname }}
</div>
<div style="display:inline-block;width:150px;">
成绩:<br>
{{ sc.Grade }}
</div>
<div style="display:inline-block;width:150px;">
学分:<br>
{{ course.Credit }}
</div> </div>
</form>
</div>
</body> </html>

修改views.py:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render # Create your views here. def index(request):
return render(request, 'jwcjcx.html')

然后就成这样了。。。。。

8、根据jwc数据库设计Models。。。。

django默认支持的是sqllite,,现在换成 mariadb,修改settings.py

DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'jwc2',
'USER':'root',
'PASSWORD':'你的密码',
'HOST':'localhost',
'PORT':'',
}
}

9、去models.py下面建表吧。。。。

# -*- coding: utf-8 -*-
from __future__ import unicode_literals from django.db import models # Create your models here. class Student(models.Model):
Sno=models.CharField(max_length=9,primary_key=True)
Sname=models.CharField(max_length=20,unique=True)
Sdept=models.CharField(max_length=20)
Spwd=models.CharField(max_length=20) class Course(models.Model):
Cno=models.CharField(max_length=2,primary_key=True)
Cname=models.CharField(max_length=30,unique=True)
Credit=models.DecimalField(max_digits=2, decimal_places=1) class SC(models.Model):
Sno=models.CharField(max_length=9)
Cno=models.CharField(max_length=2)
Grade=models.IntegerField() def __unicode__(self):
return self.Sno

这种ORM免去了写sql语句的麻烦,直接把表封装成一个类继承model.Model,查询字段直接‘点’操作。。。很方便。

然后生成数据模型表:python manage.py makemigrations

再将数据表迁移到mariadb数据库:python manage.py migrate

生成cjcx_三个表,其他是django默认的不用管,另外数据库要自己先建(create database jwc2 charset=utf8;)

10、使用django admin做数据管理。。。。Admin真心好用这是django框架最显著的一个优势。。。

创建用户:python manage.py createsuperuser

然后在主机后面加/admin就可以登录。。。我们发现它的css和img丢失了

解决办法:

在jwc2下面建一个静态文件夹:static

修改settings.py。。。在最后一行添加STATIC_ROOT = "/var/www/html/jwc2/static/",LANGUAGE_CODE = 'zh-Hans'(改成中文的admin)

执行命令 :python manage.py collectstatic

上面apache的静态文件配置取消注释。。。

这样进去看不到数据表,需要修改admin.py引入models

# -*- coding: utf-8 -*-
from __future__ import unicode_literals from django.contrib import admin
import models
# Register your models here.
admin.site.register(models.Student)
admin.site.register(models.Course)
admin.site.register(models.SC)

可以直接操作数据库了。。。django的强大之处。。

11、下面开始我们最重要的业务逻辑。。

数据入库(MVC中的M,models):我这里把Course表的Cno给删了,把SC表的Cno换成Cname了。。。和上面有所不同,只需要把库删了重新生成数据表即可。。。

#encoding=utf-8
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import MySQLdb
import time
import urllib
import urllib2
import sys reload(sys)
sys.setdefaultencoding('utf8') conn= MySQLdb.connect(
host='localhost',
port = 3306,
user='root',
passwd='密码',
db ='jwc2',
charset='utf8'
)
cur = conn.cursor() driver = webdriver.PhantomJS();
driver.get("教务处登录入口")
driver.find_element_by_name('txtUid').send_keys('账号')
driver.find_element_by_name('txtPwd').send_keys('密码')
driver.find_element_by_id('btLogin').click()
cookie=driver.get_cookies()
driver.get("http://jwc2.yangtzeu.edu.cn:8080/cjcx.aspx")
driver.find_element_by_name("Button2").click()
html=driver.page_source
#html = open("btAllcj.html","r")
soup = BeautifulSoup(html,"lxml")
Sno = str(soup.find(id="lbXH").getText())
Sname = str(soup.find(id="lbXm").getText())
Sdept = str(soup.find(id="lbBj").getText())
Student = (Sno,Sname,Sdept,'')
sql = "insert into cjcx_student values(%s,%s,%s,%s)"
cur.execute(sql,Student)
id = 0
tables = soup.findAll("table")
for tab in tables[1:2]:
for tr in tab.findAll("tr")[1:]:
count = 0
for td in tr.findAll("td"):
count += 1
if count==1:
Cname = td.getText()
if count==2:
Grade = td.getText()
          id += 1
sql = "insert into cjcx_sc values(%s,%s,%s,%s)"
SC = (id,Sno,Cname,Grade)
cur.execute(sql,SC)
if count==3:
Credit = td.getText()
sql = "insert into cjcx_course values(%s,%s)"
Course = (Cname,Credit)
cur.execute(sql,Course)
conn.commit()
cur.close()
conn.close()

业务逻辑views.py(MVC中的V,views)

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render
from . import models # Create your views here. def index(request):
return render(request, 'jwcjcx.html') def search_action(request):
Sno = request.POST['Sno']
Spwd = request.POST['Spwd']
#这里放爬虫和数据入库的代码。。。。。
student = models.Student.objects.get(Sno=Sno)
pwd = student.Spwd
if Spwd==pwd:
sc = models.SC.objects.filter(Sno=Sno)
# course = models.Course.objects.filter(Cname=sc.Cname)
return render(request,'jwcjcx.html',{'student':student, 'sc':sc})

修改urls.py(MVC中的C,Controller)

jwc2项目urls:

from django.conf.urls import url,include
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^cjcx/',include('cjcx.urls', namespace='cjcx')),
]

cjcx应用urls:

from django.conf.urls import url
from . import views urlpatterns = [
url(r'^$', views.index),
url(r'^search/$',views.search_action,name='search_action'),
]

12、前端数据渲染。。。。

<html>

<head>
<title>YUOL成绩查询系统</title>
<style type="text/css">
#border {
margin: 0 auto;
width: 500px;
min-height: 500px;
background-color: #FFFFFF;
border: 1px solid #000000;
} #button {}
</style>
</head> <body style="text-align:center">
<div id="border">
<h1>YUOL成绩查询系统</h1><br/>
<form action="{% url 'cjcx:search_action' %}" method="post">{% csrf_token %} 账号:
<input type="text" id="xuehao" name="Sno" /><br/> 密码:
<input type="password" id="pwd" name="Spwd" /><br/><br/>
<input type="submit" value="查询" id="submit" /><br/>
<div style="text-align:left;padding-left:50px;">
-----------------------------------------------------------<br/>
姓名:{{ student.Sname }}<br/>
学号:{{ student.Sno}}<br/>
班级:{{ student.Sdept }}<br/>
</div>
-----------------------------------------------------------<br/>
<div>
&nbsp;&nbsp; &nbsp;&nbsp;
<br/>
<div style="display:inline-block;width:200px;">
科目:<br/>
{% for sc in sc %}
{{ sc.Cname }}<br/>
-------------------<br/>
{% endfor %}
</div>
<div style="display:inline-block;width:100px;">
成绩:<br/>
{% for sc in sc %}
{{ sc.Grade }}<br/>
------<br/>
{% endfor %}
</div>
<div style="display:inline-block;width:150px;">
学分:<br/>
{% for course in course %}
{{ course.Credit }}
{% endfor %}
</div> </div>
</form>
</div>
</body> </html>

收工。。。。。。

写了两天两夜,实在卡不住了,后面学分就没写了。。。。。。。。。爬虫还不稳定,逻辑判断几乎没写。。。只是简单实现了功能。。。

最后附上一张照片:

暑假闲着没事第一弹:基于Django的长江大学教务处成绩查询系统的更多相关文章

  1. python 全栈开发,Day95(RESTful API介绍,基于Django实现RESTful API,DRF 序列化)

    昨日内容回顾 1. rest framework serializer(序列化)的简单使用 QuerySet([ obj, obj, obj]) --> JSON格式数据 0. 安装和导入: p ...

  2. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  3. Hadoop基础-MapReduce的工作原理第一弹

    Hadoop基础-MapReduce的工作原理第一弹 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在本篇博客中,我们将深入学习Hadoop中的MapReduce工作机制,这些知识 ...

  4. RMQ_第一弹_Sparse Table

    title: RMQ_第一弹_Sparse Table date: 2018-09-21 21:33:45 tags: acm RMQ ST dp 数据结构 算法 categories: ACM 概述 ...

  5. 基于Django的Disqus如何支持每月80亿PV(转)

    原文:基于Django的Disqus如何支持每月80亿PV 本文由 伯乐在线 - 贱圣OMG 翻译.未经许可,禁止转载!英文出处:Matt Robenolt.欢迎加入翻译小组. 现在我们Disqus能 ...

  6. 第一章、Django概述

    目录 第一章.Django概述 一.了解软件开发架构 二.HTTP协议 三.响应状态码 四.请求方式 五.基于wsgiref模块 六..动静态网页 七.python三大主流web框架 八.安装Djan ...

  7. JVM第一弹

    JVM第一弹 基本概念 JVM是可运行java代码的假想计算机,包括一套字节码指令集,一组寄存器,一个栈,一个垃圾回收.堆和一个存储方法域.JVM是运行在操作系统之上的,它与硬件没有直接的交互. 运行 ...

  8. 六、Django学习之基于下划线的跨表查询

    六.Django学习之基于下划线的跨表查询 一对一 正向查询的例子为 已知用户名,查询用户的电话号码.反向查询例子反之. 正向查询 其中下划线前的表示表名,无下划线的表示的是Author表 resul ...

  9. Spring Boot 第一弹,问候一下世界!!!

    持续原创输出,点击上方蓝字关注我吧 目录 前言 什么是Spring Boot? 如何搭建一个Spring Boot项目? 第一个程序 Hello World 依赖解读 什么是配置文件? 什么是启动类? ...

随机推荐

  1. 点击 Button触发事件将GridView1 CheckBox勾选的行添加到GridView2中

    有时候想实现一个CheckBox选取功能,但是很多细节不是很清楚 相信大家都有遇到类似的情况,直接看代码,如下: 前端代码GridView1,CheckBox控件设置 <asp:GridView ...

  2. centos7安装docker并设置开机自启以及常用命令

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...

  3. CSS3中三角形及三角形组合图实现

        几何之三角形及三角形的组合图案理论 三角形( triangle ['traɪæŋɡl])可以看成正方形对角线交叉形成的图形 若想得到编号①方向向下三角形,只需对编号②③④三角形让其透明tran ...

  4. 数据库【mongodb篇】练习操作

    本文的目标是通过大量的示例,来更好的理解如果在Mongodb中进行数据操作: 初入客户端刚利用 mongod命令进入客户端环境,此时对数据库一无所知: 举目四望,想知道现在有哪些数据库,   show ...

  5. Why Ambari is setting the security protocol of the kafka to PLAINTEXTSASL instead of SASL_PLAINTEXT?

    首页 / Data Ingestion & Streaming / Why Ambari is setting the security protocol of the kafka to PL ...

  6. 通过getResourceAsStream 获得Properties文件属性和属性值

    1.Class.getResourceAsStream(String path) path:不以‘/’开头默认是从此类所在的包下取资源:以'/'开头则是从ClassPath根目录下获取 2.Class ...

  7. vue启动时候报错

    使用vue时,在已经安装模块完毕的情况下,依旧会报错,如: Module build failed: Error: %1 is not a valid Win32 application. 这个时候只 ...

  8. CentOS7.x搭建时间同步服务器

    关于chrony Chrony是一个开源的自由软件,像CentOS7或基于RHEL 7操作系统,已经是默认服务,默认配置文件在 /etc/chrony.conf 它能保持系统时间与时间服务器(NTP) ...

  9. MyIsam与InnoDB存储引擎主要区别

    MyIsam与InnoDB主要有以下4点大的区别,缓存机制,事务支持,锁定实现,数据物理存储方式(包括索引和数据). 1.缓存机制 myisam 仅仅缓存索引,不会缓存实际数据信息,他会将这一工作交给 ...

  10. selenium中隐式等待和显示等待的区别

    Selenium显示等待和隐式等待的区别1.selenium的显示等待原理:显示等待,就是明确的要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,那么久 ...