Commit f215ddf7 authored by jackfrued's avatar jackfrued

更新了语言基础之后的文档

parent 5da0ed27
## 网络应用开发
### 发送电子邮件
在即时通信软件如此发达的今天,电子邮件仍然是互联网上使用最为广泛的应用之一,公司向应聘者发出录用通知、网站向用户发送一个激活账号的链接、银行向客户推广它们的理财产品等几乎都是通过电子邮件来完成的,而这些任务应该都是由程序自动完成的。
就像我们可以用HTTP(超文本传输协议)来访问一个网站一样,发送邮件要使用SMTP(简单邮件传输协议),SMTP也是一个建立在TCP(传输控制协议)提供的可靠数据传输服务的基础上的应用级协议,它规定了邮件的发送者如何跟发送邮件的服务器进行通信的细节,而Python中的smtplib模块将这些操作简化成了几个简单的函数。
下面的代码演示了如何在Python发送邮件。
```Python
from smtplib import SMTP
from email.header import Header
from email.mime.text import MIMEText
def main():
# 请自行修改下面的邮件发送者和接收者
sender = 'abcdefg@126.com'
receivers = ['uvwxyz@qq.com', 'uvwxyz@126.com']
message = MIMEText('用Python发送邮件的示例代码.', 'plain', 'utf-8')
message['From'] = Header('王大锤', 'utf-8')
message['To'] = Header('骆昊', 'utf-8')
message['Subject'] = Header('示例代码实验邮件', 'utf-8')
smtper = SMTP('smtp.126.com')
# 请自行修改下面的登录口令
smtper.login(sender, 'secretpass')
smtper.sendmail(sender, receivers, message.as_string())
print('邮件发送完成!')
if __name__ == '__main__':
main()
```
如果要发送带有附件的邮件,那么可以按照下面的方式进行操作。
```Python
from smtplib import SMTP
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
import urllib
def main():
# 创建一个带附件的邮件消息对象
message = MIMEMultipart()
# 创建文本内容
text_content = MIMEText('附件中有本月数据请查收', 'plain', 'utf-8')
message['Subject'] = Header('本月数据', 'utf-8')
# 将文本内容添加到邮件消息对象中
message.attach(text_content)
# 读取文件并将文件作为附件添加到邮件消息对象中
with open('/Users/Hao/Desktop/hello.txt', 'rb') as f:
txt = MIMEText(f.read(), 'base64', 'utf-8')
txt['Content-Type'] = 'text/plain'
txt['Content-Disposition'] = 'attachment; filename=hello.txt'
message.attach(txt)
# 读取文件并将文件作为附件添加到邮件消息对象中
with open('/Users/Hao/Desktop/汇总数据.xlsx', 'rb') as f:
xls = MIMEText(f.read(), 'base64', 'utf-8')
xls['Content-Type'] = 'application/vnd.ms-excel'
xls['Content-Disposition'] = 'attachment; filename=month-data.xlsx'
message.attach(xls)
# 创建SMTP对象
smtper = SMTP('smtp.126.com')
# 开启安全连接
# smtper.starttls()
sender = 'abcdefg@126.com'
receivers = ['uvwxyz@qq.com']
# 登录到SMTP服务器
# 请注意此处不是使用密码而是邮件客户端授权码进行登录
# 对此有疑问的读者可以联系自己使用的邮件服务器客服
smtper.login(sender, 'secretpass')
# 发送邮件
smtper.sendmail(sender, receivers, message.as_string())
# 与邮件服务器断开连接
smtper.quit()
print('发送完成!')
if __name__ == '__main__':
main()
```
### 发送短信
发送短信也是项目中常见的功能,网站的注册码、验证码、营销信息基本上都是通过短信来发送给用户的。在下面的代码中我们使用了[互亿无线](http://www.ihuyi.com/)短信平台(该平台为注册用户提供了50条免费短信以及常用开发语言发送短信的demo,可以登录该网站并在用户自服务页面中对短信进行配置)提供的API接口实现了发送短信的服务,当然国内的短信平台很多,读者可以根据自己的需要进行选择(通常会考虑费用预算、短信达到率、使用的难易程度等指标),如果需要在商业项目中使用短信服务建议购买短信平台提供的套餐服务。
```Python
import urllib.parse
import http.client
import json
def main():
host = "106.ihuyi.com"
sms_send_uri = "/webservice/sms.php?method=Submit"
# 下面的参数需要填入自己注册的账号和对应的密码
params = urllib.parse.urlencode({'account': '你自己的账号', 'password' : '你自己的密码', 'content': '您的验证码是:147258。请不要把验证码泄露给其他人。', 'mobile': '接收者的手机号', 'format':'json' })
print(params)
headers = {'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'}
conn = http.client.HTTPConnection(host, port=80, timeout=30)
conn.request('POST', sms_send_uri, params, headers)
response = conn.getresponse()
response_str = response.read()
jsonstr = response_str.decode('utf-8')
print(json.loads(jsonstr))
conn.close()
if __name__ == '__main__':
main()
```
This diff is collapsed.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
font-family: Verdana, '宋体';
}
body {
width: 960px;
margin: 10px auto;
background-image: url(img/dark-wood.jpg);
}
#header, #main, #footer {
background-color: lightgray;
margin: 10px 0;
clear: both;
}
#header h1 {
height: 60px;
line-height: 60px;
text-align: center;
}
#nav {
height: 35px;
text-align: center;
}
#nav ul li {
line-height: 35px;
width: 100px;
margin:0 10px;
display: inline-block;
}
a {
text-decoration: none;
}
a:link, a:visited, a:active {
color: black;
}
#nav ul li:hover {
border-bottom: 4px solid red;
}
.feature {
height: 250px;
text-align: center;
background-color: #ADD8E6;
}
.one, .two, .three {
width: 300px;
height: 150px;
float: left;
}
.one {
margin: 10px 15px 0 0;
background-color: #FFEBCD;
}
.two {
margin: 10px 15px;
background-color: coral;
}
.three {
margin: 10px 0 0 15px;
background-color: darkseagreen;
}
#footer {
text-align: center;
line-height: 45px;
height: 45px;
font-size: 1.2em;
}
</style>
</head>
<body>
<div id="header">
<h1>Logo</h1>
<div id="nav">
<ul>
<li><a href="">Home</a></li>
<li><a href="">Products</a></li>
<li><a href="">Services</a></li>
<li><a href="">About</a></li>
<li><a href="">Contact</a></li>
</ul>
</div>
</div>
<div id="main">
<div class="feature">
<!-- 这一块相当于是页面的最主要的区域 -->
</div>
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
<div id="footer">
&copy; Copyright 2011
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.menu {
margin: 20px 50px;
}
.menu li {
list-style: none;
width: 120px;
height: 35px;
line-height: 35px;
color: white;
text-align: center;
border-bottom: 1px solid lightgray;
}
.menu>li {
background-color: #8FBC8F;
overflow: hidden;
}
.menu>li:hover {
height: auto;
}
.menu li ul li {
background-color: lightsteelblue;
}
</style>
</head>
<body>
<ul class="menu">
<li>
Menu 1
<ul>
<li>Menu 1-1</li>
<li>Menu 1-2</li>
<li>Menu 1-3</li>
</ul>
</li>
<li>
Menu 2
<ul>
<li>Menu 2-1</li>
<li>Menu 2-2</li>
</ul>
</li>
<li>
Menu 3
<ul>
<li>Menu 3-1</li>
<li>Menu 3-2</li>
<li>Menu 3-3</li>
<li>Menu 3-4</li>
<li>Menu 3-5</li>
</ul>
</li>
<li>
Menu 4
<ul>
<li>Menu 4-1</li>
<li>Menu 4-2</li>
</ul>
</li>
<li>
Menu 5
<ul>
<li>Menu 5-1</li>
<li>Menu 5-2</li>
<li>Menu 5-3</li>
<li>Menu 5-4</li>
</ul>
</li>
</ul>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
font-size: 18px;
}
#login label {
display: inline-block;
width: 150px;
text-align: right;
margin-right: 20px;
}
.formitem {
margin: 20px 0;
}
.hint {
display: inline-block;
width: 320px;
font-size: 14px;
margin-left: 10px;
}
.correct {
color: green;
}
.incorrect {
color: red;
}
#login input[type="submit"] {
display: inline-block;
width: 120px;
height: 30px;
background-color: darkred;
color: white;
font-size: 20px;
line-height: 30px;
border: none;
cursor: pointer;
margin-left: 200px;
}
</style>
</head>
<body>
<form id="login" action="" method="post">
<div class="formitem">
<label for="username">用户名: </label>
<input type="text" id="username" name="username">
<span id="uidHint" class="hint"></span>
</div>
<div class="formitem">
<label for="password">密码: </label>
<input type="password" id="password" name="password">
<span id="pwdHint" class="hint"></span>
</div>
<div class="formitem">
<label for="repassword">确认密码: </label>
<input type="password" id="repassword">
<span id="rePwdHint" class="hint"></span>
</div>
<div class="formitem">
<label for="tel">手机号: </label>
<input type="text" id="tel" name="tel">
<span id="telHint" class="hint"></span>
</div>
<div class="formitem">
<label for="code">验证码: </label>
<input type="text" id="code" name="code" size="4">
<input type="button" value="获取验证码">
</div>
<div class="formitem">
<input type="submit" value="立即开通">
</div>
<div class="formitem">
<label for="agreement"></label>
<input type="checkbox" id="agreement">
<span class="hint">我同意<a href="#">《XYZ服务协议》</a></span>
</div>
</form>
<script src="js/mylib.js" ></script>
<script>
(function() {
// 使用正则表达式的字面量语法创建正则表达式对象
var uidRegEx = /^\w{6,20}$/;
var pwdRegEx = /^.{8,20}$/;
var telRegEx = /^1[345789]\d{9}$/;
var uid = $('username');
function checkUsername() {
var uidHint = $('uidHint');
var username = uid.value.trim();
if (uidRegEx.test(username)) {
uidHint.textContent = '√';
uidHint.className = 'hint correct';
return true;
} else {
uidHint.textContent = '用户名由字母数字下划线构成且长度为6-20个字符';
uidHint.className = 'hint incorrect';
return false;
}
}
handleEvent(uid, 'blur', checkUsername);
var pwd = $('password');
function checkPassword() {
var pwdHint = $('pwdHint');
var password = pwd.value;
if (pwdRegEx.test(password)) {
pwdHint.textContent = '√';
pwdHint.className = 'hint correct';
return true;
} else {
pwdHint.textContent = '密码长度为8-20个字符';
pwdHint.className = 'hint incorrect';
return false;
}
}
handleEvent(pwd, 'blur', checkPassword);
var rePwd = $('repassword');
function checkRepassword() {
var rePwdHint = $('rePwdHint');
var password = pwd.value;
var repassword = rePwd.value;
if (repassword.length == 0) {
rePwdHint.textContent = '确认密码不能为空';
rePwdHint.className = 'hint incorrect';
return false;
}
if (repassword == password) {
rePwdHint.textContent = '√';
rePwdHint.className = 'hint correct';
return true;
} else {
rePwdHint.textContent = '密码和确认密码不一致';
rePwdHint.className = 'hint incorrect';
return false;
}
}
handleEvent(rePwd, 'blur', checkRepassword);
var telInput = $('tel');
function checkTel() {
var telHint = $('telHint');
var tel = telInput.value;
if (telRegEx.test(tel)) {
telHint.textContent = '√';
telHint.className = 'hint correct';
return true;
} else {
telHint.textContent = '请输入有效的手机号';
telHint.className = 'hint incorrect';
return false;
}
}
handleEvent(telInput, 'blur', checkTel);
var form = $('login') || document.forms[0];
// 给表单对象绑定表单提交事件
handleEvent(form, 'submit', function(evt) {
evt = evt || window.event;
// 阻止表单提交等到验证通过了之后手动提交表单
evt.preventDefault();
if (!$('agreement').checked) {
alert('请先选中同意《XYZ服务协议》');
return ;
}
// 请注意&&和&之间区别 前者有短路效果后者没有
if (checkUsername() & checkPassword() &
checkRepassword() & checkTel()) {
var target = evt.target || evt.srcElement;
// 如果所有表单数据验证都通过了就提交表单
target.submit();
}
});
}());
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="description" content="" />
<title>用户登录</title>
<style>
body {
width: 90%;
margin: 0 auto;
font-size: 16px;
}
#login {
width: 290px;
margin: 20px auto;
}
#login fieldset {
border-radius: 5px;
}
#login legend {
background-color: lightgray;
padding: 2px 15px;
border-radius: 5px;
}
#login span {
display: inline-block;
width: 60px;
text-align: right;
}
#login input {
margin: 12px 5px;
border: none;
}
#login input[name^="user"] {
width: 175px;
outline: none;
border-bottom: 1px dotted darkgray;
}
#login input[type="submit"] {
margin-left: 195px;
color: white;
background-color: chocolate;
border-radius: 5px;
}
#login input[type="submit"]:hover {
background-color: darkgreen;
cursor: pointer;
}
#data {
margin: 10px auto;
border-collapse: collapse;
}
#data td {
border-bottom: 1px solid gray;
border-right: 1px solid gray;
width: 160px;
height: 60px;
}
#data td.tl {
border-top-left-radius: 10px;
}
#data td.tr {
border-top-right-radius: 10px;
}
#data td.bl {
border-bottom-left-radius: 10px;
}
#data td.br {
border-bottom-right-radius: 10px;
}
#data td.last {
border-right: none;
}
#data td.first {
width: 250px;
padding-left: 10px;
}
#data td.center {
color: white;
text-align: center;
}
#data td.bottom {
border-bottom: none;
}
#data tr.head {
background-color:lightblue;
}
#data tr.odd {
background-color: beige;
}
#data tr.even {
background-color: blanchedalmond;
}
</style>
</head>
<body>
<form id="login" action="" method="post">
<fieldset>
<legend>用户登录</legend>
<span>用户名: </span>
<input type="text" name="username" required>
<span>密码: </span>
<input type="password" name="userpass" required>
<span>邮箱: </span>
<input type="email" name="useremail" required>
<input type="submit" value="登录" />
</fieldset>
</form>
<table id="data">
<tr class="head">
<td class="tl first"></td>
<td class="center">成都</td>
<td class="center">北京</td>
<td class="tr center last">杭州</td>
</tr>
<tr class="odd">
<td class="first">Python从入门到住院全国巡演</td>
<td class="after">2018年2月28日 上午9:30</td>
<td class="after">2018年3月28日 上午9:30</td>
<td class="last">2018年4月28日 上午9:30</td>
</tr>
<tr class="even">
<td class="first">MySQL从删库到跑路公开课</td>
<td>2018年2月27日 上午9:30</td>
<td>2018年3月5日 上午9:30</td>
<td class="last">2018年4月2日 上午9:30</td>
</tr>
<tr class="odd">
<td class="first">Django从学习到上吊交流会</td>
<td>2018年2月28日 上午9:30</td>
<td></td>
<td class="last">2018年5月21日 上午9:30</td>
</tr>
<tr class="even">
<td class="first bottom bl">爬虫从精通到坐牢无遮大会</td>
<td class="bottom">2018年3月3日 上午9:30</td>
<td class="bottom">2018年4月17日 上午9:30</td>
<td class="last bottom br">2018年1月15日 上午9:30</td>
</tr>
</table>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
body {
width: 960px;
margin: 20px auto;
}
#cart {
margin: 0 auto;
width: 850px;
}
#cart-header {
height: 40px;
background-color: lightgray;
margin-bottom: 20px;
}
#cart-header div {
line-height: 40px;
}
.left {
float: left;
}
.right {
float: right;
}
.w110 {
width: 100px;
}
.ml10 {
margin-left: 10px;
}
.w120 {
width: 120px;
}
.w250 {
width: 250px;
}
.center {
text-align: center;
}
.w20 {
width: 20px;
}
.w90 {
width: 90px;
}
.clear {
clear: both;
}
#cart-items>div {
height: 100px;
}
#cart-items>div>div {
line-height: 100px;
}
.w250 span {
display: inline-block;
font-size: 12px;
line-height: 16px !important;
}
.single-item {
border-bottom: 1px solid gray;
}
.small-button {
display: inline-block;
width: 20px;
height: 20px;
border: none;
}
.big-button {
color: white;
background-color: red;
display: inline-block;
width: 120px;
height: 40px;
border: none;
font-size: 22px;
}
#totalCount, #totalPrice {
color: red;
}
#totalPrice {
font: bolder 20px Arial;
display: inline-block;
width: 150px;
}
#cart a {
text-decoration: none;
}
#cart a:link, #cart a:visited, #cart a:active {
color: gray;
}
</style>
</head>
<body>
<div id="cart">
<div id="cart-header">
<div class="left w110 ml10">
<input id="selectAll" type="checkbox">
<label for="selectAll">全选</label>
</div>
<div class="left w250">商品</div>
<div class="left w120 center">单价</div>
<div class="left w120 center">数量</div>
<div class="left w120 center">小计</div>
<div class="left w120 center">操作</div>
</div>
<div id="cart-items">
<div class="clear single-item">
<div class="left w20 ml10">
<input name="selectOne" type="checkbox">
</div>
<div class="left w90">
<a href="">
<img src="img/a1.jpg">
</a>
</div>
<div class="left w250">
<span>
海澜之家/Heilan Home春装商务白衬衫男修身HNCAD3A067Y 漂白(69) 漂
</span>
</div>
<div class="left w120 center">&yen;<span class="price">138.00</span></div>
<div class="left w120 center">
<button class="small-button">-</button>
<input class="center count" type="text" size="2" value="1">
<button class="small-button">+</button>
</div>
<div class="left w120 center">&yen;<span>138.00</span></div>
<div class="left w120 center">
<a href="javascript:void(0);">删除</a>
</div>
</div>
<div class="clear single-item">
<div class="left w20 ml10">
<input name="selectOne" type="checkbox">
</div>
<div class="left w90">
<a href="">
<img src="img/a2.jpg">
</a>
</div>
<div class="left w250">
<span>
HLA海澜之家长袖衬衫男牛津纺休闲干净透气HNEAJ1E048A浅灰
</span>
</div>
<div class="left w120 center">&yen;<span class="price">128.00</span></div>
<div class="left w120 center">
<button class="small-button">-</button>
<input class="center count" type="text" size="2" value="1">
<button class="small-button">+</button>
</div>
<div class="left w120 center">&yen;<span>128.00</span></div>
<div class="left w120 center">
<a href="javascript:void(0);">删除</a>
</div>
</div>
<div class="clear single-item">
<div class="left w20 ml10">
<input name="selectOne" type="checkbox">
</div>
<div class="left w90">
<a href="">
<img src="img/a3.jpg">
</a>
</div>
<div class="left w250">
<span>
HLA海澜之家牛津纺清新休闲衬衫2018春季新品质感柔软长袖衬衫男
</span>
</div>
<div class="left w120 center">&yen;<span class="price">99.00</span></div>
<div class="left w120 center">
<button class="small-button">-</button>
<input class="center count" type="text" size="2" value="1">
<button class="small-button">+</button>
</div>
<div class="left w120 center">&yen;99.00</div>
<div class="left w120 center">
<a href="javascript:void(0);">删除</a>
</div>
</div>
</div>
<div id="cart-footer">
<div class="clear left">
<a id="clearSelected" href="javascript:void(0);">删除选中商品</a>
</div>
<div class="right">
<span>总共选中了<span id="totalCount">0</span>件商品</span>
<span>总计: <span id="totalPrice">&yen;0.00</span></span>
<button id="pay" class="big-button">去结算</button>
</div>
</div>
</div>
<script src="js/jquery.min.js"></script>
<script>
// jQuery中的$函数(jQuery)的作用
// 1. 如果$函数的参数是一个函数那么该函数绑定文档加载完成后要执行的回调函数
// 2. 如果$函数的参数是一个选择器字符串那么$函数会返回对应的元素(jQuery对象)
// 3. 如果$函数的参数是一个标签字符串那么$函数会创建该元素并返回(jQuery对象)
// 4. 如果$函数的参数是一个原生的JS元素对象那么$函数会将它转变成jQuery对象
$(function() {
// this到底是什么要看具体的上下文环境
// 简单的说函数中的this指的是谁调用了这个函数或者谁引发了这个函数的执行
$('#selectAll').on('change', function(evt) {
// 获取事件源的两种方式: evt.target或者this
// 这里拿到的是原生的JavaScript对象
if ($(this).prop('checked')) {
$('.single-item input[type="checkbox"]').prop('checked', true);
calcTotal();
} else {
$('.single-item input[type="checkbox"]').prop('checked', false);
$('#totalCount').text('0');
$('#totalPrice').html('&yen;0.00');
}
});
// 为单个商品项的复选框绑定改变事件
$('input[name="selectOne"]').on('change', function() {
if (!$(this).prop('checked')) {
$('#selectAll').prop('checked', false);
}
calcTotal();
});
// 为删除选中商品超链接绑定事件回调
$('#clearSelected').on('click', function() {
if (confirm('确定要删除所选商品吗?')) {
$('.single-item').each(function() {
if ($(this).find('input[name="selectOne"]').prop('checked')) {
$(this).remove();
}
});
calcTotal();
}
});
// 为减少和添加商品数量的按钮绑定事件回调
$('.single-item button').on('click', function(evt) {
$(this).parent().parent().find('input[name="selectOne"]').prop('checked', true);
if ($(this).text() == '-') {
var count = parseInt($(this).next().val());
if (count > 1) {
count -= 1;
$(this).next().val(count);
} else {
alert('商品数量最少为1');
}
} else {
var count = parseInt($(this).prev().val());
if (count < 200) {
count += 1;
$(this).prev().val(count);
} else {
alert('商品数量最多为200');
}
}
var price = parseFloat($(this).parent().prev().find('span').text());
$(this).parent().next().html('&yen;' + (price * count).toFixed(2));
calcTotal();
});
// 为单个商品项删除超链接绑定事件回调
$('.single-item a').on('click', function() {
if (window.confirm('确定要删除该项吗?')) {
$(this).parent().parent().remove();
calcTotal();
}
});
// 为商品数量文本框绑定改变事件回调
$('.single-item input[type="text"]').on('change', function() {
$(this).parent().parent().find('input[name="selectOne"]').prop('checked', true);
var count = parseInt($(this).val());
// 12 == "12"
// "12abc" == 12
// "xyz" == NaN
if (count != $(this).val() || count < 1 || count > 200) {
alert('无效的商品数量值');
count = 1;
$(this).val(count);
}
var price = parseFloat($(this).parent().prev().find('span').text());
$(this).parent().next().html('&yen;' + (price * count).toFixed(2));
calcTotal();
});
// 计算总计
function calcTotal() {
var checkBoxes = $('input[name="selectOne"]');
var priceSpans = $('.single-item .price');
var countInputs = $('.single-item .count');
var totalCount = 0;
var totalPrice = 0;
for (var i = 0; i < priceSpans.length; i += 1) {
// 复选框被勾中的购物车项才进行计算
if ($(checkBoxes[i]).prop('checked')) {
// 强调: jQuery对象使用下标运算或get方法会还原成原生的JavaScript对象
var price = parseFloat($(priceSpans[i]).text());
var count = parseInt($(countInputs[i]).val());
totalCount += count;
totalPrice += price * count;
}
}
$('#totalCount').text(totalCount);
$('#totalPrice').html('&yen;' + totalPrice.toFixed(2));
}
});
</script>
</body>
</html>
This diff is collapsed.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=957658&site=qq&menu=yes"><img border="0" src="http://wpa.qq.com/pa?p=2:957658:53" alt="点我聊一聊" title="点我聊一聊"/></a>
</body>
</html>
\ No newline at end of file
## 玩转Linux操作系统
### 操作系统发展史
![](./res/history-of-os.png)
### Linux概述
Linux是一个通用操作系统。一个操作系统要负责任务调度、内存分配、处理外围设备I/O等操作。操作系统通常由内核和系统程序(设备驱动、底层库、shell、服务程序等)两部分组成。
Linux内核是芬兰人Linus Torvalds开发的,于1991年9月发布。而Linux操作系统作为Internet时代的产物,它是由全世界许多开发者共同合作开发的,是一个自由的操作系统(注意是自由不是免费)。
### Linux系统优点
1. 通用操作系统,不跟特定的硬件绑定。
2. 用C语言编写,有可移植性,有内核编程接口。
3. 支持多用户和多任务,支持安全的分层文件系统。
4. 大量的实用程序,完善的网络功能以及强大的支持文档。
5. 可靠的安全性和良好的稳定性,对开发者更友好。
### 基础命令
Linux系统的命令通常都是如下所示的格式:
```Shell
命令名称 [命名参数] [命令对象]
```
1. 获取登录信息 - **w** / **who** / **last**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# w
23:31:16 up 12:16, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 182.139.66.250 23:03 4.00s 0.02s 0.00s w
jackfrue pts/1 182.139.66.250 23:26 3:56 0.00s 0.00s -bash
[root@izwz97tbgo9lkabnat2lo8z ~]# who
root pts/0 2018-04-12 23:03 (182.139.66.250)
jackfrued pts/1 2018-04-12 23:26 (182.139.66.250)
[root@izwz97tbgo9lkabnat2lo8z ~]# who am i
root pts/0 2018-04-12 23:03 (182.139.66.250)
```
2. 查看自己使用的Shell - **ps**
Shell也被称为“壳”,它是用户与内核交流的翻译官,简单的说就是人与计算机交互的接口。目前很多Linux系统默认的Shell都是bash(<u>B</u>ourne <u>A</u>gain <u>SH</u>ell),因为它可以使用Tab键进行命令补全、可以保存历史命令、可以方便的配置环境变量以及执行批处理操作等。
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# ps
PID TTY TIME CMD
3531 pts/0 00:00:00 bash
3553 pts/0 00:00:00 ps
```
3. 查看命令的说明 - **whatis**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# whatis ps
ps (1) - report a snapshot of the current processes.
[root@izwz97tbgo9lkabnat2lo8z ~]# whatis python
python (1) - an interpreted, interactive, object-oriented programming language
```
4. 查看命令的位置 - **which** / **whereis**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# whereis ps
ps: /usr/bin/ps /usr/share/man/man1/ps.1.gz
[root@izwz97tbgo9lkabnat2lo8z ~]# whereis python
python: /usr/bin/python /usr/bin/python2.7 /usr/lib/python2.7 /usr/lib64/python2.7 /etc/python /usr/include/python2.7 /usr/share/man/man1/python.1.gz
[root@izwz97tbgo9lkabnat2lo8z ~]# which ps
/usr/bin/ps
[root@izwz97tbgo9lkabnat2lo8z ~]# which python
/usr/bin/python
```
5. 查看帮助文档 - **man** / **info** / **apropos**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# ps --help
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
For more details see ps(1).
[root@izwz97tbgo9lkabnat2lo8z ~]# man ps
PS(1) User Commands PS(1)
NAME
ps - report a snapshot of the current processes.
SYNOPSIS
ps [options]
DESCRIPTION
...
[root@izwz97tbgo9lkabnat2lo8z ~]# info ps
...
```
6. 切换用户 - **su**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# su hellokitty
[hellokitty@izwz97tbgo9lkabnat2lo8z root]$
```
7. 以管理员身份执行命令 - **sudo**
```Shell
[jackfrued@izwz97tbgo9lkabnat2lo8z ~]$ ls /root
ls: cannot open directory /root: Permission denied
[jackfrued@izwz97tbgo9lkabnat2lo8z ~]$ sudo ls /root
[sudo] password for jackfrued:
calendar.py code error.txt hehe hello.c index.html myconf result.txt
```
> **说明**:如果希望用户能够以管理员身份执行命令,用户必须在sudoers(/etc/sudoers)名单中。
8. 登入登出相关 - **logout** / **exit** / **adduser** / **userdel** / **passwd** / **ssh**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# adduser jackfrued
[root@izwz97tbgo9lkabnat2lo8z ~]# passwd jackfrued
Changing password for user jackfrued.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@izwz97tbgo9lkabnat2lo8z ~]# ssh hellokitty@1.2.3.4
hellokitty@1.2.3.4's password:
Last login: Thu Apr 12 23:05:32 2018 from 10.12.14.16
[hellokitty@izwz97tbgo9lkabnat2lo8z ~]$ logout
Connection to 1.2.3.4 closed.
[root@izwz97tbgo9lkabnat2lo8z ~]#
```
9. 查看系统和主机名 - **uname** / **hostname**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# uname
Linux
[root@izwz97tbgo9lkabnat2lo8z ~]# hostname
izwz97tbgo9lkabnat2lo8z
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core)
```
10. 重启和关机 - **reboot** / **init 6** / **shutdown** / **init 0**
11. 查看历史命令 - **history**
### 实用程序
#### 文件和文件夹操作
1. 创建/删除目录 - **mkdir** / **rmdir**
2. 创建/删除文件 - **touch** / **rm**
- touch命令用于创建空白文件或修改文件时间。在Linux系统中一个文件有三种时间:
- 更改内容的时间(mtime)
- 更改权限的时间(ctime)
- 最后访问时间(atime)
3. 切换和查看当前工作目录 - **cd** / **pwd**
4. 查看目录内容 - **ls**
5. 查看文件内容 - **cat** / **head** / **tail** / **more** / **less**
6. 拷贝/移动文件 - **cp** / **mv**
7. 查看文件及内容 - **find** / **grep**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# find -name *.html
./index.html
./code/index.html
[root@izwz97tbgo9lkabnat2lo8z ~]# grep "<script>" . -R -n
./index.html:15: <script>
./code/index.html:2884: <script>
./code/foo.html:2:<!--STATUS OK--><html> <head><meta ...
```
8. 符号链接 - **ln**
9. 压缩和归档 - **gzip** / **gunzip** / **xz** / **tar**
10. 其他工具 - **sort** / **uniq** / **diff** / **file** / **wc**
#### 管道和重定向
1. 管道的使用 - **\|**
2. 输出重定向和错误重定向 - **\>** / **2\>**
3. 输入重定向 - **\<**
#### 别名
1. **alias**
2. **unalias**
#### 其他程序
1. 时间和日期 - **date** / **cal**
2. 录制操作脚本 - **script**
3. 给用户发送消息 - **mesg** / **write** / **wall** / **mail**
### 文件系统
#### 文件和路径
1. 命名规则
2. 扩展名
3. 隐藏文件
4. 工作目录和主目录
5. 绝对路径和相对路径
#### 目录结构
1. /bin - 基本命令的二进制文件
2. /boot - 引导加载程序的静态文件
3. /dev - 设备文件
4. /etc - 配置文件
5. /home - 用户主目录的父目录
6. /lib - 共享库文件
7. /lib64 - 共享64位库文件
8. /lost+found - 存放未链接文件
9. /media - 自动识别设备的挂载目录
10. /mnt - 临时挂载文件系统的挂载点
11. /opt - 可选插件软件包安装位置
12. /proc - 内核和进程信息
13. /root - root账户主目录
14. /run - 存放系统运行时需要的东西
15. /sbin - 超级用户的二进制文件
16. /sys - 设备的伪文件系统
17. /tmp - 临时文件夹
18. /usr - 用户应用目录
19. /var - 变量数据目录
#### 访问权限
1. **chmod**
2. **chown**
#### 磁盘管理
1. 列出文件系统的磁盘使用状况 - **df**
2. 磁盘分区表操作 - **fdisk**
3. 格式化文件系统 - **mkfs**
4. 文件系统检查 - **fsck**
5. 挂载/卸载 - **mount** / **umount**
### 编辑器vim
1. 启动和退出
2. 命令模式和编辑模式
3. 光标操作
4. 文本操作
5. 查找和替换
/正则表达式
:1,$s/正则表达式/替换后的内容/gice
g - global
i - ignore case
c - confirm
e - error
6. 参数设定
.vimrc
set ts=4
set nu
7. 高级技巧
- 映射快捷键
- inoremap key:...
- 录制宏
- 在命令模式下输入qa开始录制宏(qa/qb/qc/qd)
- 执行你的操作,这些操作都会被录制下来
- 如果要录制的操作完成了,按q结束录制
- @a播放宏(1000@a - 将宏播放1000次)
### 环境变量
1. HOME
2. SHELL
3. HISTSIZE
4. RANDOM
5. PATH
### 软件安装和配置
#### yum
- yum update
- yum install / yum remove
- yum list / yum search
- yum makecache
#### rpm
- rpm -ivh \-\-force \-\-nodeps
- rpm -e
- rpm -qa | grep
#### 源代码构建安装
- ...
- make && make install
#### 实例
1. 安装MySQL。
2. 安装Redis。
3. 安装NginX。
### 配置服务
1. systemctl start / stop / restart / status
2. systemctl enable / disable
3. 计划任务 - **crontab**
4. 开机自启。
### 网络访问和管理
1. 通过网络获取资源 - **wget**
- -b 后台下载模式
- -O 下载到指定的目录
- -r 递归下载
2. 显示/操作网络配置(旧) - **ipconfig**
3. 显示/操作网络配置(新) - **ip**
4. 网络可达性检查 - **ping**
5. 查看网络服务和端口 - **netstat**
6. 安全文件拷贝 - **scp**
7. 安全文件传输 - **sftp**
### Shell和Shell编程
1. 通配符。
2. 后台运行。
### 其他内容
1. awk
2. sed
3. xargs
\ No newline at end of file
## 关系型数据入门
### 关系型数据概述
1. 数据持久化。
2. 数据库发展史。
3. 关系型数据库特点。
4. E-R图。
5. 关系型数据库产品。
### MySQL简介
1. 安装和配置。
2. 常用命令。
### SQL详解
1. DDL
2. DML
3. DQL
### Python数据库编程
1. MySQLdb
2. PyMySQL
### ORM概述
## Redis实战
### NoSQL概述
### Redis安装和配置
### Redis的数据类型
This diff is collapsed.
......@@ -208,147 +208,17 @@ Python的就业市场分析:相同工作职位和要求,薪资普遍高3k-5k
> **说明:**本章节的授课重点不是要面面俱到把每个知识点都讲一遍,而是让学生能够用Python语言和内置模块迅速开发出一些实用的网络应用程序,让学生感受到经过一个月的学习已经能够使用这门语言做很多以前很难想象的事情。
#### Day21 - [图像和办公文档处理](./Day21/图像和办公文档处理.md)
### Web前端
- 操作图像 - 图像基础知识 / 使用Pillow / 剪裁图片 / 旋转和缩放 / 在图像上绘画
- 处理Excel电子表格 - openpyxl模块 / 读取Excel文档 / 获取工作表 / 取得单元格 / 填充数据 / 设置单元格 / 公式计算 / 其他常用操作
- 处理Word文档 - 读取Word文档 / 创建带样式的Word文档 / 设置段落 / 添加图片
- 处理PDF文档 - 从PDF提取文本 / 创建PDF / 加密PDF / 操作页面 / 暴力PDF口令破解
### Linux基础
#### Day22 - [关系型数据库入门](./Day22/关系型数据库入门.md)
### 数据库入门
- 关系型数据库概述 - 数据库发展史 / 关系型数据库相关概念 / 安装和使用MySQL
- SQL详解 - DDL / DML / DQL / DCL
### Web框架之Django
#### Day23 - [数据库编程](./Day23/数据库编程.md)
#### Day31 - Django实战(01) - 快速上手
- 使用PyMySQL模块 - 安装PyMySQL / 打开数据库连接 / 创建游标对象 / 执行DDL / 实现CRUD操作
- ORM - ORM的概念 / 安装SQLAlchemy模块 / 自动生成表 / 创建session对象 / 实现基本CRUD操作 / 关联映射 / 实现复杂查询操作
#### Day24 - [非关系型数据库入门](./Day24/非关系型数据库入门.md)
- NoSQL - 非关系型数据库的概念 / 非关系型数据库的分类 / 非关系型数据库的应用场景
- MongoDB和Redis - 安装和使用MongoDB / MongoDB中的基本概念 / 安装和使用Redis / Redis中的数据类型 / 使用PyMongo操作MongoDB / 使用redis模块操作Redis
> **说明:**在时间不充足的情况下建议将NoSQL的知识转移到后面的Web项目优化中进行,尤其是涉及到缓存和非结构化数据的处理时候再引入NoSQL的东西学生可能更容易理解和接受,而且强烈建议让学生在阿里云的Linux服务器上安装redis和mongodb,这样在也可以让学生相互协作配置这些服务的主从模式和集群模式。
#### Day25 - [总结和考试](./Day25/考试.md)
> 说明:建议用半天时间对Python基础知识进行简单回顾,对遗漏的知识点进行查漏补缺,了解学生对知识点的掌握情况,如果时间充足的情况下最好用思维导图的方式进行梳理,如果时间不够也可以将考试推迟到星期六。
### Web开发部分
#### Day26 - [用标签承载内容](./Day26/用标签承载内容.md)
- HTML5入门 - HTML5概述 / HTML标签简介 / CSS简介 / JavaScript简介
- 常用标签 - 标题 / 水平线 / 折行 / 段落 / 列表 / 图像 / 链接 / 表格 / 表单 / 块 / 跨度 / 内联框架
- HTML5的标签 - 画布 / 音频 / 视频 / 导航 / 页眉 / 页脚 / 选项列表 / 嵌入
#### Day27 - [用层叠样式表渲染页面-1](./Day27/用层叠样式表渲染页面-1.md)
- CSS入门 - CSS简介 / CSS语法 / 选择器 / 行内(内嵌)样式 / 内部样式 / 外部样式
- 常用CSS属性 - 文本 / 字体 / 尺寸 / 背景 / 列表 / 表格 / 链接 / 显示 / 定位 / 浮动 / 对齐
- 盒子模型 - 外边距 / 边框 / 内边距(填充)
#### Day28 - [用层叠样式表渲染页面-2]( ./Day28/用层叠样式表渲染页面-2.md)
- CSS其他知识 - 选择器的组合 / 伪类和伪元素 / 属性选择器 / 属性继承 / 计算优先级
- CSS3相关内容 - 文字效果 / 2D变换 / 3D变换 / 过渡和动画 / 弹性盒子 / 媒体查询
- CSS常用效果 - 导航栏 / 下拉菜单 / 滚动菜单 / 便签效果 / 提示信息 / 图文混排 / 分页效果 / 吸顶效果 / 开关效果 / 加载动画 / 覆盖效果
#### Day29 - [用JavaScript处理交互行为-1](./Day29/用JavaScript处理交互行为-1.md)
- JavaScript入门 - JavaScript的历史和现状 / 浏览器中的JavaScript
- JavaScript核心语法 - 核心语言元素 / 常用内置对象 / 面向对象编程 / 函数式编程 / ES规范
- 浏览器对象模型 - window对象 / 模态对话框 / screen对象 / location对象 / history对象 / navigator对象 / 计时器 / Cookie操作
#### Day30 - [用JavaScript处理交互行为-2](./Day30/用JavaScript处理交互行为-2.md)
- 文档对象模型 - DOM简介 / 事件处理 / 操作标签 / 操作样式表
- JavaScript常用实例 - 表单验证 / 购物车 / 轮播广告 / 倒计时效果 / 保存用户偏好 /
#### Day31 - [使用jQuery](./Day31/使用jQuery.md)
- jQuery入门 - jQuery简介 / 在页面中使用jQuery / jQuery对象 / 选择器
- 事件处理
- HTML元素操作
- 动画效果
- Ajax异步请求
#### Day32 - [使用Bootstrap](./Day32/使用Bootstrap.md)
- Bootstrap入门 - Bootstrap简介和原理 / 下载和使用Bootstrap
- Bootstrap实例
- 可视化定制
#### Day33 - [综合案例:房天下-1](./Day33/综合案例-1.md)
- 首页
#### Day34 - [综合案例:房天下-2](./Day34/综合案例-2.md)
- 登录页
- 注册页
- 用户自服务页
#### Day35 - [综合案例:房天下-3](./Day35/综合案例-3.md)
- 发布房源页
- 房源详情页
### Linux部分
#### Day36~Day39:Linux入门
#### Day40 - Django入门
### 后台开发部分
#### Day41 - Django中的模型
#### Day42 - Django中的视图
#### Day43 - Django中的模板
#### Day44 - 完整的案例-1
#### Day45 - 完整的案例-2
#### Day46 - Django专题知识-1
#### Day47 - Django专题知识-2
#### Day48 - Django专题知识-3
#### Day49 - Django专题知识-4
#### Day50 - 项目相关知识介绍
#### Day51 - 阶段项目-1
#### Day52 - 阶段项目-1
#### Day53 - 阶段项目-1
#### Day54 - 阶段项目-1
#### Day55 - 项目总结和考试
#### Day56~Day60 - Tornado相关
### Docker部分
#### Day61~Day70 - Docker的使用
### 爬虫开发
#### Day71~Day80- 分布式爬虫 / 搜索引擎
### 数据分析
#### Day81~Day95 - 数据分析 / 数据可视化 / 机器学习
### 项目实战
#### Day96~Day110 - 团队项目/ 项目答辩 / 简历指导 / 模拟面试
#### Day32 - Django实战(02) - 深入模型
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment