3.Python教程--项目框架篇(全)

Python人工智能总目录

人工智能总目录网页链接

文章目录

9、Python-web前端

Day01-HTML-页面

1. Web

1. 什么是WEB
web就是基于B/S模式的应用程序 - 网页

WEB的典型的应用:

B/S : Browser / Server 浏览器与服务器交互模式
C/S : Client / Server 客户端与服务器交互模式
2. 组成
服务器 : 处理用户的请求(request)和响应(response)->提供数据支持
# 服务器的组成: 服务器,浏览器 和 通信协议组成
浏览器 : 代替用户向服务器发请求,解析数据->代替用户向服务器发送请求(User Agent)
通信协议 : 规范数据传输及打包的方式. - http
http : Hyper Text transfer protocal 超文本传输协议
3. Web 服务器
  1. 作用 :
1. 提供数据支持
2. 接收请求并响应
3. 提供数据安全功能
4. 产品 :
5. Apache
6. Tomcat
7. IIS - Internet Information Service
8. Nginx ...
9. 开发语言:
10. Java
11. PHP
12. ASP.net
13. Python (Django, flask...)
4. 浏览器
  1. 作用 :
1. 代替用户向服务器发送请求 接收响应数据并解析,以图形化界面展示给用户
2. 产品(主流) :
    1. Chrome - Google产品
    2. Safari - Apple产品
    3. IE - 微软产品
    4. Firefox - Mozilla 产品
    5. Opera - Opera产品 划分依据 :
6. 市场份额(决定每年排名)
7. 浏览器引擎(内核)不同
	渲染引擎:解析页面,控制渲染结果
JS引擎:解析脚本
1. 技术 : 前端开发 - 制作网页 
    HTML : 写页面结构 
    CSS : 写样式 
    JS : 写逻辑,实现用户交互 
    框架 : VUE Angular Node.js

2. HTML 概述

1.HyperText Markup Language
1. HyperText Markup Language
   超文本     标记  语言
   作用 : 通过标签的形式书写页面结构并且填充内容
   1. 超文本:具备特殊功能的文本就是超文本
      普通文本 a :普通字符a
      超文本 a :表示的是超链接功能

      普通文本 b :普通字符b
      超文本 b :表示文字加粗功能
   2. 标记:超文本的组成形式
      普通文本 a : a
      超文本 a : <a></a>
   3. 语言:语言有自己的语法规范
2. W3C:World Wide Web Consortium 万维网联盟
2. 标记
也叫标签或元素,标记页面结构和内容,配合CSS实现页面整体布局和美化
以<>为标志
3. 网页
在计算机中以.html 或 .htm 后缀标识 
网页文件的打开工具 - 浏览器 
开发工具 : 记事本, sublime,VSCode,editPlus,WebStorm,Hbuilder... 
调试工具 : 浏览器自带开发者工具,使用右键-'检查'打开,或者F12打开

3. HTML基础语法

1. 标签/标记
1. 所有的标签都以<>为标志,区分普通文本
2. 标签分类:
   1. 双标签 : 成对出现,有开始,有结束 语法 : <标签名> 标签内容(文本或其他标签) </标签名>
   2. 单标签 : 只有开始,没有结束,本身代表一定的意义或功能 
	语法 :
      <标签名>
         或
      <标签名/>
3. 标签嵌套
	在双标签中嵌套添加其他标签
4. 文档结构
   1. 网页文件以.html / .htm为后缀
   2. 添加双标签<html></html>
   3. 在<html>标签中嵌套一对<head></head>,嵌套<body></body>标签
5. 标签属性
   主要用来修饰当前你标签的显示效果,或者为元素及网页本身添加额外补充信息
   语法 :
   	<开始标签 属性名=属性值 属性名=值>
   注意 :
      1. 标签属性必须写在开始标签中
      2. 属性值必须使用引号引起来,单双引号都可以
      3. 多组属性之间使用空格隔开
6. HTML语法规范
   1. 标签名不区分大小写,建议统一使用小写
   2. 标签名不报错,如果缺少闭合标签,浏览器会自动添加闭合;
		标签名书写错误,不报错,只是丧失原有标签的效果及功能
      <meta>
      <label>
      <table>
   3. 注释 :
      <!-- 注释内容 -->
      注意 :
      注释不能嵌套
      <body <!-- -->> 错误
      <!-- <!-- --> --> 错误
   4. 代码中适当添加注释与缩进,提高可阅读性
2. HTML标签介绍

3. 完整的网页结构
1. HTML5 提供的文档类型声明,以便浏览器能正确解析网页中的标签,并且采用标准方式渲染页面
2. <html></html>
	表示网页文档的开始和结束
3. <head></head>嵌套在html标签中,表示网页的头部,可以书写网页标题,字符集,外部资源的引入,网页相关介绍,网
	页选项卡图标
4. <body></body>表示网页的主体,也是浏览器窗口显示区域
	一切有关页面的内容都写在body中
4. 网页头部设置
网页头部:<head></head>中可以嵌套其它标签,设置标题,选项卡图标,字符集等信息
1. 标题
	<title>百度一下,你就知道</title>
2. 字符集
	<meta charset="utf-8">
3. 选项卡小图标
	<link rel="shortcut icon" href="图片路径" type="image/x-icon">
	图片后缀 .ico
	<link>标签用于引入外部资源
   标签属性 :
      rel 设置资源类型
      href 设置资源路径
      type 声明文件类型和后缀
5. 网页主体内容
1. 文本标签
   1. 标题标签 n表示数字,取值1~6,总共六级标题.标题中的文本自带加粗效果,并且一级到六级,字号逐级
   	减小
   2. 段落标签
2. 普通文本标签
	给一段文本中的某一部分额外添加样式或者动态操作使用的标签
   1. 行分区
      <span></span>
      常与段落或者标题结合使用,为内容设置额外样式
   2. <label></label>
      在表单中使用,优化用户操作
   3. 格式标签
      加粗 : <b></b><strong></strong> H5推荐使用更有语义的标签
      斜体 : <i></i>
      删除线 : <s></s>
      下划线 : <u></u>
      上标 : <sup></sup>
      下标 : <sub></sub>
	4. 空格与换行
   开发过程中出于代码整理造成的空格和换行.在浏览器解析时,统统理解为一个空格
	换行标签 : 可以使用<br/><br>实现换行
	5. 水平线标签 : <hr/>
  	6. 字符实体
      由于HTML是标签语法,所以在某些情况下,特殊字符无法正常显示
      例:
      	<day01> 标签语法
      	如果内容为<day01>,浏览器会认为是HTML标签
         3. < : &lt;
         4. > : &gt;
         5. 空格 : &nbsp;
         6. 版权符号 : &copy;
         7. 人民币符号 : &
6. 列表标签
1. 列表是一种结构化标签,按照从上到下依次显示数据,每一条数据称为一个列表项,不同类型的列表,项目符
	号不同
2. 分类 :
   1. 有序列表(ordered list) 默认按照阿拉伯数字从1开始排列 
		语法 :
         1. List Item
         2. 列表项
	2. 无序列表(unordered list)
		语法 :
			列表项
			默认以实心原点标识列表项 
      练习 : 
         新建文件,在body中添加列表 
         无序列表显示四大名著 
         有序列表列出四种编程语言



7. 列表的标签属性
1. 有序列表 - ol
	1. type 设置项目符号的类型,默认以阿拉伯数字标识 
      可取 : 
         1 默认项目符号 
         a 按照小写字母排序 
         A 按照大写字母排列 
         i 按照希腊数字排列 
         I 大写希腊数字排列
	2. start 设置项目符号使用第几个字符开始标识 
		取值 : 无单位的数值,跟项目符号类型无关
2. 无序列表 - ul type :
      设置项目符号的类型
      取值 :
         disc 默认实心原点
         circle 空心圆
         square 实心方块
         none 取消项目符号
8. 列表的嵌套
在列表中嵌套使用另外一个列表实现多级结构
语法 :
    <ul>
        <li>
            Desktop
            <ul>
                <li>Python-web</li>
            </ul>
        </li>
        <li>C盘</li>
    </ul>
    <ul>
        <li>Desktop</li>
        <ul>
            <li>Python-web</li>
        </ul>
        <li>C盘</li>
    </ul>
练习 :
   使用列表显示四大名著,
   每本名著下显示三个主要人物
建议 :
	下拉菜单使用嵌套列表实现,建议采用父子关系嵌套

9. 标签的层级结构
1.出现标签嵌套时,外层标签称为父元素,内层标签称为子元素
2.多级嵌套时,外层标签称为祖先元素,内层所有标签都可以称为后代元素
3.平级的子元素之间称为兄弟关系,元素称为兄弟元素
 :
   <html>
      undefined
   <head>
       <title></title>
   </head>
   <body>
       <h1>
           <span></span>
       </h1>
   </body>
   </html>
10. 图像与超链接标签

​ 1. 路径 (URL)

1. URL :
	统一资源定位符 Uniform Resource Locator 表示资源文件所在的位置
2. 组成 : 
	协议 域名 文件目录 文件名 
	 : 
      http://www.baidu.com 
      https://ss0.bdstatic.com/community/010cf65652fd876ac7251c94c524cf.jpg 
      file:///C:/Users/Python/Desktop/Web/day1/03-list.html
3. 分类 :
	1. 绝对路径
      从根目录开始查找文件
      Windows操作系统上,根目录以盘符为标志
      其他操作系统,根目录使用/表示
   2. 相对路径
      从当前所在目录(文件夹)开始查找资源文件
      可以使用../表示回退上一级目录
      ./表示当前目录文件夹
      et :
         03-list.html
   注意 :
      1. 网络URL中不能出现中文
      文件及文件夹名称中禁止出现中文
      2. URL严格区分大小写

​ 2. 图片标签(img)

作用: 在网页中插入一张图片
语法 :
标签属性 :
	1. src : 设置图片URL(必填)

Day02笔记

1. 图片与超链接

1. 图片
作用 : 在网页中插入一张图片
语法 : <img src="">
属性 :
    1. src : 设置图片URL,必填属性
    2. width : 设置图片宽度,取像素值
    3. height : 设置图片高度,取像素值
         : 默认情况下,图片会按照原始尺寸显示在网页中,宽高属性可以只写一个,另外一个方向会自动等比缩放
    4. title : 设置图片标题,鼠标悬停于图片时显示标题文本
    5. alt : 设置图片加载失败时的提示文本
2. 超链接
1. 作用 : 实现资源文件的跳转
2. 语法 :
		<a href="链接地址"></a>
3. 属性 :
   1. href : 设置资源文件的地址,必填
   	如果省略,超链接文本跟普通文本无差别
   2. target : 设置目标文件是否在当前窗口打开,默认值为 _self 表示在当前窗口打开新文件.可取 _blank 表示
   	新建窗口打开文件
4. 默认样式
   超链接自带两种状态:
      访问前 蓝色文本色,自带下划线
      访问后 紫色文本色,自带下划线
5. 锚点链接
   作用 : 链接到指定文件的指定位置
   语法 :
   1. 定义锚点
      <a name="1"></a>
      空标签添加name属性定义锚点名称
   2. 指定超链接的链接地址
      <a href="#1">1. 人物介绍</a>
      链接地址中使用#代表当前页面,后面跟上锚点名称,指定位置
6. 链接地址为空时的语法:
   1. href="" 跳转至当前页,包含刷新
   2. href="#" 跳转到当前页,没有刷新,会在当前url末尾添加上#
   3. href="javascript:void(0);"
   跳转至当前页,类似于href="",但是不会刷新页面

2. 表格标签

1. 结构化标签,采用行和列来显示数据
作用 : 在网页中插入一张图片
语法 : <img src="">
属性 :
    1. src : 设置图片URL,必填属性
    2. width : 设置图片宽度,取像素值
    3. height : 设置图片高度,取像素值
         : 默认情况下,图片会按照原始尺寸显示在网页中,宽高属性可以只写一个,另外一个方向会自动等比缩放
    4. title : 设置图片标题,鼠标悬停于图片时显示标题文本
    5. alt : 设置图片加载失败时的提示文本
2. 语法
1. 表格标签
2. 表格中嵌套行标签
	tr : table row
3. 行中嵌套单元格标签<td></td>
	td : table data
3. 标签属性
1. table 属性
   1. border : 为表格添加边框,取像素值
   2. bgcolor : 设置表格背景颜色,取颜色的英文单词
   3. align : 设置表格在父元素中的水平位置,取值 : left/center/right
   4. width : 设置表格宽度,取像素值
   5. height : 设置表格高度,取像素值  : 表格的默认尺寸由内容决定,手动设置宽高之后,会根据单元格
   内容的多少自动分配行和列的尺寸
   6. cellspacing : 设置表格边框与边框之间的距离,取像素值
   7. cellpadding : 设置单元格内容与边框之间的距离
   8. tr 属性
   9. bgcolor : 设置当前行的背景颜色
   10. align : 设置当前行内容的水平对齐方式,默认居左,可取值left/center/right
   11. valign : 设置当前行内容 的垂直对齐方式,默认垂直居中,可取值 top/middle/bottom
   12. td 属性
   13. bgcolor : 为单元格设置背景颜色
   14. align : 设置当前单元格内容的水平对齐方式
   15. valign : 设置单元格内容的垂直对齐方式
   16. width/height : 设置单元格的宽高尺寸
4. 单元格合并(表格结构调整)
1. 合并属性是单元格td独有的属性
2. 属性 :
   	colspan : collum-span 跨列合并
   横向合并单元格,取值为无单位的数值,表示包含当前单元格在内,合并几个单元格
   :
      colspan="3"
      rowspan : 跨行合并,取无单位的数值,表示合并几个单元格
3. 注意 :
   不管是跨行还是跨列,都涉及表格结构调整,需要手动删除多余的单元格
   跨列合并 : 删除当前行中多余的单元格
   跨行合并 : 删除后面行中对应的单元格

5. 表格内部结构(行分组标签)
1.表头行分组
2. <tfoot></tfoot>
	表尾行分组
3. <tbody></tbody>
	表格主体,行分组标签可以省略不写,默认情况下,所有的行都自动加入tbody中
6. th标签
用法与td一致,表示单元格,自带文本加粗和居中效果,常用于表头

3. 表单元素

1. 作用
表单用于收集用户信息,并将数据发送给服务器
2. 组成
1. form 表单元素
2. 表单控件(输入框,按钮,文件选择...)
3. 语法
<form>
	表单控件
</form>
4. form标签属性
1. action : 指定数据的提交地址
2. method : 指定数据的提交方式
   默认为get,可取get/post
   1. get 请求 :
      1. 将数据以参数形式拼接在URL后面,明文传输
       :
      	baidu.com?name=zhangsan&passwd=123456
      2. 安全性较低
      3. 数据大小有限制,不超过2Kb
   2. post请求
      1. 数据会被打包,以请求体的方式传输,外界不可见
      2. 隐式传输,安全性较高
      3. 没有大小限制
3. enctype : encode-type
   指定数据发往服务器时的编码类型
   取值 :
      1. application/x-www-form-urlencoded
      默认的编码方式,会将表单中的数据转换成一个字符串,附加到URL后面(get方式提交数据),请求新的URL
      2. multipart/form-data
      专门用来上传特殊数据类型,比如图片,文件等,通过二进制形式将数据发送至服务器,要求必须指定数据以post
      方式提交
5. 表单控件(重点)
1. 提供与用户交互的可视化组件
2. 分类
   1. 文本框和密码框 
      语法 :
         <input type="text">
         <input type="password">
      属性 :
         1. name : 定义控件名称,必填,缺少的话无法提交数据
         2. value : 设置控件的值,文本框与密码框的值更常见使用JS动态操作
         3. maxlength : 设置输入框最大字符数,取无单位数值
         4. placeholder : 用户输入之前显示的提示文本
         5. autocomplete : 文本框的自动提示功能,取值on/off
   2. 单选钮和复选框
      单选:<input type="radio">
      复选:<input type="checkbox">

      属性 :
         1. name : 控件名称,必填
         2. value: 控件的值,必填,代表按钮的含义,最终将发送给服务器
         3. checked : 设置按钮的选中状态,直接使用属性名,省略属性值
      注意 :一组按钮的name属性值必须保持一致
      特殊用法 : label for id
      将文本与按钮绑定在一起,点文本与点按钮一致
      语法 :
         <label for="male">
         <input id="male">
   3. 隐藏域和文件选择框
      1. 隐藏域 : 对用户不可见,某些服务器需要,但是不需要告知用户的数据,例如用户id,都可以使用隐藏域设置
      	<input type="hidden" name="uid" value="001">
      2. 文件选择框 :
         <input type="file" name="uImg">
          :二进制数据传输时, 必须使用post提交,必须指定enctype
   4. 下拉菜单
      语法 :
         <select name="address">
         	<option value="beijing"></option>
         </select>
   5. 多行文本域
      语法 :
         <textarea name='uinfo'></textarea>
		特点 : 支持多行输入,支持用户手动调整尺寸
   6. 按钮控件
      1. 提交按钮 : 当用户点击时,会将表单中的数据按照指定的方式发送给后台
      	<input type="submit" value="">
      	属性value用于设置按钮的显示文本
      2. 重置按钮 : 将表单中的数据恢复到初始化状态
      	<input type="reset" value="">
      3. 普通按钮 : 需要自行绑定JS事件
      	<input type="button" value="">
      	 : 提交和重置按钮自带显示文本,普通按钮没有默认显示文本,需要单独指定
      4. <button></button>标签
      	也可以表示按钮,标签内容就是按钮显示文本
      	注意 :
      		1. form表单外使用button标签,就是普通按钮
      		2. form表单内部使用<button>标签,等价于<input type="submit">,具有提交功能

Day03-CSS-样式

1. Cascading Style Sheet

1. Cascading Style Sheet
Cascading Style Sheet 层叠样式表,修饰和美化页面元素,实现页面的排版和布局.
1. CSS使用方式
2. 行内样式/内联样式
   语法 : 通过标签属性style,为元素设置CSS样式
    : CSS样式声明是由CSS的属性和值组成的
    :
       <h1 style="CSS属性名:值;"></h1>
   常用CSS属性 :
       1. 文本颜色 color 取颜色值(英文单词)
       2. 背景颜色 background-color 取颜色值
       3. 字体大小 font-size 取像素值
2. 文档内嵌
语法 : 使用<style></style>标签引入CSS代码,实现样式与结构的分离
例 :
   <style>
       CSS选择器{
           属性:;
           属性:;
       }
   </style>
   <h1></h1>
   <p></p>
 :
   1. CSS选择器主要用来匹配页面中的元素为其设置样式
   2. <style></style>标签可以书写在文档的任意位置,书写任意次,一般遵循"样式优先"的原则
3. 外链方式
1. 在HTML文件中使用外部的样式表文件,CSS文件以.css为后缀,文件中直接使用选择器书写样式,在HTML中使用标签引入

2. 外链方式真正实现结构与样式的分离,实现样式的复用

2. 样式表特征

1. 层叠性
不同的样式在同一个元素上共同起作用
2. 继承性
CSS某些样式可以被子元素或后代元素继承
 : 大部分的文本样式;
	块元素默认与父元素宽度保持一致
3. 样式表的优先级
元素发生样式冲突时最终选用哪一种样式,由样式表的优先级决定
1. 行内样式优先级最高 (style属性定义的样式)
2. 文档内嵌和外链样式优先级低于行内样式,发生样式冲突时,考虑代码的书写顺序,后来者居上.
3. 浏览器默认样式优先级最低 (user agent style)

3. CSS 选择器

1. 作用
选择页面中哪些元素应用样式
2. 分类
1. 标签选择器/元素选择器
   1. 作用 : 根据指定的标签名匹配文档中所有的该元素
   2. 语法 : 标签名 { 属性:; 属性:; }
   练习 : 
		创建文件,添加超链接标签 
		设置超链接文本色为红色,取消下划线 text-decoration:none;
2. id 选择器
   1. 作用 : 根据标签的id属性值选择元素
   2. id属性具有唯一性,不能重复
   3. id属性值命名规范 : 自定义,尽量见名知意; 可以由数字,字母,下划线 ,-组成,禁止以数字开头
   4. 语法 : 
			id选择器以#开头,后跟id属性值,用于匹配文档中唯一的元素 
	例 : 
		#id属性值 { 样式声明 } <标签 id="">
   练习 
		创建文件 id-selector.html 
		添加div标签,文本内容不限 
		设置div 200*200 尺寸,背景色自选
   	width:200px; height:200px;
3. class选择器/类选择器
   1. 作用 : 根据标签的class属性值匹配元素
   2. 特点 : 类选择器定义的样式可以实现复用,类名可在多个元素中重复使用,命名规范参照id属性值
   3. 语法 : 类选择器以英文.开头,后跟class属性值 
	例 : 
		.c1{ 
      	color:red; 
         font-size:32px; 
		}
   练习 
		创建class-selector.html 
		添加标签 p span div 
		通过类选择器为元素统一设置样式 200*200 文
   	本色 背景色 字体大小
   4. 特殊用法
   5. 标签选择器与类选择器组合使用,注意标签名在前,类名在后
      例 : 
         div.c1{
         } 
         匹配类名为c1的div元素 或 : .c1.c2 类选择器的组合使用

4. 群组选择器
   1. 作用 : 为一组元素统一设置样式
   2. 语法 :
      	选择器1,选择器2,选择器3...{

       	} 
	3. 练习 : 
		创建div h1 p标签 
		通过群组选择器,统一设置字体大小,文本颜色,自定义尺寸 
		div,h1,p{ 	
         font-size:32px; 	
         color:red; 	
         width:200px; 	
         height:200px; 
		} 
5. 后代选择器       
	1. 语法 : 
		选择器1 选择器2{
 		}       
	2. 作用 : 在选择器1对应的元素下,查找所有满足选择器2的后代元素     
6. 子代选择器       
	1. 语法 : 
		选择器1>选择器2{
		}       
	2. 查找直接子元素 
7. 伪类选择器
	1. 作用 :针对元素的不同状态设置样式       
	2. 分类 :
      1. 超链接伪类选择器 
			针对超链接访问前和访问后两种状态分别设置样式 访问前 :link 访问后 :visited
      2. 动态伪类选择器 
			:hover 表示鼠标滑过/悬停时的状态 
			:active 表示激活(鼠标点按不抬起)状态 
			:focus 文本输入框获取焦点时的状态(编辑状态)       
		3. 使用 : 伪类选择器必须与其他选择器结合使用,表示某种状态 
		例 : 	
			a:link{	
			} 	
			#d1:hover{ 	 
			}       
		4. 如果需要为超链接添加四种状态的样式, 需要固定书写顺序: LoVe/HAte 
			爱恨原则 :link :visited :hover :active
3. 选择器优先级
在使用选择器为元素设置样式,发生冲突时,最终选用哪一个选择器的样式,取决于选择器的权重
权重:权值,使用数字来标明选择器的优先级,数字越大,优先级越高

权重:

选择器权重
标签选择器1
类选择器10
id选择器100
行内1000
 : 
    1. 组合选择器(后代,子代,伪类),权重为各个选择器权值之和 
    2. 群组选择器权重不累加,单独看每个选择器的权重
练习 :
    创建div id为nav,表示导航栏
    div中嵌套若干a标签,表示导航项
    div : 宽高,背景色
    a : 取消下划线,修改默认颜色
    鼠标悬停修改a标签的文本色和背景色

4. HTML 标签分类

1. 块元素 :
独占一行,不与其他元素共行;可以设置宽高
例 : div p h1 table ul ol form li
注 : 除table外,所有块元素默认宽度与父元素保持一致,高度由内容决定
2. 行内元素
可以与其他元素共行显示,不能手动调整宽高
例 : a span label i b strong u s sub sup
3. 行内块元素
既可以共行显示,又可以设置宽高
例 : img input button
注 :
   行内块元素是特殊的行内元素,默认垂直方向上,以文本底部对齐显示(基线对齐).
   可以通过属性 vertical-align 调整行内元素的垂直对齐方式,常用于调整行内块元素垂直对齐问题
   取值 : top / middle / bottom / baseline(默认值)   

复习:

  1. 引入方式

  2. style属性书写行内样式

  3. 使用 <style></style> 标签书写样式

  4. 外链文件,使用 <link rel="stylesheet" href="">

  5. 引入方式之间的优先级

行内 > 外链/内嵌(代码书写顺序)
  1. 选择器
1. 标签选择器 div{}
2. id选择器   #id{}
3. class选择器 .className{}
4. 伪类选择器 a:link{}
5. 群组选择器 div,h1{}
6. 后代选择器 div span{}
7. 子代选择器 div>span{} div中的直接子元素span
  1. 选择器权重
选择器权重
标签选择器1
类选择器10
id选择器100
行内1000
组合选择器后代或子代选择器,权重为各个选择器权值之和
例 :
   span{
      color:red;
   }
   #box span{}
   .c1 span{}
  1. HTML 标签类型

  2. 块元素

块元素: 独占一行,手动设置宽高块元素默认与父元素宽度保持一致
 :
	<body>
		<div style="width:200px;">
			<h1></h1>
		</div>
	</body>
   元素 : body div h1 p ul ol table form li
  1. 行内元素
行内元素 :可以共行显示,不能手动调整宽高
常见 : a b strong span label i s u sub sup
  1. 行内块元素
行内块 : 既可以共行,也可以设置宽高
常见: img button input
属性: vertical-align
取值: top/middle/bottom
作用: 调整行内块元素的垂直对齐方式
  1. CSS属性
color
background-color
font-size
text-decoration
width
height
vertical-align

Day04笔记

1. 尺寸与颜色取值

1. 尺寸单位
px : 浏览器默认单位,表示像素
%  : 百分比单位参照父元素对应尺寸计算
em : 默认1em等于字体大小 16px
rem :参照文档根元素的字体大小进行尺寸设置
2. 颜色取值
1. 英文单词
2. rgb(r,g,b) 采用三原色设置颜色,取值范围 0 ~ 255
   特殊值 :
      rgb(255,0,0) red
      rgb(0,255,0) green
      rgb(0,0,255) blue
      rgb(0,0,0) black
      rgb(255,255,255) white
3. rgba(r,g,b,a) a表示alpha透明度,取值0-1
   0表示透明,1表示不透明,小数为半透明
    :
   	rgba(255,0,0,.55)
4. 十六进制表示颜色
   1. 语法 : 以#开头表示十六进制,可以使用6位字符或三位字符表示颜色,每位字符取值0-9,a-f
   2. 六位十六进制: 每两位为一组,代表一种三原色
   特殊值 :
      rgb(255,0,0) red #ff0000
      rgb(0,255,0) green #00ff00
      rgb(0,0,255) blue #0000ff
      rgb(0,0,0) black
      rgb(255,255,255) white
   计算 :
      ff :
      15 * 16 (0) + 15 * 16 (1)
2. 短十六进制 三位字符表示
   浏览器会自动对每一位重复扩充,最终完成6位十六进制
   #000 -> #000000
   #fff -> #ffffff

2. 内容与边框

1. 内容
1. 尺寸属性 : 
	width/height : 取像素值或%    
2. 内容溢出 : 
   元素内容超过元素自身的尺寸,称为溢出,默认溢出部分可见 
   属性 : overflow 
   取值 : 	
      visible (默认溢出部分可见) 	
      hidden	隐藏溢出部分 	
      scroll  强制在水平和垂直方向添加滚动条 	
      auto    自动在出现溢出的方向上添加可用的滚动条
2. 边框
1. 边框实现
	属性 : border 
	作用 : 为元素统一设置上右下左四条边框 
	取值 : 
      border-width border-style border-color 	
      1. border-width : 设置边框宽度,取像素值 	
      2. border-style : 设置边框样式,可取 		
         solid  实线边框 		
         dashed 虚线边框 		
         dotted 点线边框 		
         double 双线边框 	
      3. border-color : 设置边框颜色 
    注意 :  	
      1. 边框宽度默认为3px,border-width可以省略 	
      2. 边框颜色默认为黑色,border-color可以省略 	
      3. 边框样式必须写,没有默认值    
2. 单边框的设置
   1. 属性 : 
      border-top  	上边框  
      border-right	右  
      border-bottom	下  
      border-left		左
   2. 取值 : width style color;
3. 网页三角标制作 :
   1. 块元素设置宽高为0
   2. 统一设置四条边框宽度样式,透明色(transparent)
   3. 想要哪个方向的三角标就设置某个方向边框颜色,显示 注意 :
   4. 三角标是通过边框拼接而成,所以不能省略其他的边框
   5. 行内元素不能设置宽高,自带高度(文本大小决定),空标签只能拼接上下三角标,所以一般使用块元素做三角标
3. 轮廓线
类似于边框,常见于输入框获取焦点时自带的样式
区别 : 元素添加边框,在文档中是实际占位的,而轮廓线在文档中不占位
属性 : outline
取值 : color style width
使用 :
   取消文本输入框自带的轮廓线
   outline:none;
4. 圆角边框
1. 作用 : 
	调整元素四个角的显示形状,也可以改变元素形状
2. 属性 :
	border-radius    
3. 取值 : 
	像素值或百分比,表示半径,以当前半径在元素的四个角做圆或者椭圆,取一段弧,形成圆角效果    
4. 取值情况
   1. 像素值 
		border-radius : 20px; 四个角都以20px为半径做圆角效果  
		border-radius : 5px 10px 15px 20px;  分别代表上右下左四个角的圆角半径  
		border-radius : 10px 20px;  上下保持一致,左右保持一致  
		border:radisu : 10px 20px 30px;  上下分别为10px 30px,左右保持一致为20px
2. 百分比 
	百分比参照自身宽高尺寸计算圆角半径  
	根据宽高计算出两条半径,确定圆心,取弧,取值情况参照像素值  
	border-radius:20%;  
	border-radius:20% 30%;  
	border-radius:20% 30% 40%;  
	border-radius:10% 20% 30% 40%;
5. 取值范围
	不超过元素尺寸 
	注意 :  	
		1. 取100%等价于50%的效果 	
		2. 单个角的取值范围 0 ~ 100% 	
		3. 多个角统一设置,最大取50% 	
		4. 四个角统一50%,改变元素形状(圆/椭圆,与元素尺寸有关)
4. 盒阴影
1. 属性 : box-shadow
2. 取值 :
   offsetX : 阴影的水平偏移距离,取像素值 
	offsetY : 阴影的垂直偏移距离,取像素值 
	blur	: 阴影的模糊程度,取像素值,越大越模糊 
	spread	: (选填)阴影的延伸距离,取像素值 
	color 	: 阴影颜色    
3. 浏览器或者元素自身都具备坐标系.默认以左上角为(0,0)点,向右向下分别为X轴和Y轴的正方向

3. 盒模型

1. 一切元素皆为框
盒模型组成 : 
   元素尺寸(width/height)
   内边距 (padding)
   边框   (border) 
   外边距 (margin)
作用 : 各个属性互相叠加,影响元素在文档中的最终占据尺寸
计算 : 默认情况下,元素最终占据尺寸为 
   最终宽度 = width + 左右内边距 + 左右边框宽度 + 左右外边距
   最终高度 = height + 上下内边距 +上下边框宽度 + 上下外边距
2. 外边距 (margin)
1. 作用 : 设置元素与元素之间的距离
2. 属性 : margin
3. 取值 :
   像素值/百分比
   1. margin : v1;
   	设置上右下左四个方向的外边距
   2. margin : v1 v2;
   	设置上下外边距为v1,左右外边距为v2
   3. margin : v1 v2 v3;
   	左右外边距一致为v2
   4. margin : v1 v2 v3 v4;
   	分别设置上右下左四个方向的外边距
4. 特殊取值 :
   1. margin:0; 取消默认外边距
   2. margin:0 auto;
   	设置左右外边距自动,实现元素居中效果;auto只对左右边距有效
   3. 可以使用负值,实现元素位置的微调
5. 单方向外边距的设置
   1. 属性
      margin-top
      margin-right
      margin-bottom
      margin-left
   2. 取值:
   	只写一个值
6. 外边距合并
   1. 垂直方向
      1. 子元素(块元素)添加的margin-top,作用于父元素上
      解决办法 :
         1. 父元素添加顶部边框
         2. 父元素添加顶部内边距0.1px
         	padding-top:0.1px;
         3. 父元素添加overflow:hidden;
         2. 垂直方向上的块元素,同时添加上下外边距,取较大的值
   2. 水平方向
   行内元素默认情况下,对盒模型的属性部分支持,水平方向的外边距会叠加显示
7. 具有默认外边距的元素
   body h1~h6 p ul ol
   取消默认外边距 margin:0;
2. 内边距 (padding)
1. 元素内容与边框之间的距离
2. 语法 :
   1. padding:10px; 设置上右下左四个方向的内边距
   2. padding:10px 20px; 上下内边距一致,左右内边距一致
   3. padding:10px 20px 30px; 左右保持一致
   4. padding:10px 20px 30px 40px; 分别设置四个方向的内边距
   5. 单方向内边距的设置
   6. 属性 : padding-top padding-right padding-bottom padding-left
   7. 取值 : 只取一个值
   8. 具有内边距的元素

ul ol 表单控件 button
2. box-sizing
1. 作用 : 指定盒模型的计算方式
2. 取值 :
   1. content-box 默认值 大部分元素遵照content-box计算在文档中的实际尺寸,计算方法 : 盒模型
   	各项属性值依次累加
   2. border-box 表单控件默认都是按照border-box计算最终尺寸的 计算方法 : CSS属性
   	width/height定义的尺寸,是border-box的尺寸,包含边框,内边距,内容.
   	最终占据尺寸 width/height + margin

Day05笔记

1. 背景相关的属性

1. 背景颜色
属性 : background-color
取值 : 颜色值
注意 :
   1. 所有的元素默认背景颜色为透明rgba(0,0,0,0),窗口显示的白色是浏览器自动渲染的,与元素本身无关
   2. 背景颜色从边框位置渲染,包含内边距和元素尺寸区域
2. 背景图片相关
1. 背景图片设置
   属性 : background-image
   取值 : url('路径')
   注意 :
   	1. 路径加不加引号都可以,如果出现空格或者中文,必须加引号
   	2. 图片尺寸小于元素尺寸,浏览器会自动将背景图片重复平铺,填满元素
   	3. 图片尺寸大于元素尺寸,图片按照原始尺寸从边框位置显示,超出部分不可见
2. 背景图片重复方式
   默认水平和垂直两个方向重复平铺,填满元素
   属性 : background-repeat
   取值 :
   	1. repeat 默认值
   	2. repeat-x 沿水平方向重复平铺
   	3. repeat-y 沿垂直方向重复平铺
   	4. no-repeat 不重复平铺
3. 背景图片的尺寸设置
   属性 : background-size
   取值 :
      1. width height(px)
      2. %	 % 
         百分比单位参照当前元素尺寸计算并调整背景图片大小
         注意 : 如果只给一个值,默认表示宽度,高度会等比拉伸
      3. cover 图片等比拉伸至足够大,完全覆盖元素,超出部分裁剪不可见
      4. contain 图片等比拉伸至刚好被元素容纳,不改变图片宽高比,不会超出元素尺寸,会出现填不满元素的情况
4. 背景图片的位置设置
   默认情况下,元素的内容或者背景图片都是从左上角显示的
   属性 : background-position
   取值 :
   	1. x y(px)
   		分别表示水平和垂直偏移距离
   		正值表示向右向下移动
   		负值表示向左向上移动,一旦超出元素区域,超出部分不显示
   	2. % %
   		参照元素自身的宽高尺寸,计算偏移距离
   		1. 0% 0%
   			显示在元素的左上角
   		2. 100% 100%
   			显示在元素的右下角
   		3. 50% 50% 
   			显示在元素的中间
   	3. 方位值
   		x y 代表水平和垂直方向
   		取值 :
   			x : left/center/right
   			y : top/center/bottom
   		如果只设置一个方向的值,另外一个方向默认为center
精灵图技术 :
	为了减少网络请求,节省资源,通常会将一组按钮不同状态下的小图片拼在一张图片上,通过一次网络请求得到,页面中借助background-position调整图标的显示
3. 背景属性简写
属性 : background
取值 : color url() repeat position;
注意 :
   1. 使用简写属性统一设置背景相关的样式时,遵照以上顺序书写
   2. 属性值根据需要添加,没有必填项
   3. background-size是CSS3提供的属性,根据需要单独设置

2. 文本相关属性

1. 字体样式
1. 设置字体大小
   属性 : font-size 
   取值 : 像素值 /em    
2. 指定字体名称 
   属性 : font-family 
   取值 : 字体名称,多个名称之间使用逗号隔开; 
			如果字体名称中出现中文或者空格,必须加引号 
	 : 	
      font-family : Arial; 	
      font-family : Arial,"黑体","Microsoft YaHei";
3. 指定字体粗细 
	属性 : font-weight 
	取值 : 	
		normal (默认) 	
		bold   (加粗) 	
		使用100~900之间的整百数值表示粗细程度 	
		400 -> normal 	
		700 -> bold 
4. 指定字体样式(是否斜体或倾斜) 
	属性 : font-style 
	取值 : 	
		1. normal (默认正常显示) 	
		2. italic (斜体显示) 	
		3. oblique (字体倾斜显示) 
	注意 : oblique 默认情况下显示效果与 italic一致,没有区别.一般将oblique作为italic的备用样式   
5. 简写属性 
	属性 : font 
	取值 : style weight size family; 
	注意 : 	
		1. 严格按照顺序书写 	
		2. size family 是必填项,不能省略
2. 文本样式
1. 文本颜色
	属性 : color 
	取值 : 颜色值    
2. 文本的水平对齐方式 
	属性 : text-align 
	取值 : left/center/right/justify(两端对齐) 
	注意 :  	
		1.用于块元素,在元素尺	寸范围内设置文本内容的水平对齐; 	
		2. 两端对齐,浏览器会自动调整每一行字符之间的间距    
3. 文本的垂直显示位置 
		属性 : line-height 
		取值 : 像素值 
		使用 : 	
			1. 一行文本的垂直居中: 		
				将行高设置与高度保持一致,元素尺寸范围内,只能显示一行.
				文本内容在当前行中,永远是垂直居中的,浏览器会自动分配上下空隙 	
			2. 如果行高小于高度,文本显示在元素靠上的位置 	
			3. 如果行高大于高度,文本显示在元素靠下的位置,可以通过行高对文本位置微调 
		特殊 : 	
			line-height可取无单位的数值,表示字体大小的倍数,依此计算行高 	
			p{ 		
            font-size:16px; 		
            line-height:2; 		
            /*表示行高为字体大小的两倍,32px*/ 	
			}    
4. 文本装饰线 
	属性 : text-decoration 
	取值 : 	
		1. underline   下划线 	
		2. overline	   上划线 	
		3. line-through 删除线 	
		4. none 		取消装饰线    
5. 标签嵌套 
	1. 块元素中可以嵌套一切标签 
		注意 : 		
			1. 标题中只能嵌套段落或者行内元素 		
			2. 段落中只能嵌套行内元素
	2. 行内元素中只能嵌套行内元素

3. 表格相关的属性

1. 表格是块元素,CSS属性是可以通用

  1. table标签独有的CSS属性
1. 边框合并
   属性 : border-collapse
   取值 :
      1. separate (默认表格边框与单元格边框是分离状态)
      2. collapse 边框合并

2. 设置边框之间的距离
   属性 : border-spacing
   取值 : h v;
      两个值分别设置水平方向边框之间的距离
      垂直方向边框之间的距离,取像素值
   注意 : 必须在边框分离状态下才能使用该属性
3. 表格尺寸
   1. table设置宽高,单元格会自动分配空间
   2. table固定宽高,指定某个单元格的尺寸,会影响单元格所在的行高和列宽
   3. 如果需要统一设置所有单元格的尺寸,table就不能再指定宽高了,让表格的尺寸由内容决定

4. CSS过渡效果

1. 作用
不同状态下元素样式的改变,不再是瞬时完成,而是增加平滑过渡的效果
  1. 属性
1. 指定过渡时长
	transition-duration 
	取值 : 以秒(s)或者毫秒(ms)为单位的数值 1s = 1000ms    
2. 指定过渡属性 
	transition-property 
	取值 : 	
      1. all (代表所有CSS属性) 	
      2. CSS属性名,属性名,属性名    
3. 指定过渡效果的速度变化 
	transition-timing-function 
	取值 : 	
		1. ease 默认值,慢速开始,中间快速变快,慢速结束 	
		2. linear 匀速变化 	
		3. ease-in 慢速开始,加速结束 	
		4. ease-out 快速开始,减速结束 	
		5. ease-in-out 慢速开始和结束,中间过程先加速后减速    
4. 指定过渡效果延迟执行 
		transition-delay 
		取值 : 时间值(s/ms)    
5. 属性简写 
	语法 : 	
		transition : property 	duration timing-function delay; 
	注意 : 	duration 是必填项,不写过渡时长,就没有过渡效果 
	练习 : 	
		1. 块元素200*200,背景颜色自定义 	
		2. 鼠标悬停时,尺寸改为300*300,改成圆形,背景颜色自定义 	
		3. 所有样式改变,添加过渡效果,在3s内完成

5. 布局方式

1. 设置元素在文档中的排列显示和位置
2. 分类
1. 普通流布局/文档流布局/静态布局
	特点 : 按照元素类型和书写顺序,从上至下,从左到右,依次显示元素,是默认的布局方式    
2. 浮动布局 
	属性 : float 
   取值 : left/right/none(默认) 
	特点 : 	
		1. 元素设置浮动,会停靠在其他元素的边缘,left/right指定元素的浮动方向 	
		2. 浮动元素会脱离文档流,在文档中不再占位,后面正常元素会向前占位,影响整体布局 	
		3. 元素一旦脱离文档流,尺寸就由内容多少决定,可以手动调整宽高 	
		4. 浮动会造成文字环绕效果,浮动元素不占位,悬浮在文档上方,有可能遮挡正常元素,正常元素中的内容会围绕在浮动元素周围显示 
	问题 : 	浮动元素不占位,导致父元素高度为0,影响布局,影响父元素背景图片,背景色的展示 
	作业 :
		1. 自定义导航栏,内容样式不限,要求导航项均匀分布,导航项之间有间隔
   	2. 登录页面
      3. 表格练习

Day06笔记

CSS页面布局样式

1. 布局方式

1. 文档流布局
特点 : 根据标签类型和书写顺序从上到下,从左到右依次排列显示
2. 浮动布局
属性 : float
取值 : left/right/none
特点 :
   1. 元素设置浮动,会从它在文档中的原始位置,脱离文档流,向左或向右移动,停靠在其它元素的边缘,多个浮动元素会按照顺序依次停靠
   2. 浮动元素在文档中不占位,元素设置浮动之后都可以设置宽高尺寸,并且水平方向没有缝隙
问题 :
   子元素全部浮动不占位,导致父元素高度为0,自身的背景色背景图无法显示,后面正常文档中的元素会向前占位,影响布局
解决 :
   1. 给父元素固定高度(导航栏)
   2. 给父元素添加overflow:hidden;
   3. 清除浮动带来的影响 :
       在父元素末尾添加空的块元素,
       为新添加的块元素设置clear:both;
清除浮动 :
   属性 : clear
   取值 : left/right/both
   作用 : 使文档中正常元素不受前面浮动元素的影响
3. 定位布局
属性 : position
取值 : static(默认)/relative/absolute/fixed
已定位元素 : 只有元素设置position属性值为relative/absolute/fixed,才称为已定位元素
分类 :
   1. relative 相对定位
       特点 : 元素设置相对定位,会参照它在文档中的原始位置进行偏移
       偏移属性 :
           top : 正值,元素下移;负值,元素上移
           left :正值,元素右移;负值,元素左移
           right:
           bottom :
   2. absolute 绝对定位
       特点 : 
           1. 绝对定位的元素会参照一个离它最近的已经定位的祖先元素进行偏移,
              如果没有已定位的祖先元素,就参照浏览器窗口的左上角进行偏移.
           2. 绝对定位的元素会脱离文档流,所有脱流元素在文档中都不占位
       使用 :
           1. 偏移属性,根据元素参照物的边缘进行偏移
           2. 父相子绝 : 父元素相对定位,子元素通过绝对定位调整显示位置
   3. 堆叠次序调整
       属性 : z-index
       取值 : 无单位的数值,数值越大,越靠上,默认值为0
       使用 :
           1. 只有已定位的元素才可以使用z-index调整堆叠次序
           2. 兄弟元素之间,通过z-index调整堆叠次序,数值越大越靠上;数值相等,后来者居上(代码书写顺序)
           3. 父子关系不受z-index影响,永远子元素在上
   4. 固定定位 fixed
       特点 : 固定定位的元素,永远参照浏览器窗口进行偏移,固定显示在窗口的某个位置,不会跟随页面滚动而滚动(聊天窗)

2. 元素显示方式

1. display
取值 : inline/block/inline-block/none;
作用 : 调整元素的显示方式,取值对应标签分类
       inline 行内元素
       inline-block 行内块元素
       block  块元素
       none   元素隐藏不显示,隐藏元素不占位
2. visibility
取值 : visible(默认) / hidden (隐藏)
作用 : 控制元素显示与隐藏,元素隐藏但是仍然在文档中占位
3. opacity
取值 : 0 (透明) ~ 1 (不透明)
特点 :
    1. 使用opacity设置元素半透明,表示元素内部所有的内容都呈现半透明效果
    2. 父子元素都设置opacity半透明,子元素最终的半透明效果是在父元素基础上再次半透明,值相乘
3. 光标显示
属性 : cursor
作用 : 调整鼠标在当前元素上的显示形状
取值 :
    1. default 默认值
    2. pointer 手指形状
    3. text    文本 I 

3. 列表样式

1. 列表
列表 : 自带上下margin,padding-left,带有项目符号 
属性 : 	
	1. list-style-type : 		
		设置列表项目符号 	
	2. list-style-image: 		
      自定义项目符号 		
      取值 : url() 	
	3. list-style-position 		
   	取值 : outside(默认) / inside	 		
作用 : 
	设置项目符号的显示位置,是否在内容框中显示,默认在padding区域显示 
简写属性 : 	
	list-style : none; 	取消列表项目符号	

4. 转换属性

1. 转换操作
元素的缩放,平移和旋转都称为转换操作
2. 语法
属性 : transform
取值 : 转换函数 转换函数 转换函数;
3. 使用
1. 转换原点(基准点)
   默认以元素的中心点作为转换原点. 
   属性 : transform-origin 
   取值 : x y; 
      1. 取像素值 	在元素自身左上角为原点构建的坐标系中选取点的坐标 
      2. 取百分比 
      3. 取方位值 	left/center/right 	top/center/bottom    
2. 转换函数
	1. 平移变换 
   	函数 : translate(h,v)  
      取值 : 可以分别设置元素沿X轴和Y轴移动的距离,正值表示向右向下平移,负值表示反方向.取一个值,表示沿X轴方向平移  
      其他 : 
         translateX(value) : 沿X轴平移  	
         translateY(value) : 沿Y轴平移  	
         translate(value) : 等价于translateX(value)
	2. 缩放变换 改变元素在页面中的大小  
   	函数 : scale(value)  
		取值情况 :
         1. value为无单位的数值,表示缩放比
         2. value > 1 元素放大
         3. 0 < value < 1 元素缩小
         4. value < 0 ,数值仍然是缩放比,负号表示元素翻转  
		其他函数 :  	
			scaleX(value):X轴缩放  	
			scaleY(value):Y轴缩放  	
			scale(value) :沿X轴和Y轴同时缩放
	3. 旋转变换 
   	将元素旋转一定角度显示  
   	函数 : rotate(value)  
		取值 : 角度deg为单位的数值,正值表示顺时针旋转,负值表示逆时针旋转

      注意 : 转换基准点不同,效果不同  
      3D旋转  函数 : rotateX() / rotateY()

	4. 转换函数的组合使用
      1. 转换原点会影响最终结果
      2. 转换函数的先后顺序,也会影响结果:
      	旋转操作会连带坐标轴一起旋转

Day07-JavaScript-语言

1. Javascript 概述

1. Javascript 概述
浏览器解释型语言,嵌套在HTML文件中交给浏览器解释和执行.
2. 作用
实现用户交互(键盘或者鼠标操作);实现页面动效;小游戏制作等. 
3. 组成
1. 核心语法 (ECMAScript)
2. BOM : Browser Object Model,浏览器对象模型,提供一系列与浏览器相关的属性和方法
3. DOM : Document Object Model 文档对象模型,提供一系列操作页面的属性和方法
4. 自定义对象

2. JS的使用

1. 元素绑定事件
事件 : 所有用户的行为都称为事件
事件处理函数 :
   对应用户的行为,JS中所做的操作
   onclick 单击事件
语法 :
   <标签名 事件名="JS代码">
JS语句 :
   alert("Hello world"); //网页弹框
   console.log("控制台输出");
2. 在文档中嵌入JS代码,使用
注意 : 	脚本标签在文档中可以书写任意多次,出现在任意位置,但是不同的位置有可能影响执行结果. 
语法 : 
3. 外部的JS文件
创建.js文件,在HTML中通过<script src=""></script>引入
注意 : 引入外部JS文件时,脚本标签中不能再书写JS代码
输出语句 :
   prompt(""); 带有输入框的弹框,可以接受用于输入,并返回
   document.write(""); 在页面中写入内容,可以识别HTML标签;
   注意 :
       1. document.write()代码的书写位置,决定了内容在body中的添加位置
       2. 事件处理时书写的document.write(),会造成页面重写,点击会造成刷新
练习 :
   1. 使用元素绑定事件的方式,为button标签添加单击事件,点击时在控制台输出"第一个JS代码"
       <button onclick="console.log('');">点击</button>
   2. 使用内嵌的方式,在页面中写入一级标题,内容不限
       <script>
           document.write("<h1></h1>");
       </script>
   3. 外链方式给提示框
       <script src=""></script>

3. JS 基础语法

1. JS 基础语法规范
1. JS代码是由语句组成的,语句可以由变量,常量,运算符,关键字,函数等组成
2. JS代码中语句的结束以;为标志,可以省略
3. JS代码严格区分大小写
如:
   Console.log(); //错误
   consolo.log(); //错误
4. 所有的标点都是英文标点
   注释 :
   单行 : //单行注释
   多行 : /* 多行注释 */   

4. JS的变量与常量

1. 变量
1. 变量表示在程序运行期间随时可以修改的数据
2. 变量创建 :
3. JS 变量使用 
	var 关键字表示 
   语法 : 	
      var a; //变量声明,自定义变量名 	
      a = 100; //变量赋值 	
      var b = 200; //声明并赋值 	
      var m,n,k; //同时声明多个变量 	
      var s=10,y=20;//声明并赋值多个变量
4. 变量的命名规范
   1. 可以由数字,字母,下划线,$组成,禁止以数字开头;
   2. 禁止与关键字或保留字冲突(var const function class if do while for break continue name)
   3. 变量以小写字母开头,尽量见名知意,多个单词组成的变量名,采用小驼峰 
      例 :   	
         var userName;  	
         var username;
   4. 变量名严格区分大小写
5. 变量使用注意
   var a = 100;
   console.log(a,b,'');
   alert(a); //接收一个参数
   prompt(a);
   document.write('<h1>'+a+'</h1>');
3. 常量

4. 变量使用注意
1. 一经声明就无法修改的数据
2. 语法 :
	常量使用关键字 const 声明,必须声明的同时赋值;为了与变量区分,常量名采用全大写字母表示 
   例 : 	
      const PI = 3.14;: 强制修改常量,会报错	    
3. 练习 : 
   自定义半径(变量),定义圆周率(常量),计算圆的周长和面积,控制台输出结果    
4. 小数位设置 toFixed(n); 
   保留小数点后n位 
   例 : 	
      var a = 62.80000000004; 	
      a = a.toFixed(2);

5. JS数据类型

1. 简单数据类型

​ 1.number 数值类型

1.整数
   十进制表示
   var a = 10;

   八进制表示
   八进制数据以0开头,采用0-7八位数字表示
   var a = 010; //08(0)+18(1)
   控制台一律转成十进制输出

   十六进制表示
   十六进制表示整数,0x为前缀
   var b = 0x35; //516(0) + 316(1)

2. 小数
   小数点计数法 3.14
   指数计数法 1.5e3
   1.5 * 10(3)
   e表示10为底,3表示10的次方数

​ 2.string 字符串类型

字符串由一个或多个字符组成,使用引号表示,每位字符都有对应的Unicode码值
1. 语法 
	var s = '100';  
	var a = 100;
2. 查看字符对应的Unicode码值 
	方法 : charCodeAt(index);  
	参数 : 字符串默认为每个字符分配下标,0开始.参数传入下标,获取指定位置的字符编码  
	使用 :  	
      var s1 = "hello";  	
      s1.charCodeAt(0);
3. 已知中文的Unicode码,转换为字符,中文在计算机中以十六进制存储 
	方法 : 
		toString(16); //转换为16进制  十六进制字符串转换汉字时, 需要添加\u转义字符
4. 中文范围 
	"\u4e00" ~ "\u9fa5"
5. 转义字符 
	\n  : 换行  
	\t  : 制表符  
	\  : 表示\  
	\"  : 表示"
	

​ 3.boolean 布尔类型

布尔类型的结果只有真和假 true/false 
var isTrue = true; 
转换成数值true=1,false=0;

​ 4.null 空类型

布尔类型的结果只有真和假 true/false 
var isTrue = true; 
转换成数值true=1,false=0;
2. 复杂(引用)数据类型
对象,由属性和方法组成的

​ 1.检测数据类型

运算符(关键字) : typeof 
typeof a;
typeof (code.toString(16));

​ 2.数据类型转换

不同类型的数据进行运算,需要转换类型

​ 3.自动(隐式)类型转换

不同类型的数据进行运算,需要转换类型
1. 字符串与其他类型的数据结合,使用+号连接时,永远表示字符串的拼接
	转换规则 : 将非字符串类型的数据转换成字符串,后进行拼接,最终结果仍为字符串    
2. number + boolean 
	转换 : 将非number类型的数据,转换成number,进行数学相加 
	特殊 : 
		//undefined首先转换number,返回NaN(not a number,转换失败) 
		//10 + NaN = NaN 
		var s2 = 10 + undefined; 
		var s3 = 10 + null;  //10,null转number,转为0    
3. boolean + boolean 
	布尔类型参与数学运算,会自动转换成number

​ 4.强制类型转换

1. 转换字符串类型
   方法 : 
		toString(); 将任意类型的数据转换成字符串类型 
		例 : 	
			var a = 100; 	
		
			var a1 = a.toString(); 	
         console.log(a,typeof a); 	
         console.log(a1,typeof a1);    
2. 转换number类型
   1. Number(param) 
		将任意类型的数据转换成number类型  
		参数 : 需要类型转换的数据  
		返回 : 返回转换结果,成功则返回number值,失败返回NaN:  	
		var s1 = Number("35.5");//35.5  	
		var s2 = Number(true);//1  	
		var s3 = Number("18a"); //NaN
   2. parseInt(param) 解析字符串中的number数据(只保留整数)  
		过程 :  	
			1. 如果参数非字符串,自动转换成字符串类型  			
			2. 从左至右,对每一位字符串进行转number的操作,当前位转换失败则停止向后解析,直接返回结果  
			例 :  	
				var s1 = parseInt(35.5);  	
				var s2 = parseInt("18.5a");  	
				var s3 = parseInt("a18");//NaN
   3. parseFloat(param) 
			解析字符串中的number数据,包含小数部分  
			例 :  	
				var s1 = parseFloat("35.5");  	
				var s2 = parseFloat("18.5a"); 
				//9.3  	
				var s3 = parseFloat("9.3.5a");

6. 运算符

1. 赋值运算符 =
将赋值符号右侧的值赋给左边的变量
var a = 100;   
2. 算数运算符
+ - * / %(取余)   
1. 所有涉及字符串参与的+运算,全都是字符串拼接.:var s1 = "10" + true;
2. 非字符串类型参与算数运算,统一转换成number(自动转换),后进行计算.
  字符串类型再进行除+以外的其他运算时,也先转换number再进行计算
2. 自增/自减运算符 ++ –
1. 变量使用++/--,表示在自身基础上+1/-1
	var a = 10; a ++; 
	// a += 1; a = a + 1; 
	console.log(a);    
2. 使用 :
   1. 单独与变量结合,做前缀或做后缀,没有区别
   2. 与其他运算符结合使用时,前缀和后缀影响计算结果;
		做前缀,++/--,后结合其他运算;
		做后缀,先结合其他运算符,最后再++/--
3. 思考 : 
	var n = 5; 
	var r = n++ + ++n + n++ + ++n +n;: 	
		表达式1 : r1 = n++; //r1=5,n=6 	
		表达式2 : r2 = ++n; //r2=7,n=7 	
		表达式3 : r3 = n++; //r3=7,n=8 	
		表达式4 : r4 = ++n; //r4=9,n=9 	
		表达式5 : r5 = n;   //r5=9,n=9 	r = 5 + 7 + 7 + 9 + 9;

复习 :

  1. JS引入方式
  2. 事件绑定
<div onclick="JS 语句"></div>
  1. 使用标签
  2. 输出语句 alert(); prompt(); console.log(); document.write();
  3. 变量与常量 var a = 100; const PI = 3.14;
  4. 数据类型 number string boolean undefined null
  5. 数据类型转换
  6. 自动
15 + "10"  //"1510"
10 + 5 + "5" //"155"
"10" + true //"10true"
10 + "10" + true //"1010true"
10 + true + "10" //"1110"
10 + undefined //NaN
"10" + null //"10null"
true + false //1
  1. 强制

    1.任意类型转换字符串

toString();: 	
      var a = true; 	
      var a1 = a.toString();//"true"    

​ 2.任意类型转换number

1. Number(param):  	
		Number("50.4");//50.4  	
		Number("50a");//NaN  	
		Number(true);//1  
2.parseInt(param):  	
		parseInt(35.5);//35  	
		parseInt("35.5a")//35  	
		parseInt("a35.5")//NaN
3. parseFloat(param):  	
		parseFloat("35.5.3");//35.5
  1. 运算符

  2. 赋值运算符

  3. 算数运算符 + - * / %

例 :
   "10" - 5 ; //5
   "10a" - 5; //NaN
   "10" + true;
   "10" - true;//9
  1. 复合运算符
+= -= *= /= %=
例 :
   var a = 10;
   a += 5; // a = a + 5;
  1. 自增,自减 ++ –
1. 单独使用放前或放后没有区别
	例 : 	
      var a = 10; 	
      a ++; 	
      ++ a; 	
      5 ++; //error 	const A = 5; 	
      A ++; //error 
    	注 : 	自增和自减运算只能变量使用,常量无法修改    
2. 与其他运算符结合使用 
	例 : 	
      var n = 10; 	
      var r = n ++ + ++n;

Day08笔记

1. 运算符

1. 比较运算符(关系运算符)
> >= < <= ==(相等) !=(不等) 
> >===(恒等) !==(不恒等)
1. 比较运算符用来判断表达式之间的关系,结果为布尔类型
2. 分类
  1. number 与其他类型之间的比较
    过程 : 将非number数据转换成number,再进行比较
    注意 : NaN 与任意数据比较,结果都为false
  2. 字符串之间的比较
    1. 字符串之间比较,不会再数据类型转换
    2. 从前往后,依次比较每位字符的Unicode码
      例 :
      var r = "2" > "10";
      var r = "20" > "21";
  3. 字符串与布尔类型的比较
    例 :
       "10" > true //true
       "10a" > true //false
    注 : 先转number再比较
3. 相等与全等
  1. 相等:包含自动类型转换,只要值相等,就成立
    例 :
       "10" == 10  //true
       "10" != 10  //false
  2. 全等:不会进行自动类型转换,要求类型一致,值相等,才视为成立
    例 :
       "10" === 10  //false
       "10" !== 10  //true
2. 逻辑运算符
1. 将多个条件表达式的结果组合成最终单一的布尔值
2. 分类 :
   1. && :逻辑与
      两个表达式都成立,最终结果才成立,为true. (11):
          5 > 3 && "10" >"2" //false
          true && false
   2. || :逻辑或
      两个表达式中只要有一个成立,最终结果都为true. (11):
          5 > 3 || "10" >"2" //true
   3. ! :逻辑非
      对布尔结果取反操作
      非真即假,非假即真.:
          !(5 > 3) //false
          !false   //true
          !5      //false
       注 : 除零值以外的所有值都为真,零值为假
       练习 :
          接收输入的年份,检测数据类型;
			 判断该年份是否是闰年,在控制台输出结果
          闰年 :
         	 1. 能被 400 整除
         	 2. 能被4整除,但是不能被100整除

          接收用户输入一个字符,判断输入的内容
          是数字吗 ? 
             是字母吗 ?
             是中文吗 ?
3. 位运算
  1. 数据在计算机中是以二进制存储的,位运算是指直接对二进制位操作
  2. 分类 :
    1. 位与 : &
将操作数转换成二进制形式,按位进行与操作
 例 : 
        3   &  5 = 1
        011
    &   101
    ---------
        001  -> 1: 任何整数与1做位与,可以判断奇偶.结果为1,操作数为奇数;结果为0,操作数为偶数
    例 :
        3 & 1 //011 & 001 = 001
        2 & 1 //010 & 001 = 000

​ 2. 位或 : |

对二进制位进行或操作,11:
     3 | 5 //011 | 101 = 111

​ 3. 异或 : ^

比较二进制位,相同为0,不同为1:
    3 ^ 5 //011 ^ 101 = 110:
    异或可以在不借助第三方变量的情况下,互换两个变量的值
    var a = 3;
    var b = 5;
    a = a ^ b; //110 = 6
    b = a ^ b; //110 ^ 101 = 011 3
    a = a ^ b; //110 ^ 011 = 101 5
4. 三目运算符(三元)
  1. 语法
条件1 ? 表达式1 : 表达式2;
  1. 过程
判断条件1是否成立?
成立,执行表达式1
不成立,执行表达式2
返回结果
  1. 练习
1. 成绩判定
    接收用户输入的成绩
    >=90  A
    80~90 B
    60~80 C
    <60   D
    判断等级并输出
2. 身体指数 BMI
    bmi  = 体重(kg) / (身高 * 身高m);
    保留两位小数
    判断身体情况
    bmi > 23.9 该减肥了
    18.5 <= bmi <= 23.9 健康
    < 18.5 偏瘦

2. 流程控制(if、switch)

1. 作用
控制代码的执行顺序
2. 分类
  1. 顺序结构
自上而下,依次执行所有的代码语句
  1. 分支(选择)结构
根据条件是否成立,选择执行某段代码

1.if语句

1. if(条件){
   	条件成立时执行
   }:
       1. {} 可以省略,省略之后,if条件满足时,只执行后面紧跟的一条语句
       2. 零值为假 :
           if(0){}
           if(0.00){}
           if(""){}
           if(NaN){}
           if(undefined){}
           if(null){}
           注意 :
               带有空格的字符串视为真
2. if-else
	语法 : 
      if(条件){
         //成立时执行
      }else{
         //条件不成立时执行
      }:
       var age = 20;
       if(age >= 18){
           console.log("一起开黑");
       }else{
           console.log("未成年人禁止入内");
       }
3. 多重分支
   语法 :
       if(条件1){
          //条件1成立执行
       }else if(条件2){
          //条件2成立时执行
       }else if(){
          
       }else{

       }
   练习 :
      1. 使用if判断成绩等级
      2. 日期计算器,接收用户输入的年,,,判断当日是该年的第几天

2.switch语句

主要用来做值的匹配  
语法 :  	
   switch(变量){  		
      case 值1 :  			
         //匹配成功执行的代码段  			
         break; //结束匹配  		
      case 值2 :  			
         //匹配成功执行  			
         break;  		
      ...  		
      default:  			
         console.log("匹配失败,默认执行的操作");  			
         break;  	
   }  
   注意 :
      1. switch进行值的全等匹配,要求类型与值都一致,才能匹配成功
      2. case 用来列举所有可能的取值情况
      3. break用于结束匹配,可以省略;如果省略break,会从当前匹配到的case开始向后执行所有case中的代码
      4. 多个case可以共用代码段 :  			case '1' :  			case '3' :  			case '5' :  				alert("红烧肉");  				break;
      5. default 表示默认情况,写在最后,表示所有case都匹配失败最终执行的操作
	练习 :        
      1. 控制台输出1-100之间所有的 整数
      2.1-100之间所有整数的和
      3. 控制台输出1-100之间所有3的倍数
      4. 改版日期计算器

3. 循环结构(while、do-while、for)

  1. 重复执行某一段代码

  2. 循环三要素 : 循环变量; 循环执行的条件; 循环体

  3. 分类 :

    1.while 循环

语法 :
    循环变量;
    while(循环条件){
        循环体;
        更新循环变量
    }
例 :
    var i = 1;
    while(i < 101){
        console.log("优秀");
        //更新循环变量
        i++;
    }
执行流程 :
    1. 定义循环变量
    2. 判断循环条件
    3. 条件成立,执行循环体
    4. 循环体中更新循环变量,避免死循环
    5. 重复2-3-4,直到条件不成立,结束循环
练习 :
    1. 控制台输出1-100之间所有的 整数
    2. 求1-100之间所有整数的和
    3. 控制台输出1-100之间所有3的倍数
    4. 改版日期计算器

2.do-while 循环

语法 :
    循环变量
    do{
        循环体
        更新循环变量
    }while(循环条件);
执行流程 :
    1. 定义循环变量
    2. 执行循环体
    3. 更新循环变量
    4. 判断循环条件,条件成立,重复2-3-4;条件不成立,结束循环
练习 :
    循环接收用户输入并在控制台输出,直到用户输入"exit",结束循环
总结 :
    do-while 不管循环条件是否成立,至少执行一遍循环体;更适用于不确定循环次数的场合
    while 先判断后执行,更适用于明确循环次数的场合

3.for 循环

for(定义变量;循环条件;更新){
        循环体
    }
例 :
for(var i = 1; i < 101; i++){
        console.log(i);
}
循环控制 :
    1. break : 用于结束循环,后面的代码都不执行
    2. continue : 跳出本次循环,开始下一次循环
循环嵌套 :
    在循环体中嵌套使用其他循环体

练习 :
    1. 判断素数
        接收用户输入的一个数字,判断是否是素数
    2. 接收用户输入的年月日,判断星期几
        已知 : 199011日是星期一
        190011日是星期一
    3. 控制台输出图案
      一:
        *
        **
        ***
        ****
        *****:
        *
        ***
        *****
        *******
        *********
    4. 九九乘法表

Day09笔记

1. 函数

1. 函数
2. 作用 :
保存一段待执行的代码
3. 语法 :
1. 函数声明
	封装代码段 
   function 函数名 (参数列表) { 	
      函数体 	
      return 返回值; 
   }    
2. 函数调用 执行代码段 函数名(实际参数)
4. 注意:
1. 函数名自定义,见名知意,命名规范参照变量,普通函数使用小写字母开头.
2. 参数的小括号不能省略,多个参数之间使用逗号隔开
3. return关键字用于将函数内部的结果返回给外界使用,只能返回一个值(表达式),外界通过定义变量来接收.return关键字后面的代码都不执行,所以return写在函数体末尾
5. 其他声明和使用方式 :
1. 使用变量保存匿名函数
	var fun = function (){}; 
   fun();: 变量名相当于函数名    
2. 匿名函数自执行 (function (){})(参数);
6. 变量的作用域
1. 全局作用域
   1. 在函数外部定义的变量都是全局作用域中的变量,在任何地方都可以访问
   2. 所有省略var关键字创建的变量都是全局变量
   3. 函数作用域
   	在函数内部使用var关键字定义的变量都是局部变量,只在当前函数体中可以访问,外界无法使用    
	4. 作用域链 
		函数作用域中访问变量,首先从自身作用域中查找,查找失败,向外层作用中查找变量,依次类推,直至全局作用域 
练习 :    
   5. 日期计算改用函数封装 整体功能通过函数封装,按钮点击调用 闰年判断封装函数

2. 内置对象

  1. 对象由静态属性和动态方法组成

3. 数组 Array-遍历

1. 按照顺序存储一组数据
	1. 创建数组
   1. 使用[]表示数组结构,数据使用逗号隔开 例 :
      var arr1 = [1,2,3];
   2. 使用 new 关键字,根据类型 Array,创建具体的对象 例 : 	 	
      var arr2 = new Array(10,20,30); 	 	
      var arr3 = new Array(5);: 	 	
      使用new关键字创建数组时,如果只传一个整数作为参数,表示初始化数组长度(预分配,数组长度可以动态修改)

2. 操作数组元素
3. 数组会自动为元素分配下标,默认从0开始
4. 通过元素下标实现对数组元素的读取 语法 :   			 	
   arr[下标] = 10;
5. 遍历数组元素
	属性 : length 表示数组长度(元素个数),通过点语法访问 
   语法 : 
		for(var i = 0; i < arr.length; i++){ 	
      	console.log(arr[i]); 
   	} 
		for(var j = arr.length-1; j>=0;j--){ 	
         //倒序遍历 
      } 
		快速for循环 -- 
		for..in for(variable in array){ 	
         自定义变量variable表示数组下标 
      }  

练习 : 
   1. 循环接收用户输入,将数据存储在数组中,直至用户输入"exit"表示结束输入,控制台打印数组元素 
   2. 声明包含若干数据的数组(number),求这一组数据中的最大值 
   3. 创建一个包含三个number数据的数组,按照从小到大的顺序排列输出 	
   	[67,128,30] 	
      两两比较出结果 :  		
         第一次 : 67  128 		
         第二次 : 128 30 -> 30 128 		
         第三次 : 67 30 -> 30 67 
	4. 声明数组包含若干元素(number),接收用户输入,查询用户输入的数据在数组中对应的下标,如果不存在,返回-1            

4. 属性与方法

1. 属性 length 
	表示数组长度
2. 方法
	1. toString()
      作用 : 将数组转换成字符串
      返回 : 字符串
	2. join(param)
   	作用 : 将数组中的元素按照指定的符号链接,返回字符串
		参数 : 可选,用于指定元素之间的链接符,默认为逗号
	3. reverse(param)
      作用 : 反转数组,倒序重排
      返回 : 数组,反转操作改变原始数组的结构  
   4. sort()  
      作用 : 将数组中的元素按照Unicode码值升序排列
		返回 : 数组,改变原始数组的存储顺序
		参数 : 可选,自定义排序算法 
		例 :
         function sortASC(a,b) {
            return a-b;
         }
      自定义升序排列的算法,对number按照值的大小升序排列 :
      1. 参数a,b :代表数组中的两个元素.会自动传入相邻的两个元素进行比较
    	2. 如果a-b > 0,交换元素的位置,否则不变
      例 :
         function sortASC(a,b) {
            return b-a;
         }
      自定义降序排列
	5. push(data)
   	作用 : 在数组的末尾添加一个或者若干个元素,多个元素之间使用逗号隔开
		返回 : 新数组的长度
	6. pop()
   	作用 : 删除数组中末尾元素
		返回 : 被删除的元素
	7. unshift(data)
      作用 : 在数组的头部添加一个或多个元素
      返回 : 修改之后数组的长度
	8. shift()
      作用 : 删除数组中的第一个元素
      返回 : 被删除元素
	9. forEach(function)
      作用 : 遍历数组元素
      参数 : 通过函数,获取数组中元素,
      执行相关操作过程 : 每取出一个元素,将元素和其对应的下标,传入函数,自动执行.
      函数 : 接收两个参数,分别表示元素和下标;如果只定义一个形参,只接受元素       
例 :
	arr.forEach(function (elem,index){
		console.log(elem,index);
	});

5. 二维数组

1. 数组中的每一个元素又都是数组结构
2. 语法 : 
   var arr = [[1,2],[3,4],[5,6,7]];
3. 读取元素 : 
   var arr2 = arr[0];  
   var num = arr2[0];  
   var num2 = arr[1][0]; //3  
   练习 :  
      通过代码实现十进制转二进制,输出最终的二进制字符串  
      数字可以由用户输入(整数)  
      方法 :
         1.2取余,直至商为0
         2. 余数倒序排列
	例 : 
      5 -> 101
      5 / 2 = 2 ... 1
      2 / 2 = 1 ... 0
      1 / 2 = 0 ... 1   

Day10笔记

1. 字符串 String

1. 创建语法
var s1 = "100";
var s2 = new String("hello");
var s3 = String("hi");
注 : 内置对象类型,创建时可以省略new关键字
2. 属性
length : 获取字符串长度(字符个数)
注 : 字符串采用类数组结构存储每一个字符,自动为每位字符分配下标,默认从0开始 
3. 方法
  1. 英文转换大小写
1. toUpperCase() 将字符串中的字母转换大写
2. toLowerCase() 将字母转小写 返回 : 转换后的字符串,不会影响原始字符串 
   练习 : 
      模拟验证码 :
      1. 创建数组,存放数字,字母,作为数据源
      2. 生成随机验证码(4) 随机数 : Math.random() [0,1) 随机下标 : [0,10) , 取整
      3. 通过弹框提示用户输入,不区分大小写
      4. 验证用户输入,提示正确与否
      5. 用户点击 "获取验证码",提示用户输入
		6. 验证功能封装函数
		7. 生成验证码的过程也封装成函数,可以接受参数,生成指定位数的验证码
  1. 获取字符
1. charAt(index) 			获取指定下标的字符
2. charCodeAt(index) 	获取指定下标的字符Unicode码
  1. 检索字符(获取指定字符的下标)
1. indexOf(value,fromIndex) 
	作用 : 获取指定字符的下标  
   返回 : 下标,从指定位置(默认从0开始)向后查找,返回第一次匹配成功的下标;查找失败,返回-1  
   参数 :
 	   1.value : 指定字符或字符串,必填
		2. fromIndex : 选填,默认为0,表示从哪一个下标开始向后查找
2. lastIndexOf(value,fromIndex) 
	作用 : 获取指定字符()最后一次出现的下标位置  
   参数 : 
      1. value : 指定字符或字符串
		2. fromIndex : 指定起始下标,选填  
	注意 : lastIndexOf,根据给出的起始位置, 从后向前查找字符,找到即返回下标
  1. 截取字符串
substring(startIndex,endIndex); 
	作用 : 根据指定的下标范围,截取字符串并返回 
   参数 : 指定截取范围 [startIndex,endIndex),endIndex可以省略,表示截止末尾 
   练习 :

		1. 自定义邮箱字符串 
         用户名@服务商 
         要求 : 从邮箱字符串中提取除用户名和服务商
		2. 指定身份证号码,提取出生年月日 
      	例: 100321 1900 01 01 0001
    
  1. 分割字符串
split(seperator); 
作用 : 根据指定的分隔符,分割字符串 
返回 : 数组,存放分割后的每个字符串 
参数 : 指定分割符,如果字符串中不包含指定的字符,字符串不会被分割,仍然会返回数组 
练习 : 
	"101_5&201_10&301_20" 
   商品id _ 商品数量 
   101			
   5 提取商品id和数量,进行输出 
   "商品id为...数量为...."
  1. 模式匹配
1. 作用 : 结合正则表达式实现指定字符串的查找和替换
2. 正则表达式 :
   1. 语法 :
      /正则格式/修饰符
      修饰符 :
         i : ignorecase 忽略大小写
         g : global 全局匹配
      例 :
      var reg1 = /微软/g;
      var reg2 = /\d{2,6}/;
3. 字符串方法
   1. match(regExp/subStr);
      参数 : 可以使用正则表达式表示字符串格式,或者直接使用字符串
      作用 : 查找字符串中所有满足正则格式或给定字符要求的内容
      返回 : 数组,存放查找到的所有字符串
   2. replace(regExp/subStr,newStr)
      作用 : 根据指定字符或正则查找字符串中相应内容,并替换为newStr
      返回 : 替换后的新字符串,不影响原始数据

2. 正则表达式对象 RegExp

1. RegExp : Regular Expression
制定字符串的组成模式
2. 创建 :
1. var reg1 = /正则格式/修饰符;
2. var reg2 = new RegExp('正则格式','修饰符');
3. 属性和方法
1. 属性 : lastIndex
	可读可写,表示下一次匹配的起始下标    
2. test(param) 验证字符串中是否存在满足正则格式的内容,返回布尔值 参数为要验证的字符串

3. Math 对象

1. Math对象提供一系列数学方法
2. 属性
数学常量 :
    Math.PI 表示圆周率3.14或者度数 180度
    Math.E  自然对数
3. 方法
1. 三角函数
   Math.sin(x) 求正弦,参数为角度值 
   Math.cos(x) Math.tan(x): 可以借助Math.PI进行角度转换 
   例 : PI/3    
2. 计算函数 
   Math.sqrt(x) 开平方 
   Math.pow(x,y) 求x的y次方 
   Math.log(x)	 求对数    
3. 数值函数 
   Math.abs(x) 求绝对值 
   Math.max(a,b,c,d,e) 求一组数据的最大值 
   Math.min(a,b,c,d,e) 求一组数据的最小值 
   Math.random() 生成[0,1) 随机小数 
   Math.ceil(x) 对x向上取整 
   Math.floor(x) 舍弃小数位,保留整数位 Math.round(x) 四舍五入取整

4. Date 日期对象

1. 操作日期与时间
2. 创建
1. 获取当前的系统时间
	var date1 = new Date();    
2. 创建指定日期时间的对象 
	var date2 = new Date("2012/12/12 10:10:10");
3. 方法
1. getTime()
	读取当前日期对象距离1970-01-01 00:00:00 之间间隔的毫秒数
2. 读取时间分量
   1. getFullYear() 
   	获取当前日期对象的年份
   2. getMonth() 
   	获取当前日期对象的月份,返回0-11表示12个月,需要进行+1处理
   3. getDate() 
   	获取当前对象的日期信息
   4. getDay() 
   	获取当前对象的星期数  取值0-6,对应周日-周六
   5. getHours() 
   	获取小时数
   6. getMinutes() 
   	获取分钟
   7. getSeconds() 
   	获取秒数
   8. getMilliseconds() 
   	获取毫秒数
3. 转换日期格式
   1. toLocaleString() 
   	以本地格式显示日期时间
   2. toLocaleDateString() 
   	以本地格式显示日期
   3. toLocaleTimeString() 
   	以本地格式显示时间  
      外置对象

5. BOM

1. 浏览器对象模型
浏览器对象模型 : 提供与浏览器交互的对象. 核心对象是window(窗口) window 由浏览器在打开页面时自动创建,可以直接访问
2. window的属性和方法
window 包含的属性和方法 :
   1. 属性
   	history screen location document navigator 
   	以上都是对象类型,包含自身的属性和方法    
   2. 方法 
   	alert(); 
      prompt(); 
      confirm(""); 
   		确认框,参数为提示文本,自带确认和取消两个按钮,点击确认返回true,点击取消,返回false 
      window.close();  
         关闭当前窗口 
         定时器方法
	3. 使用
   	1. 可以省略window对象,直接访问相关的属性和方法 
      	window.alert();  
      	window.document.write();
		2. 所有的全局变量和全局函数,都是window对象的属性和方法 
      	练习 :  
            使用确认框,询问用户是否要关闭当前窗口;  
            如果点击确定,关闭窗口  window.close();
3. 定时器方法
  1. 周期性定时器(间歇调用)
1. 根据指定的时间间隔,不断调用相关代码
2. 语法 :
	1. 开启  
   	var timerID = setInterval(func,interval);  
      参数 :
			1. func : 需要间歇调用的代码段
			2. 时间间隔,默认以毫秒为单位  
      返回 : 定时器的ID
	2. 关闭  clearInterval(timerID);
  1. 一次性定时器(超时调用)
1. 在指定的时间间隔之后,执行一次代码
2. 语法  
	1. 开启 : 
      var timerID = setTimeout(func,interval); 
   2. 关闭 : clearTimeout(timerID);
3. 练习 
   1. 创建按钮(开始和结束) 点击开始,在控制台每个一秒输出一次系统时间 点击结束,停止输出    
   2. 弹框询问是否关闭窗口,如果点击确定,3秒后关闭页面

复习 :

  1. 内置对象
1. Array length join() reverse() push() pop() unshift() shift() toString() sort() forEach(function (elem,index){})
2. String length 按下标存取元素
3. toUpperCase() toLowerCase()
4. charAt(index) charCodeAt(index)
5. indexOf(str,fromIndex) lastIndexOf(str,fromIndex)
6. substring(startIndex,endIndex)
7. [startIndex,endIndex-1]
8. split(seperator):   
      var date = "2011-11-11";   
      var arr = date.split('-');
6. match(substr/regExp) 
	返回结果数组 replace(substr/regExp,newContent) 返回替换后的新字符串
7. RegExp
8. /知乎/g /\w{2}/ig new RegExp("正则格式",'修饰符')
9. lastIndex 下一次匹配的起始下标 test(str)
10. Math Math.random()  [0,1) Math.ceil(x)    
	向上取整 Math.floor(x)   舍弃小数位 Math.round(x)   四舍五入
11. Date
12. new Date()  
	获取当前的系统日期时间 new Date("") 根据指定日期时间,初始化日期对象
13. getFullYear() getMonth() 0-11表示月份 getDate() 日期  getDay()  星期 0-6 (周日-周六) getHours() 		getMinutes() getSeconds() toLocaleString() toLocaleDateString() 年月日 toLocaleTimeString() 时分秒 星期      

Day11笔记

1. 外置对象

2. window

1. 全局变量和全局函数的访问
全局变量和全局函数都是window对象的属性和方法,可以通过点语法访问
2. window对象
window对象在浏览器打开页面时自动创建,使用时可以省略
3. 方法
alert(str) 
prompt(str) 返回输入内容(字符串) 
confirm(str)返回true/false 
close() 关闭当前窗口 
var timerId =setInterval(func,interval); 
clearInterval(timerId); 
var timerId2 =setTimeout(func,timeout);
clearTimeout(timerId2);

4.属性

1. 大部分window对象的属性,又是对象类型,包含自身的属性和方法 
  例 : document screen location history...
2. screen 屏幕对象 
  保存与屏幕相关的信息  
   属性 :  	
      width/height : 获取屏幕宽高  	
      availWidth/availHeight : 实际可用的屏幕宽高(减去任务栏之后的尺寸)
3. history  
	保存当前窗口访问过的URL信息  
   属性 :  	
      length:获取当前窗口访问过的URL数量  
   方法 :  	
    	back():相当于浏览器的后退按钮  	
      forward():相当于前进按钮  	
      go(num):参数可正可负,正值代表前进,负值代表后退  
      注意 :   	
        1. 方法使用时,都是从当前页面在history中的位置开始,前进或者后退  	
        2. 窗口的历史记录数量,跟随url变化自动添加,访问顺序决定历史记录的顺序.重复切换页面,不会影响历史记录的顺序和数量
4. location 
	操作当前窗口地址栏的信息  
   属性 :  	
      href : 用来获取或设置当前窗口地址栏URL的信息;如果赋值,页面重定向,发生内容跳转  
      方法 : reload(param)  	重载页面,相当于刷新  	
      参数 : true/false  		
      	 	默认为false,从缓存中重载页面  		
          true 从服务器根目录重新请求页面

3. DOM - Document Object Model

1. 文档对象模型
重主要围绕document对象,实现对网页文档内容的操作
2. 节点树

在JS中,认为HTML文件本身就是一篇文档,文档的层次结构,对应在JS中表现为节点树.

节点 : 网页在解析过程中,其中的标签,标签属性,文本内容都会被封装成一个节点 
节点分类 : 	
		1. 元素节点 -> 标签名 	
		2. 属性节点 -> 标签属性 	
		3. 文本节点 -> 文本内容 	
		----------------------- 	
		4. 文档节点 -> document 	
		5. 注释节点 -> 网页中的注释 
节点操作 : 	
		1. 获取节点 	
		2. 读取和修改节点内容 	
		3. 创建节点 	
		4. 添加节点 	
		5. 删除节点    

3. 获取元素节点
1. document.getElementsByTagName('div'); 
	作用 : 通过标签名获取元素节点 
   返回值 : 节点列表(数组) 
   参数 : 字符串的标签名
2. document.getElementsByClassName('className'); 
	作用 : 根据class属性值获取元素节点的数组  
   返回 : 节点列表  
   参数 : 字符串的class属性值
3. document.getElementById('id属性值'); 
	作用 : 根据id属性值获取具体的元素节点  
   返回 : 节点对象  
   参数 : id属性值
4. document.getElementsByName("name"); 
	作用 : 根据name属性值获取节点数组  
   练习 :  
      创建文本框和按钮,div  
      点击按钮时,获取文本框输入的内容,以一级标题的形式显示在div中 innerHTML  
      元素节点常用属性 :
	1. innerHTML
   	读取或设置元素节点的标签内容,可以识别HTML标签语法
   2. innerText
   	读取或设置元素节点的文本内容,不能识别标签语法
   3. value
   	针对表单控件,表示表单元素的值
4. 操作标签属性
1. getAttribute('attrName')	 
	根据属性名,获取属性值

2. setAttribute('attrName','attrValue'); 
	为元素节点添加标签属性
3. removeAttribute('attrName'); 
	移除指定属性
4. 标签属性也是元素节点对象的属性,可用点语法直接访问 
	例 :  	h1.id = "d1";  	
      	//避免与JS关键字冲突,标签属性class对应的属性名使用className表示  	
         h1.className = "c1";  	
         //移除属性值  	
         h1.id = null;  
   练习 :  
      创建超链接,初始链接地址为百度  
      创建按钮,点击时修改超链接的链接地址,改为"http://www.tmooc.cn"
5. 操作元素节点的样式
1. 为元素添加id/class属性,对应选择器样式	
	例 : h1.setAttribute('class','c1'); 	
   h1.className = "c1";
2. 操作行内样式 
	例 :
      通过元素访问style属性,返回样式对象  	
         h1.style : 样式对象  
      样式对象中包含全部的CSS属性,可以通过点语法直接操作  
      注 : 
         通过样式对象点语法访问CSS属性,对于带有连接符的属性一律更名为驼峰标识;  	
         采用字符串为CSS属性赋值  	
         h1.style.fontSize = "20px";
   练习 :    
      1. 创建 div 文本框 按钮  	
         要求用户名必须在6-18位之间
      2. 点击按钮时,获取输入内容,进行验证  	
         验证通过,设置div显示文本"用户名合法",并设置字体颜色为绿色  	
         用户名不合法,设置div以红色文本色显示"不合法"         

Day12-DOM节点

1. DOM-查询节点

1. 读取节点信息
  1. 节点类型
属性 : nodeType
返回 : 
   1  元素节点
   2  属性节点
   3  文本节点
   8  注释节点
   9  文档节点
  1. 节点名称
属性 : nodeName
返回 :
   元素节点 -> 标签名
   属性节点 -> 属性名
   文本节点 -> #text
   注释节点 -> #comment
   文档节点 -> #document

2. 元素节点的层次属性

  1. parentNode
获取父节点
  1. childNodes
获取当前节点的所有子节点,返回子节点数组
(包含文本节点)
  1. children
获取当前节点的所有元素子节点.返回子节点数组
(只包含元素,不包含文本节点)
  1. nextSibling
获取下一个兄弟节点
nextElementSibling: 获取下一个元素兄弟节点
  1. previousSibling
获取前一个兄弟节点
previousElementSibling: 获取前一个元素兄弟节点
  1. attributes
获取当前元素节点中所有的属性节点,返回节点数组

3. 节点的创建,添加与删除

1. 创建节点
1. 创建元素节点
	var div = document.createElement('div'); 返回 : 创建成功的元素节点    
2. 创建文本节点
	var text = document.createTextNode('content'); 返回 : 创建成功的文本节点    
3. 属性节点操作
	标签属性可以通过元素节点直接访问 
  div.id = "d1"; 
  练习 : 
    动态创建div,设置id为box; 
    文本内容为"动态创建的div" 
    控制台输出元素节点
2. 添加节点
节点的添加和删除必须由父元素操作
1. 添加在父元素的末尾
  语法 :
    parentNode.appendChild(childNode);
  注意 :
    文本节点也是元素节点的子节点
2. 在指定位置插入节点
  语法 :
    parentNode.insertBefore(newNode,oldNode);
    在已有节点(oldNode)之前插入新节点(newNode)
  注意 : 节点对象不能复用,页面中想出现几个节点,JS中需要动态创建几个节点,一一对应
3. 删除节点
语法 :
    parentNode.removeChild(node);
    从父元素中移除指定节点对象
练习 :
1. 静态页面 :
  1. 顶部 三个输入框,一个按钮
  2. 主体 表格,第一行表头信息
2. 动态添加
  根据用户输入,创建行和单元格,添加到页面中显示
  注意 : 表格的行分组<tbody>
4. 事件处理
5. 事件 : 用户行为
6. 事件处理函数
  1. 系统提供的,在用户行为触发后,浏览器自动调用的函数

  2. 分类

1. 鼠标事件
  onclick     单击事件
  ondblclick  双击事件
  onmouseover 鼠标移入
  onmousemove 鼠标移动
  onmouseout  鼠标移出
2. onload 
	文档或元素加载完毕后触发执行
3. 表单控件状态改变
  onfocus     文本框获取到焦点时触发
  onblur      文本框失去焦点时触发
  oninput     实时监听文本框的输入
  onchange    监听输入框前后输入内容是否
  发生改变,要求输入框失去焦点并且前后内容不一致时触发
  onsubmit    表单元素监听,点击提交按钮时
  自动触发
4. 键盘事件
  onkeydown   按键被按下
  onkeypress  按键被按下
  onkeyup     按键抬起

3.元素绑定事件的方式

1. 内联 
    通过标签属性的方式,将事件处理函数绑定到具体的元素上
    ondblclick
2. 动态绑定事件
    语法 :
      h1.onclick = function (){

    };
3. W3C标准事件监听
		语法 :
				h1.addEventListener('click',function,false);
		参数 :
        1. 省略'on'前缀的事件函数名
        2. 事件触发后要执行的操作,以匿名函数或者函数名表示
        3. 默认值为false,可省略,表示事件冒泡,设置true,表示事件捕获
    事件传递机制 :
        表示事件的传递顺序.
        分类 :
          事件冒泡 : 从里向外逐级传递事件,默认机制
          事件捕获 : 从外向里逐级传递,IE不支持
  1. 事件行为
1. window.onload = function (){};
		等待窗口加载完毕后自动执行函数
2. form.onsubmit = function (){};
		点击提交按钮时自动触发,执行处理函数.
		函数中允许对表单数据做提交前的最后一步验证,通过返回值true/false控制数据是否可以提交给服务器.
		true : 允许发送
		false: 不允许发送
3. this关键字 :
    默认情况下,指代函数或方法的调用对象
    例 :
    function f1(){
    	console.log(this);
    }
    f1();
    window.f1();
  1. 事件对象
1. 事件对象 : 伴随事件产生,浏览器自动封装的对象,包含了所有与当前事件相关的信息
2. 获取 :
    事件对象会以参数的形式由浏览器自动传入事件处理函数中,我们只需要定义形参接收即可 
    例 :  function f1(){	} 
    f1(100);
    div.onclick = function (evt){};
3. 常用属性
	不同的事件类型,事件对象中包含的信息也不同
	1. srcElement/target
		获取当前事件的触发对象
	2. 鼠标事件对象
    1. offsetX offsetY
      获取鼠标在元素坐标系中的位置信息
      以元素左上角为原点,向右向下为正方向,构建坐标系
    2. clientX clientY
    	获取鼠标在网页窗口坐标系中的位置信息
    3. screenX screenY
    	获取鼠标在屏幕坐标系中的位置信息
	3. 键盘事件对象
    1. onkeydown
    	1. which
    		获取当前按键的键码
    2. onkeypress
    	只有在按下字符时才触发
    	1. which
    		获取当前按键字符的ASC码
    	2. key
    		获取字符

复习 : DOM

  1. 获取元素节点 getElementsByTagName/ClassName/Name() getElementById()
  2. 操作节点对象的属性和样式
  <h1 style = "" id="" class="">
  h1.style
  h1.id = "d1";
  h1.className = "c1"
  h1.style = "color:red;font-size:20px;";
  h1.style.fontSize = "24px";
3. 层次属性
  h1.parentNode;
  //返回子节点数组,文本节点也是元素的子节点
  h1.childNodes; 
  //返回元素子节点数组
  h1.children;
  h1.nextSibling;
  h1.nextElementSibling;
  h1.previousSibling;
  h1.previousElementSibling;
  //属性节点数组
  h1.attributes;
4. 创建,添加和删除
  document.createElement('');
  parentNode.appendChild(elem);
  parentNode.insertBefore(new,old);
  parentNode.removeChild(elem);
5. 事件
  1. 分类
    onclick
    ondblclick
    onmouseover
    onmousemove
    onmouseout
    -----------
    onload
    -----------
    onfocus
    onblur
    oninput
    onchange
    onsubmit : form监听,点击提交按钮时触发,允许通过返回值true/false决定数据是否发送
    -----------
    onkeydown :按键被按下就触发
    onkeypress : 按下字符按键时触发
    onkeyup :按键抬起时触发
  2. 绑定
    1. <h1 onclick = "">
    2. h1.onclick = function (){};
    3. h1.addEventListener('click',func,false);
  3. 事件对象
    1. 获取
      h1.onclick = function (event){
        event.target; //事件触发对象
        event.srcElement;
      };
    2. 鼠标事件对象
      offsetX offsetY
      clientX clientY
      screenX screenY
    3. 键盘事件对象
      onkeydown/onkeyup
        1. which :
            获取键盘按键编码
        2. key :
            获取按键对应的字符(功能键的名称或者大小写字符)
      onkeypress
        1. which
            获取按下字符的ASC码(区分大小写)
        2. key
            获取按下的字符(区分大小写)
-------------------------------------------

Day13-jQuery-框架

1. jQuery

1. 介绍 : jQuery 是JavaScript工具库,封装了一套定义好的方法,简化JS操作 
	版本 : 	1.xx.xx 包含IE6,7,8的兼容 	2.xx.xx 不再兼容IE6,7,8
2. 功能和优势 :
3. 简化DOM操作,简化样式操作
4. 可以通过选择器直接获取元素和操作样式
5. 简化事件处理
6. Ajax技术更加简便和完善
7. 提供大量的特效或功能插件
8. 允许自定义插件
9. 使用 :
	1. 引入jQuery
  		<script src=""></script>
   注意 :引入操作必须在自定义的JS代码之前,否则无法使用jQuery语法

2. jQuery 对象

对原生JS对象进行封装之后,称为jquery对象
原生对象调用原生方法
jquery对象使用jquery提供的方法,不能混用

3. 工厂函数 - $()

用来获取元素对象
通过传递参数执行获取
参数为字符串格式,传入选择器名称/DOM对象
选择器 :
    "h1"
    "#d1"
    ".c1"
    "div h1"
练习 :
    创建div/h1标签
    通过$("selector")获取元素并输出

4. jquery对象与DOM对象互相转换

  1. DOM转jquery
通过$()封装JS对象,返回jquery对象 
注 : jquery对象使用$前缀,与原生对象区分
  1. jquery转DOM
从jquery数组中取元素 var div = $div[0]; var div2 = $div.get(0);

5. 选择器

1. $()

说明:中可以接收选择器名称作为参数,匹配并返回元素对象,返回值是一个包含若干jquery对象的数组

语法 : $('selector');
2. 选择器

(1) 基础选择器

id class tagName group 语法 : 
1. $('#id') 
2. $('.className') 
3. $('tagName') 
4. $('selector1,selector2')

(2) 级选择器

1. 后代选择器 $('selector1 selector2')  包含直接与间接子元素
2. 子代选择器 $('selector1>selector2')  匹配直接子元素
3. 相邻兄弟选择器 $('selector1+selector2')   	匹配下一个兄弟元素,满足selector2则返回,否则匹配失败
4. 通用兄弟选择器 $('selector1~selector2');  匹配selector1后面所有满足selector2的兄弟元素

(3) 过滤选择器 需要结合其他选择器使用

1. :first 匹配第一个元素  例 : $('p:first') 匹配第一个p元素
2. :last 匹配最后一个元素
3. :odd 匹配偶数行对应的元素(奇数下标)
4. :even 匹配奇数行对应的元素(偶数下标)
5. :eq(index) 匹配下标为index的元素
6. :lt(index) 匹配下标小于index的元素
7. :gt(index) 匹配下标大于index的元素
8. :not('selector1,selctor2') 表示除了指定选择器以外剩余的元素

(4) 属性选择器[]

1. [attrName] 匹配包含指定属性的元素
2. [attrName=value] 匹配属性名等于指定属性值的元素
3. [attrName^=value] 匹配属性值以指定字符开头的元素
4. [attrName$=value] 匹配属性值以指定字符结尾的元素
5. [attrName*=value] 匹配属性值中包含指定字符的元素
6. [attrName!=value] 匹配属性名不等于属性值的元素

(5) 子元素过滤选择器

1. :first-child 匹配第一个子元素
2. :last-child 匹配最后一个子元素
3. :nth-child(n) 匹配第n个子元素

6. jquery 操作 DOM

1. 操作元素内容
html('')
    设置或读取标签内容,可以识别标签语法,类似于
    原生JS中的innerHTML
text('')
    设置或读取标签内容,不能识别标签语法,类似
    innerText
val('')
    设置或读取表单控件的值,类似于原生value属性
    练习 :
        创建文本框,按钮,div
        点击按钮时,将文本框的输入内容以一级标题的形式
        显示在div中
        使用jquery完成
2. 操作标签属性
1. attr('attrName','value')
   设置或读取标签属性 例 : $('div').attr('id','d1'); console.log($('div').attr('id'));    
2. prop('attrName','value') property 设置或读取标签属性 
   区分 : attr() prop()方法几乎一致,都表示属性操作 
   访问按钮checked属性时,取值不同
  $('input').attr('checked');//checked="checked"
  $('input').prop('checked');//checked="true"   
3. removeAttr('attrName') 移除指定属性
3. 操作元素样式
1. attr()/prop()
	为元素添加id/class属性,对应选择器样式 
2. 操作类选择器
	通过class属性值,结合选择器,修改样式
  1. addClass('className')
  	为元素添加class属性值,可以反复调用,反复添加
  2. removeClass('className'); 
  	移除指定的class属性值  省略参数,表示清空class属性值
  3. toggleClass('className') 
  	结合用户行为实现元素样式切换  元素存在指定className,就删除  不存在,则添加
3. 操作行内样式    
  1. css('color') 获取指定的CSS属性值
  2. css('color','red') 设置元素样式
  3. css(JSON对象) JSON对象 : 指定数据传输格式  
    使用 :
				1. 使用{}表示JSON对象
        2. CSS属性名和属性值都使用字符串表示
        3. 属性名与属性值之间使用:隔开
        4. 多组属性之间使用,隔开
        例 :  	
          css({
              "width":"200px",
              "height":"200px",
              "background-color":"red"  	
          })
 		练习 :  	
      创建div,文本内容不限  	
      使用css()设置:  		
        200*200  		
        背景色和文本色自定义  		
        文本水平和垂直居中  		
        元素居中          

复习

1. 引入jquery文件
2. $/jQuery  jquery对象 $()	     工厂函数
3. 获取元素 $('selector') -> jquery对象 jquery对象与DOM互相转换: 	
  1. dom->jquery : $(div) 	
	2. jquery->dom : $('div')[0] / $('div').get(0)
4. 选择器 tag id class group 后代 自带 相邻兄弟选择器(+) 通用兄弟选择器(~) :first :last :eq(index) :lt(index) :gt(index) :odd :even :not() :first-child :last-child :nth-child(n) [attrName][attrName='value'] ^= $= != *=
5. 操作元素
6. 操作内容
  html("")
  text("")
  val("")
7. 操作标签属性
  attr('attrName','value') //checked
  prop('attrName','value') //true
  removeAttr('attrName')
8. 操作元素样式
	1. 匹配类选择器
		addClass('className') removeClass('className') toggleClass('className') 切换类名,匹配样式    
  2. 行内样式
  	css('attrName') css('attrName','value') css({ "width":"200px", "height":"200px" })

Day14笔记

1. 通过层次关系获取节点

  1. parent()
获取父节点
  1. parents(‘selector’)
获取满足指定选择器的祖先元素,如果省略参数,返回所有祖先元素
  1. children()/children(‘selector’)
获取所有的直接子元素
获取所有满足选择器的直接子元素
  1. find(‘selector’)
获取满足选择器的后代元素,包含直接与间接
参数省略的话,查找不到
  1. next()/next(‘selector’)
获取下一个兄弟元素
获取下一个兄弟元素,要求满足selector,否则查找失败
  1. prev()/prev(‘selector’)
获取上一个兄弟元素
获取上一个兄弟元素,要求满足selector,否则查找失败
  1. siblings()/siblings(‘selector’)
获取所有兄弟元素
获取满足选择器的所有兄弟元素

2. 节点创建,添加和删除

1. 创建节点
语法1 :
    var $div = $('<div></div>');
    $div.html();
    $div.attr();
    $div.css();
语法2 :
    //<h1 id='d1' style='color:red;'>一级标题</h1>
    var $h1 = $("<h1 id='d1' style='color:red;'>一级标题</h1>")
2. 添加节点
  • 作为子元素添加
$obj.append($new) 		将 $new 作为 $obj 的最后一个子元素添加
$obj.prepend($new) 		将 $new 作为 $obj 的第一个子元素添加
  • 作为兄弟元素添加
$obj.after($new)  		将 $new 作为 $obj 的下一个兄弟元素添加  	
$obj.before($new)  		将 $new 作为 $obj 的上一个兄弟元素添加
3. 删除节点
$obj.remove(); 			删除$obj

3. 事件绑定

1. 等待文档加载完毕
// 方法一:
$(document).ready(function (){
    //等待文档加载完毕后执行
});

// 方法二:
$().ready(function (){
	//等待文档加载完毕后执行
});

// 方法三:
$(function (){
	//等待文档加载完毕后执行
});
注意 :
    原生onload事件不能重复书写,会被覆盖,只执行最后一次onload书写的代码
    jquery中的ready方法,可以重复使用,相关函数会从上至下依次执行,不会产生覆盖问题
2. 事件绑定方式
$obj.bind("事件名称",function)
参数 : 	
    1. 事件名称 : 省略on前缀 	
    2. function : 事件触发后执行的操作 例 : 
		$obj.bind('click',function (){});    
    	$obj.事件名称(function) 事件名称作为方法名,直接绑定,省略on前缀 例 :
        $obj.click(function (){});
3. 事件对象
事件对象的获取和属性操作与原生JS一致
例 :
   $obj.click(function (evt){
       //获取事件对象(参数接收)
       console.log(evt);
       //属性访问
       console.log(evt.offsetX);
   })
3. 遍历数组
each(function (){

});
遍历数组或集合,每取出一个元素,自动执行函数

10、Pythonweb-后端框架-Flask

Day01

Flask 轻量级的WEB框架 AJAX 在WEB中完成异步的请求和响应 Django 重量级的WEB框架

Python WEB

1.静态网页 和 动态网页

​ 1.静态网页 : 无法与服务器进行数据交互的网页 2.动态网页 : 允许与服务器进行数据交互的网页

2.WEB 与 服务器

1.WEB : 网页(HTML,CSS,JS)
2.服务器(Web Server)
    能够给用户提供服务的机器就是服务器
    1.硬件 和 软件
        硬件 : 一台计算机
        软件 : 一个能够接收用户请求并个给出响应的程序
            1.作用
                1.存储WEB的信息
                2.能够处理用户的请求(request)和响应(response)
                3.执行服务器端的处理程序
                4.具备最基本的安全功能
            2.服务器端的软件
                1.APACHE
                2.TOMCAT
                3.IIS(Internet Information Service)
                4.Nginx

3.框架

1.什么是框架
    框架是一个为了解决开放性问题而存在的一种程序结构
    框架的本身提供了最基本的功能
    我们只需要在框架的基础功能上搭建自己的操作就可以了
2.Python web 框架
    1.Flask - 轻量级
    2.Webpy - 轻量级
    3.Tornado - 异步框架
    4.Django - 重量级
3.框架模式
    1.MTV(Flask,Django)
        M : Models层,模型层,负责与数据库打交道
        T : Templates层,模板层,处理用户显示的内容,如html
        V : Views层,视图层,处理与用户打交道的内容(请求和响应)
    2.MVC
        M : Models层,模型层,负责与数据库打交道
        V : Views层,视图层,处理用户显示的内容,如html
        C : Controller层,控制器层,处理与用户打交道的内容(请求和响应)
        M  ---  M
        T  ---  V
        V  ---  C

4.Flask

1.什么是Flask
    Flask是一个基于Python并且依赖于Jinja2模板引擎和Werkzeug WSGI服务的一个微型框架(Micro Framework)
    WSGI : Web Server Gateway Interface(WEB服务网关接口)
    Flask是基于 MTV 框架模式开发出来的框架
2.安装Flask
    1.查看已安装的Flask版本
        在 python 的交互模式中
        1.import flask
            没报错 : 已经安装好了Flask,可以继续查看版本
            报错 : 没安装Flask
        2.flask.__version__
                已安装Flask的情况下,查看安装的版本
    2.安装Flask
        sudo pip3 install flask
        pip3 download flask
    3.初始化Flask应用
        见代码... ...
    4.杀掉占用5000端口的进程
        1.netstat -lptu
            查看占用5000端口的进程ID
        2.sudo kill -9 进程ID
            将进程ID对应的程序杀掉
    5.练习:
        1.访问路径是 http://localhost:5000/login
            在网页中显示:欢迎来到登录页面
        2.访问路径是 http://localhost:5000/register
            在网页中显示:欢迎来到注册页面     

5.Flask - 路由(route)

1.什么是路由
    处理url和函数之间的关系的程序就是"路由"
    @app.route('/login')
    def login():
        pass
2.路由的体现
    在Flask中,路由是通过@app.route装饰器来表示的
    1.基本的路由体现
        http://localhost:5000/admin/login

        @app.route('/admin/login')
        def admin_login():
            return "xxx"
    2.带参数的路由
        路由中可以携带参数来表示不同的数据
        http://localhost:5000/show/wangwc
        http://localhost:5000/show/gebilaowang
        http://localhost:5000/show/chaogege
        http://localhost:5000/show/xxx
        1.基本带参路由
            @app.route('/show/<name>')
            def show(name):
                # name 参数表示的就是由地址栏上传递进来的数据
                pass
        2.带多个参数的路由
            多个参数使用 / 隔开,并继续使用 <> 来表示
            @app.route('/show/<name>/<age>')
            def show(name,age):
                pass

        3.指定参数类型的路由
            使用 类型转换器 解决参数类型的问题
            @app.route('/show/<name>/<int:age>')
            def show():
                name : 字符串类型的数据
                age : 整数类型的数据
            
            int:类型转换器
            Flask中所支持的类型转换器
            类型转换器        作用
            缺省              字符串,不能有斜杠('/')
            int:              整数
            float:            浮点型
            path:             字符串,允许有斜杠('/')
    练习:
        1.访问路径如下
            http://localhost:5000/calc/数字1/数字2
        2.根据以上的访问路径制定路由以及视图处理函数
        3.在视图中,对两个数字进行相加,并响应在浏览器上
    3.多 URL 的路由匹配
        @app.route('/地址1')
        @app.route('/地址2')
        .... ....
        def index():
            return ""
    练习:
        当访问路径是以下任意一个的时候
        http://localhost:5000
        http://localhost:5000/index
        http://localhost:5000/数字
        http://localhost:5000/index/数字
        将请求交给 index_views()去处理
        判断路由中到底有没有数字传递进来:
            如果有:
                响应:您当前看的页数为 xxx
            如果没有:
                响应:您当前看的页数为 1
3.路由中设置允许接收的HTTP请求方法
    所有的路由默认只接受get请求,不接受post请求
    @app.route('/xxx',methods=['POST','GET'])
    @app.route('/xxx',methods=['POST'])
4.URL的反向解析
    正向解析:程序自动解析,会根据访问路径(@app.route('xxx')),自动来匹配处理函数

    反向解析:通过视图处理函数的名称自动生成对应的访问路径

    在Flask中要实现反向解析的话,需要使用:
    from flask import url_for
    url_for(funName,args)
        funName : 要生成地址所对应的函数名
        args : 该地址中要用到的参数
    作业:
        1.创建一个Flask项目 - Blog
        2.在Blog中,创建 run.py 启动文件
        3.在run.py中搭建好Flask程序结构
        4.定义如下访问路径,并给出响应:
            1.http://localhost:5000
                响应:这是blog的首页
            2.http://localhost:5000/list
                响应:这是blog的列表页
            3.http://localhost:5000/release
                响应:这是blog的发表页
            4.http://localhost:5000/info/<id>
                响应:查看id为xxx的blog信息
http://localhost:5000/ : 访问index()
http://localhost:5000/index : 访问index()

Day02

1.模板 - Templates

1.什么是模板
2.模板的设置
3.模板的渲染
1.什么是模板
    模板,在Flask中就是允许给用户看的网页,动静结合的
    动:允许包含服务器端的动态内容,如:变量,标签,过滤器,
    静:纯HTML,CSS以及JavaScript的内容

    在Flask中,模板是依赖于Jinja2的模板引擎
    Jinja官网:http://jinja.pocoo.org/
2.模板的设置
    默认情况下,Flask会在程序的主文件夹中会搜索一个templates的目录来作为模板的存放位置

    需要手动的在程序中创建一个 templates 目录,并将所有的模板文件(html)都存放进去
3.模板的渲染
    作用:在视图中,将模板文件(**.html)先变成字符串,再响应给浏览器
    语法:
        from flask import render_template
        return render_template('xxx.html')
4.模板中的语法(重点)
4.模板中的语法(重点)
    1.变量
        变量是一种特殊的占位符,告诉模板引擎,该位置的值是从渲染模板时的哪个数据中获取出来的
        语法:
            1.在视图中
                @app.route('/xxx')
                def xxx():
                    return render_template('xxx.html',变量1=值1,变量2=值2,... ...)
                    return render_template('01-template.html',name='wangwc',age=35)
            2.在模板中
                {{变量名}}
                01-template.html 中:
                    {{name}}
练习:
    创建 /03-template 路由,能够渲染 03-template.html模板,并在模板中输出以下内容:
    歌名 : <<绿光>>
    作词 : 宝强
    作曲 : 乃亮
    演唱 : 羽凡
允许传递到模板中作为变量的数据类型:字符串,整数,小数,列表,元组,字典,对象
    2.过滤器
        1.什么是过滤器
            在变量输出前,允许修改变量的值,再进行输出
        2.语法:{{变量|过滤器(参数)}}
        常用过滤器:
            过滤器名               说明
            capitalize             首字符变大写,其他变小写
            lower                  将值转换为小写
            upper                  将值转换为大写
            title                  将值中的每个单词首字符变大写
            trim                   去掉值两端的空格
            default('xx')          如果变量不存在,将采用default中的值作为默认输出
            truncate(num[,bool])     截取指定长度字符串,后面使用...显示
    3.标签
        1.什么是标签
            在模板中,标签是属于服务器端内容
            每个标签表示的是不同的服务器端的功能
        2.常用标签
            1. if 标签
                1. 基本if标签
                    {% if 条件 %}
                        if条件为真的时候,要执行的内容
                        允许是 静态内容,也允许是动态内容
                    {% endif %}
                2. if ... else 结构
                    {% if 条件 %}
                    ...
                    {% else %}
                    ...
                    {% endif %}
                3. if ... elif ... elif 结构
                    {% if 条件1 %}
                    ...
                    {% elif 条件2 %}
                    ...
                    {% elif 条件3 %}
                    ...
                    {% else %} -- 可选
                    ...
                    {% endif %}
            2. for 标签
                {% for 变量 in 元组|列表|字典 %}
                    允许出现静态内容:html,css,js
                    允许出现动态内容:
                        变量 - {{}}
                        标签 - {% if %} {% endif %}
                {% endfor %}

                循环的内部变量 - loop
                loop的作用:能够记载当前循环的一些相关信息
                    loop 常用属性:
                        1. index
                            作用:记录当前循环的次数,从1开始记录
                        2. index0
                            作用:同上,从0开始记录
                        3.first
                            作用:判断本次循环是否为第一次循环
                            值:True(是第一次循环) 或 False(非第一次循环)
                        4.last
                            作用:判断本次循环会否为最后一次循环
                            值:True(是最后一次循环) 或 False(非最后一次循环)
            3. macro 标签 (宏)
                1.作用
                    相当于是在模板中声明函数
                2.语法
                    {% macro 名(参数列表) %}
                        xxx xxx
                    {% endmacro %}
                3.在独立的模板文件中声明宏
                    1.创建 macro.html 模板文件
                        作用:定义项目中要用到的所有的宏
                    2.在使用的网页中,导入 macro.html 模板
                        {% import 'macro.html' as macros %}
            4. include 标签       
                将其他的模板文件包含到当前的模板文件中
                语法:{% include 'xxx.html' %}
5.静态文件的处理
5.静态文件的处理
    1.什么是静态文件
        在Flask中,不能与服务器做动态交互的文件称为静态文件
        如:图片,css,js,音视频,文档... ...
    2.静态文件的处理
        1.所有的静态文件必须放在 static 目录中
            static目录必须放在项目的根目录处
        2.所有的静态文件必须通过 /static/ 路径进行访问
            /static : 要到静态资源目录中进一步的搜索文件
                http://localhost:5000/static/images/a.jpg
作业:
    搭建Blog项目中的模板以及静态文件
    在 Blog 项目的基础上,实现以下功能:
    1.将所有的html页面导入到Blog项目中 -> templates
    2.将所有的静态文件(css,js,图片)导入到Blog项目中 -> static
    3.在模板中处理好所有的静态文件们
        1.首页 - /
            访问时,能够显示 index.html 中的内容
        2.列表页 - /list
            访问时,能够显示 list.html 中的内容
        3.发布页 - /release
            访问时,能够显示 release.html 中的内容
        4.详情页 - /info/id
            访问时,能够显示 info.html 中的内容     
明天:
    1.模板 
        模板继承
    2.修改配置
    3.请求(request) 和 响应(response)

Day03

1.模板中的语法

1.变量
    1.服务器端
        return render_template('xxx.html',var1=value1,var2=value2)
    2.模板
        {{var1}}
2.过滤器
    {{var|filter(parameters)}}
    {{var|default('xxxx')}}
    {{var|truncate(9,true)}}
3.标签
    1.if
        {% if express %} ... {% endif %}
    2.for
        {% for var in iterator %}
            {{loop.index}}
            {{loop.index0}}
            {{loop.first}}
            {{loop.last}}
        {% endfor %}
    3.macro - 宏
        相当于在模板中定义方法
        
        声明:
        {% macro 名(参数) %}
            
        {% endmacro %}
        调用:
        {{名(参数)}}

        将所有的宏声明在一个模板中 : macro.html
        {% import 'macro.html' as macros %}
    4.include
        {% include 'xxx.html' %}

========================================================

1.模板

1.静态文件地址的反向解析

​ 根据静态文件的具体路径,生成静态访问路径

    语法:
        url_for('static',filename='file_path')
        ex:
            url_for('static',filename='images/a.jpg')
            结果: /static/images/a.jpg
2.模板的继承
    1.语法
        1.父模板中
            需要定义出那些东西在子模板中可以被重写
            {% block 块名 %}
                在父模板中可以正常显示的内容
            {% endblock %}
            block :
                1.在父模板中可以正常显示,没任何影响
                2.在子模板中可以被重写
    2.子模板中
        1.指定需要继承自哪个父模板
            {% extends '父模板名称' %}
        2.按需重写
            {% block 块名 %}
                此处编写的内容会覆盖掉父模板中同名block的内容
                允许通过{{super()}}来调用父模板中的内容
            {% endblock %}               

2.修改配置

​ 1.构建Flask允许指定的配置信息

    app=Flask(
        __name__,
        template_folder='xxx',
        static_folder='xxx',
        static_url_path='/xxx'
    )
    1.template_folder : 指定存放模板的文件夹的名称
    2.static_folder : 指定存放静态文件资源的文件夹的名称
        注意:如果没有指定static_url_path的话,则访问路径和static_folder 的名称是一致的
    3.static_url_path : 指定静态文件的访问路径  

​ 2.启动程序的运行配置

    app.run(debug=True,port=端口号,host='0.0.0.0')
    host : 任何表示本机的地址都可以访问该项目

3.请求(request) 和 响应(response)

1.HTTP协议

​ HTTP:Hyper Text Transfer Protocol 作用:规范了数据是如何打包以及传递的

    1.通用消息
    2.请求消息
        1.请求起始行
            1.请求方式 - GET / POST
            2.请求协议 - http / https
            3.协议版本 - 1.1
        2.请求消息头
            表达客户端浏览器要传递给服务器的信息
            由 key:value 的形式组成
            每个消息头会传递不同的信息给服务器
        3.请求体
            伴随着请求要传递给服务器端的信息就是请求体
            只有 post 和 put 请求时有请求体的,其他请求方式没有请求体
    3.响应消息
        作用:将服务器端的信息传递给浏览器
        1.响应起始行
            1.协议以及版本号 : HTTP/1.1
            2.响应状态码 : 200 / 404 / 500
                1xx:请求已收到,继续处理
                2xx:请求成功接收
                3xx:该请求需要进一步处理
                    301 - 永久性重定向
                    302 - 临时性重定向
                    304 - 无修改,从缓存中提取数据
                4xx:资源不存在或无权限
                    404 : 请求资源不存在
                    403 : Forbbiden
                    405 : Method Not Allowed
                5xx:服务器处理请求失败
                    500 : Interneral Server Error 
            3.原因短句
                以简短的英文单词解释响应状态码
                200 : OK
                404 : Not Found
        2.响应消息头
            以 key:value 的形式存在,要传递给浏览器的一些说明信息
            ex:
                Content-Type : application / javascript

                Content-Type 作用:告诉浏览器响应回来的数据的类型
        3.响应主体

2.请求对象 - request

​ request - 请求对象,封装了所有与请求相关的信息.如:请求数据,请求消息头,… …

    在Flask中,要使用request的话,必须先导入:
    from flask import request
    允许在视图处理函数中使用request

    1.request的常用成员
        1.scheme : 获取请求协议
        2.method : 获取本次请求的请求方式(GET / POST)
        3.args : 获取以get请求方式提交的数据
        4.form : 获取以post请求方式提交的数据
    2.获取请求提交的数据
        1.get 请求方式
            1.地址栏上提交的数据
                http://localhost:5000/04-request?name=abc&age=30
            2.form表单中使用get方式提交
                <form action="/04-request">
                    <input type="text" name="name">
                    <input type="number" name="age">
                    <input type="submit">
                </form>
                http://localhost:5000/04-request?name=abc&age=30
            3.使用location.href
                location.href="http://localhost:5000/04-request?name=abc&age=30"
        2.post 请求方式
            只有表单中设置method为post才能产生post请求

            request.form 封装的就是以 post 方式请求提交过来的数据,允许按照字典的方式操作数据
                request.form['控件的name值']
                request.form.get('控件的name值')
作业:
    1.处理 Blog 中的 登录 - login
        1.如果是 get 请求,则渲染 login.html 到浏览器
        2.如果是 post 请求,则接收所有的请求数据 并响应给 浏览器
    2.处理 Blog 中的 注册 - register
        1.如果是get请求,渲染register.html到浏览器
        2.如果是 post 请求,接收所有的数据响应给浏览器
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_cached_json', '_get_data_for_json', '_get_file_stream', '_get_stream_for_parsing', '_load_form_data', '_parse_content_type', 'accept_charsets', 'accept_encodings', 'accept_languages', 'accept_mimetypes', 'access_route', 'application', 'args', 'authorization', 'base_url', 'blueprint', 'cache_control', 'charset', 'close', 'content_encoding', 'content_length', 'content_md5', 'content_type', 'cookies', 'data', 'date', 'dict_storage_class', 'disable_data_descriptor', 'encoding_errors', 'endpoint', 'environ', 'files', 'form', 'form_data_parser_class', 'from_values', 'full_path', 'get_data', 'get_json', 'headers', 'host', 'host_url', 'if_match', 'if_modified_since', 'if_none_match', 'if_range', 'if_unmodified_since', 'input_stream', 'is_json', 'is_multiprocess', 'is_multithread', 'is_run_once', 'is_secure', 'is_xhr', 'json', 'list_storage_class', 'make_form_data_parser', 'max_content_length', 'max_form_memory_size', 'max_forwards', 'method', 'mimetype', 'mimetype_params', 'on_json_loading_failed', 'parameter_storage_class', 'path', 'pragma', 'query_string', 'range', 'referrer', 'remote_addr', 'remote_user', 'routing_exception', 'scheme', 'script_root', 'shallow', 'stream', 'trusted_hosts', 'url', 'url_charset', 'url_root', 'url_rule', 'user_agent', 'values', 'view_args', 'want_form_data_parsed']

Day04-Flask-数据加密

1.Flask中数据加密 - 密码加密

1.请求 和 响应

1.文件上传
    1.注意问题
        表单中如果有文件上传的时候,必须遵循以下两个要求:
        1.提交方式 method 必须为 post
        2.表单的 enctype 属性值必须为 multipart/form-data
    2.服务器端处理
        1.request.files 获取上传的文件
            f = request.files['文件框的name值']
            注意:获取到的f对象(文件),是保存在缓存区中,而并非保存在磁盘上
        2.将文件保存到指定目录处
            f.save('static/'+f.filename)
    3.问题解决
        1.文件名称
            年月日时分秒微秒.扩展名 
            1.获取时间
                import datetime                 ftime=datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")
            2.获取扩展名
                ext = f.filename.split('.')[1]
            3.组合成新文件名
                fname = ftime+'.'+ext
        2.保存路径
            # 获取绝对路径
            basedir=os.path.dirname(__file__)
            # 拼成保存地址
            upload_path=os.path.join(basedir,'static/upload',filename)
            f.save(upload_path)

2.模型 - Models

1.什么是模型
    模型,是根据数据库中表的结构而创建出来的class
    每一张表对应到编程语言中就是一个类
    类中的每个属性对应到表中就是表的每个列
2.模型框架 - ORM
    1.什么是ORM
        ORM : Object Relational Mapping
                        对象   关系       映射
    2.ORM的三大特征
        1.数据表(table)到编程类(class)的映射
            数据库中的每一张表对应到编程语言中都有一个类
        2.数据类型的映射
            数据库表中的列以及数据类型 对应到 类中也有对应的属性以及类型
        3.关系映射
            将数据库表与表之间的关系 对应到 编程语言中类与类之间的关系
    3.ORM的优点
        1.封装了数据库中几乎所有的操作,大大提高开发效率
        2.省略了庞大的数据访问层,即便不使用SQL编码也能完成对数据的CRUD操作
            C : Create
            R : Retrieve
            U : Update
            D : Delete
3.Flask中的ORM框架
    Python中的ORM框架 - SQLAlchemy
    pip3 install sqlalchemy
    Flask中使用的也是 SQLAlchemy,但中间需要使用 Flask-SQLAlchemy 连接 Flask 和 SQLAlchemy
    pip3 install flask-sqlalchemy
4.定义数据库 以及 连接数据库
    1.创建数据库
        create database 数据库名 default charset utf8 collate utf8_general_ci;
        推荐:
            1.Navicate for MySQL
            2.Power Designer 
    2.Flask中连接数据库
        from flask import Flask
        from flask_sqlalchemy import SQLAlchemy

        app = Flask(__name__)

        #指定数据库的配置给 app
app.config['SQLALCHEMY_DATABASE_URI']='mysql://root:123456@localhost:3306/flask'
        #再将app交给SQLAlchemy,创建数据库实例
        db = SQLAlchemy(app) 
        # 以后在Flask中操作数据库的时候可以使用 db
5.定义模型(重点)
模型:类 (模型类 或 实体类)    
语法:
class MODELNAME(db.Model):
     __tablename__ = "TABLENAME"
     COLUMN_NAME=db.Column(db.TYPE,OPTIONS)
     COLUMN_NAME=db.Column(db.TYPE,OPTIONS)
     ... ...

     1.MODELNAME:定义模型类的名称,尽量参考表名
     2.TABLENAME:映射到数据库中表的名称
     3.COLUMN_NAME:属性名,映射到数据表中列的名称
     4.TYPE:映射到列的数据类型
     5.OPTIONS:列选项,如:是否唯一,默认值,加索引...

​ db.TYPE 列类型如下:

    类型名         python类型                说明
    Integer         int                 普通整数,32位
    SmallInteger    int                 小整数,16位
    BigInteger      int                 不限精度整数
    Float           float               浮点数
    Numeric         deciaml.Decimal     定点数
    String          str                 字符串
    db.String(30)
    Text            str                 字符串
    Boolean         bool                布尔值
    db.Boolean ->   tinyint
    Date             datetime.date      日期:年月日
    Time            datetime.time       时间:时分秒
    DateTime        datetime.datetime   日期和时间:年月日时分秒
    
    OPTIONS 列选项:
        选项名                 说明
    autoincrement  如果设置为True表示该列要自动增长
    primary_key    如果设置为True表示该列为主键
    unique         如果设置为True表示该列的值唯一
    index          如果设置为True表示该列创建索引
    nullable       如果设置为True表示该列允许为空   默认是非空 - False
    default        为列指定默认值          
练习:
    1.创建Student实体类
        表名:student
        属性:     1.id : 主键自增
                 2.sname : 姓名,长度为30的字符串
                 3.sage : 年龄,整数
                 4.isActive : 启用状态,默认为True
    2.创建Teacher实体类
        表名:teacher
        属性:     1.id : 主键自增
                  2.tname : 姓名,长度为30字符串
                  3.tage : 年龄,整数
    3.创建Course实体类
        表名:course
        属性:     1.id , 自增,主键
                  2.cname,课程名称,长度为50的字符串,允许为空
作业:
    1.创建数据库 Blog
    2.分析login 以及 regsiter 的业务,并得出 用户实体类
    3.根据分析出来的用户实体,创建实体类(属性),并映射回数据库


表名: users
类名: Users

聚集索引 和 非聚集索引

"a.jpg".split('.')[1]    

Day05-模型类-映射管理(CRUD)

1.模型类的映射管理

1.什么是映射管理
    对模型类/实体类的修改允许再映射回数据库
2.依托于第三方库完成管理
    1.flask-script
        pip3 install flask-script
        包:flask_script
        类:Manager
            作用:可以对项目进行管理,如:启动项目,添加命令
    2.flask-migrate
        pip3 install flask-migrate
        包:flask_migrate
        类:
            1.Migrate
                作用:用于管理 app 和 db 之间的协调关系
            2.MigrateCommand
                作用:允许在终端中提供实体类迁移的命令
3.实现数据库的迁移
    1.python3 run01.py db init
        作用:做一些初始化的行为操作
        特点:一个项目中只执行一次就可以了
    2.python3 run01.py db migrate
        作用:将编写好的实体类生成中间文件
        特点:只要检测到实体类有修改,就会生成中间文件
    3.python3 run01.py db upgrade
        作用:将中间文件映射回数据库

2.ORM中的CRUD

1.增加 - C(Create)
    1.创建实体的对象,并为属性赋值
        user = User()
        user.uname = 'wangwc'
        user.age = 18
    2.将实体对象增加回数据库
        db.session.add(实体对象)
        #针对非查询操作,必须要手动提交回数据库
        db.session.commit()
    3.配置操作自动提交
        针对所有非查询操作
        配置成功后,会在执行完视图之后,整体将行为提交回数据库
        app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True
2.查询 - R(Retrieve)

​ 1.基于 db.session 的查询

    1.db.session.query()
        该函数会返回一个Query对象,类型为BaseQuery
        该返回值中会包含针对某个实体或实体中的列所有的查询操作
        语法:
            1.db.session.query(实体类)
                查询对应实体类中所有列的数据
                ex:
                    db.session.query(User)
                    等同于:select * from user
            2.db.session.query(实体类.属性1,实体类.属性2)
                查询对应实体类中部分列的数据
                ex:
                    db.session.query(User.id,User.uname)
                    等同于:select user.id,user.uname from user
     2.查询执行函数
        目的:在query()的基础上的得到最终的数据
        语法:db.session.query(xxx).查询执行函数()
        函数                  说明
        all()          以列表的方式返回query()中所有的数据
        first()        以实体对象的方式返回query()中的第一条数据,如果没有结果,则返回None
        first_or_404() 效果同上,如果查询不到数据,则响应404
        count()        返回查询结果的数量
     3.查询过滤器函数
        作用:在db.session.query()的基础上,进行条件筛选
        语法:db.session.query().查询过滤器函数().查询执行函数()
        过滤器函数               说明
        filter()            按指定条件进行过滤
        filter_by()         按等值条件过滤时使用
        limit()             获取前几行数据
        order_by()          排序
        group_by()          分组
        过滤器函数的详解:
    1.filter()
    作用:实现查询中的各种条件
    注意:条件必须由 实体类.属性 构成
        1.查询年龄大于17的user的信息
        db.session.query(User).filter(User.uage>17).all()
        2.查询年龄大于17并且id大于1的user的信息
        db.session.query(User).filter(User.uage>17,User.id>1).all()
        3.查询年龄大于17或者id大于1的user的信息
        注意:查询 或 的操作,要借助于 or_()
        用法:or_(条件1,条件2)
        db.session.query().filter(or_(xxx)).all()
        4.查询id的值为2的user的信息
        注意:等值判断要用 == 
        db.session.query().filter(User.id==2).first()
        5.查询uemail中包含 w 的user的信息
        select * from user where uemail like '%w%'
        注意:模糊查询like需要使用实体类的属性所提供的like()完成查询
        db.session.query(User).filter(User.uemail.like('%w%')).all()
        6.模糊查询 - in
        注意:模糊查询in需要使用实体类的属性所提供的in_()完成查询
        db.session.query(User).filter(User.uage.in_([15,17,19])).all()
        7.模糊查询 - between and
        注意:模糊查询between and 需要使用实体类的属性所提供between(值1,值2)完成查询
        db.session.query(User).filter(User.uage.between(13,15)).all()
     2.filter_by()
        作用:只做等值条件筛选过滤,并且只用于单表查询
        特点:
        1.不用 实体类.属性名,直接使用 属性名即可
        2.不用 == ,而用 = 
        db.session.query(User).filter_by(id=1).first()
    3.limit()
        作用:获取前几行数据
        语法:db.session.query(User).limit(num).all()
        1.db.session.query(User).limit(1).all()
        获取前1条数据
        2.使用 offset() 可以完成数据的偏移
        db.session.query(User).limit(2).offset(3).all()
        跳过前3条数据,再获取剩余的前2条数据
    4.order_by()
        1.User表中的数据按id降序排序
        db.session.query(User).order_by("id desc")
        2.User表中的数据按年龄升序排序,id降序排序
        db.session.query(User).order_by("age,id desc")
        练习:
            1.访问路径 /03-queryall
            2.能够渲染 03-queryall.html 模板
            3.在模板中显示
            用表格显示以下内容:
            id    姓名    年龄    邮箱    操作
            1     wangwc  16     xxxx@163  删除 修改
            2     Rapwang 18     xxxx@163  删除 修改
select * from user limit 2,3

会话

ID:xxx 姓名:xxxx 年龄:xxxx 邮箱:xxxx
ID:xxx 姓名:xxxx 年龄:xxxx 邮箱:xxxx          

Day06

1.增加

1.创建实体对象
2.通过db.session.add()
3.提交 
    1.手动提交
        db.session.commit()
    2.自动提交
        app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True

2.查询

1.基于 db.session 的查询
    1.db.session.query()
        会返回一个query对象,类型BaseQuery
        语法:
        db.session.query(实体类|实体类.属性)
    2.查询执行函数
        作用:在基础查询上得到想要的数据
        函数:
            1.all()
            2.first()
            3.first_or_404()
            4.count()
    3.查询过滤器函数
        db.session.query().查询过滤器().查询执行函数()
        1.filter()
            1. filter(User.id==1)
            2. filter(User.id>1)
            3. filter(User.id>1,User.age>30)
            4.from sqlalchemy import or_ 
              filter(or_(User.id>1,User.age>30))
            5.filter(User.name.like('王%'))
            6.filter(User.addr.in_(['北京','上海','天津','重庆']))
            7.filter(User.age.between(35,50))
        2.filter_by()
            filter_by(id=1)
        3.limit()
            db.session.query().limit(2).offset(5)
            db.session.query().filter().limit().offset()
        4.order_by()
            db.session.query().order_by("id,age desc")
            db.session.query().filter().order_by()
2.基于 实体类 的查询            

====================================================

2.查询 - R(Retrieve)
1.查询 - R
1.聚合查询
    1.基本聚合查询
        from sqlalchemy import func
        # func对象中提供了所有的聚合函数
        db.session.query(func.聚合函数(实体类.属性)).all()
            聚合函数:
                sum() : 求和
                count() : 求非空的数量
                max() : 求最大值
                min() : 求最小值
                avg() : 求平均值
        #查询user表中所有人的平均年龄(uage)是多少??
        db.session.query(func.avg(User.uage)).first()           
    2.分组聚合查询
        db.session.query(聚合).group_by('属性名').all()
        练习:
        1.为 User 实体类增加一个属性 isActive(为user表增加一个列isActive),默认值为True
        2.到数据库中随意修改几条数据的 isActive 的值为False
        3.在程序中实现,统计被激活的用户数量以及未被激活的用户数量分别是多少并打印输出
            被激活: isActive = True
    3.带条件的分组聚合
        db.session.query(聚合).filter(条件).group_by(分组).having(分组后条件)
        ex:
            在 user 表中要统计大于16岁的用户的激活人数和未激活人数,并输出大于2人的信息                  
                
2.基于实体类进行查询
            MODELS.query.查询过滤器函数(条件参数).查询执行函数()
            ex:查询user表(User类)中所有的数据
            1.使用 db.session
                db.session.query(User).all()
            2.使用 实体类
                User.query.all()
            ex:查询id为1的user的信息
            1.使用db.session
                db.session.query(User).filter_by(id=1).first()
            2.使用 实体类
            User.query.filter_by(id=1).first()
                User.query.filter(User.id==1).first()
2.修改 - U(Update)

​ 1.查 将要修改的信息查询出来 2.改 通过实体对象.属性 = 值 3.保存 db.session.add(实体对象)

3.删除 - D(Delete)

​ 1.查 查询出要删除的实体对象 2.删 db.session.delete(要删除的实体对象)

4.重定向 - redirect()

​ 重定向:在服务器端,指定重新向一个新的地址发送请求

5.关系映射

​ 1.一对多

    1.什么是一对多
        A表中的一条数据能够关联到B表中的多条数据
        B表中的一条数据能够关联到A表中的一条数据   
        ex:
            1.博客系统中的用户与发表的文章
                1个用户允许发表多篇文章
                1篇文章只能由一个用户发表
            2.老师(Teacher) 与 课程(Course)
                1名老师只能教授一门课程
                一门课程可以被多名老师所教授
                课程(1) : 老师(M)
    2.一对多在数据库中的实现
        依托于 主外键 关系创建
        在"多"表中增加外键 要 引用自"一"表的主键依托于 主外键 关系创建
        在"多"表中增加外键 要 引用自"一"表的主键
    3.在 Flask-SQLAlchemy 上的实现
        在"多"实体类中增加对"一"实体类的引用
        1.在 "多" 实体类中:
            增加一个列,引用自"一"表(类)的主键
            外键列名=db.Column(db.Integer,db.ForeignKey('主键表.主键列'))

            ex: 模拟 Course(1) 类 与 Teacher(多) 类
        2.在"一"实体类中:
            增加关联属性以及反向引用关系属性(难点)
                
            1.关联属性:
                在"一"的实体中,要通过哪个<<属性>>来获取到对应的所有的"多"的实体对象们
            2.反向引用关系属性:
                在"多"的实体中,要通过哪个<<属性>>来获取对应的"一"的实体的对象
                
            语法:
                属性名=db.relationship('多实体类名',backref='反向引用关系属性名称',lazy='dynamic')
            ex:
                class Teacher(db.Model):
                    xxxx xxxx
                    course_id = db.Column(
                        db.Integer,
                        db.ForeignKey('course.id')
                    )

                class Course(db.Model):
                    xxx xxx
                    #增加关联属性以及反向引用关系属性
        teachers=db.relationship('Teacher',backref='course',lazy='dynamic')

​ 2.一对一 3.多对多

course = Course.query.filter_by(id=1)
可以通过 course.teachers 来得到对应的所有的老师的信息

SELECT user.`isActive` AS `user_isActive`, count(user.`isActive`) AS count_1 
FROM user 
WHERE user.uage > %(uage_1)s GROUP BY user.`isActive` 
HAVING count(user.`isActive`) > %(count_2)s
select xxxxxx 
from xxx
where
group by xxx
having xxx

#查询user表中所有的用户的年龄(uage)的和是多少
select sum(uage) as 'sumAge',avg(uage) as 'avgAge' from user
select  uid,uname,uemail,uage > (select uage from xxx where ...) from user
inner join course on xxx where xxx

[
    (Decimal('16.0000'), Decimal('16')), 
    (Decimal('18.0000'), Decimal('18')), 
    (Decimal('38.0000'), Decimal('114'))
]

[
    (16, Decimal('16.0000'), Decimal('16')), 
    (18, Decimal('18.0000'), Decimal('18')), 
    (38, Decimal('38.0000'), Decimal('114'))
]

Day07

1.关系映射

1.一对多映射
    在Flask中:
    1.在"多"类增加一个属性,表示对"一"类进行引用
        属性 = db.Column(db.Integer,db.ForeignKey("主表.主键"))
    2.在"一"类增加关联属性和反向引用关系属性
        如:Course类(course表) 和 Teacher类(teacher表)
        关联属性:在Course类中增加的一个属性,表示对应的所有的Teacher对象
        反向引用关系属性:在Teacher类中增加一个属性,表示对应的Course对象是谁
        属性名=db.relationship(
            "多类名",
            backref="反向引用关系属性名",
            lazy="dynamic"
        )
        lazy : 指定延迟加载模式,指定如何加载关联数据
            1.select
                首次访问时,加载关联数据
            2.immediate
                源对象使用后,马上加载关联数据
            3.subquery
                效果同上,但是会使用子查询的方式加载关联数据
            4.noload
                永不加载记录
            5.dynamic
                默认不加载记录,但会提供加载记录的查询
        class Course(db.Model):
            __tablename__ = "course"
            id = db.Column(db.Integer,primary_key=True)
            xxxx  xxxx
            #关联属性和反向引用关系属性
            teachers = db.relationship(
                "Teacher",
                backref='course',
                lazy="dynamic")
        
        class Teacher(db.Model):
            __tablename__ = "teacher"
            xxxx  xxxx
            #外键引用
            course_id = db.Column(db.Integer,db.ForeignKey('course.id'))
2.一对一映射
1.什么是一对一
    A表中的一条记录只能与B表中的一条记录相关联
    B表中的一条记录只能与A表中的一条记录相关联
2.在数据库中的体现
    关联的两张表的任意一张表中:
    增加外键,引用自另外一张表的主键,并施加唯一约束
3.在实体类中的体现
    1.在任意一个类中增加:
        外键列名=db.Column(db.Integer,db.ForeignKey('主表.主键'),unique=True)
            
            class User(db.Model):
                __tablename__ = "user"
                xxxx xxxx
            
            class Wife(db.Model):
                __tablename__ = "wife"
                xxxx xxxx
                user_id=db.Column(db.Integer,db.ForeignKey('user.id'),\
            unique=True)
   
    2.在另外一个实体类中增加:  
        关联属性 和 反向引用关系属性
        属性 = db.relationship(
            "关联的实体类",
            backref="反向引用关系属性名称",
            uselist=False
        )

        uselist : 该属性将使用标量来表示,而不是列表

        class User(db.Model):
            __tablename__ = "user"
            xxxx xxxx
            wife = db.relationship("Wife",backref="user",uselist=False)
                
        class Wife(db.Model):
            __tablename__ = "wife"
            xxxx xxxx   
            user_id=db.Column(db.Integer,db.ForeignKey('user.id'),\
unique=True)
练习:完成一对一的查询操作

#####

Day08

1.关系映射

​ 1.一对多关系映射 2.一对一关系映射

class User(db.Model):
    xxxx 
    wife=db.relationship("Wife",backref="user",uselist=False)
class Wife(db.Model):
    xxxx
    user_id=db.Column(db.Integer,db.ForeignKey('user.id'),unique=True)
3.多对多关系映射
    1.什么是多对多
        A表中的一条数据可以与B表中的任意多条数据相关联
        B表中的一条数据可以与A表中的任意多条数据相关联
    2.在数据库中的体现
        在数据库中使用第三张关联表
    3.在Flask-SQLAlchemy中的实现
        1.创建关联表(实体类)
            class TeacherStudent(db.Model):
                __tablename__ = "teacher_student"
                id=db.Column(db.Integer,primary_key=True)
                teacher_id=db.Column(db.Integer,db.ForeignKey
('teacher.id'))
                student_id=db.Column(db.Integer,db.ForeignKey
('student.id'))
        2.增加关联属性 和 反向引用关系属性
            class Teacher(db.Model):
                __tablename__ = "teacher"
                xxx xxx
                students = db.relationship(
                    "Student",
                    secondary="teacher_student",
                    lazy="dynamic",
                    backref=db.backref("teachers",lazy="dynamic")
                )

2.cookies / cookie

​ 1.什么是cookies cookies是一种数据存储手段 将一段文本保存在客户端(浏览器)的一种存储手段,并可以长时间保存 2.cookies的使用场景 1.记住密码 2.记住搜索关键词 3.特点

    1.cookies是以浏览器为单位,不同的浏览器之间的cookies是不共享的
    2.各个网站之间的cookies也是相互独立的,不共享
    优点:
        1.可以解决服务器端的一些存储问题
            允许将非重要的数据保存在客户端浏览器中,从而节省服务器端的位置
        2.可以长时间保存数据
    缺点:
        1.明文显示所有的数据
        2.cookie中的内容在客户端是允许被修改的

​ 3.Flask中使用 cookies

    1.保存cookies
        要通过 响应对象 将cookies从服务器端带到浏览器上
        响应对象:
            1.resp = redirect('/重定向地址')
                    resp 是一个响应对象
            2.from flask import make_response
                    resp = make_response("字符串"|render_template())
                    resp 是一个响应对象
                    return resp
        添加cookies的语法
            响应对象.set_cookie(key,value,max_age)
                key:要保存的cookie的名称
                value:要保存的cookie的值
                max_age:该cookie存活的最大时间(以s为单位,但s省略不写)
                    1. 1 表示1秒
                    2. 60 表示1分钟
                    3. 60*60 表示1小时
                    4. 60*60*24 表示1天
                    5. 60*60*24*365 表示1年
        ex:
            from flask import make_response
            @app.route('/01-addcookie')
            def addcookie_views():
                resp=make_response("添加cookie成功")
                resp.set_cookie("uname","wangwc",60*60*24*365)
                return resp
    2.获取cookies
        每当浏览器向服务器发送请求时,都会把当前站点的cookies们都封装到request中并带到服务器上
        语法:
            request.cookies
    3.删除cookies
        响应对象.delete_cookie('key')

3.session - 会话

​ 1.什么是session session是保存在服务器上,为每个浏览器所开辟的一段空间 2.保存进session的数据 服务器端在会话过程中经常要用到的数据要保存进session 3.session在Flask中的实现手段

    1.配置 SECRET_KEY
        app.config['SECRET_KEY']='aixieshaxiesha'
    2.使用session
        from flask import session
        1.保存数据到session中
            session['key'] = value
        2.从session中获取数据
            value=session['key']
            value=session.get('key')

            if 'key' in session:
                xxxx xxxx
        3.从session中删除数据
            del session['key']
{
    'csrftoken': 'HCDh1rsAlRRvdc3T9grSbW2nLGtZT8Ih6Ljqm0zvkEKnVfFS9pEpC0rD5MzBPtjy', 
    'uname': 'wangwc', 
    'Pycharm-b723704f': '18dbae5b-b244-47d1-80f5-c6ea522f3ef9'
}

resp = redirect('/')
return resp

1.登录流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VGJ3ijJp-1603206326262)(C:\Users\Administrator\Desktop\python复习\登录流程_看图王.png)]

2.练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sf94QwDI-1603206326265)(C:\Users\Administrator\Desktop\python复习\练习1-cookie_看图王.png)]

3.练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHL9JjyH-1603206326266)(C:\Users\Administrator\Desktop\python复习\练习2-session_看图王.png)]

Day09

1.AJAX

1.什么是AJAX
    Asynchronous Javascript And Xml
    Asynchronous : 异步的
    Xml : eXtensible Markup Language
            可扩展的标签语言
    JSON:JavaScript Object Notation,用来取代繁琐的xml
    解释:通过JS异步的向服务器发送请求,并接收响应回来的XML(JSON)格式的数据
    同步请求:
        当客户端向服务器发送请求时,服务器在处理的过程中,浏览器只能等待,效率低
    异步请求:
        当客户端向服务器发送请求时,服务器在处理的过程中,客户端可以做其他的操作,不需要一直等待
    AJAX优点:
        1.异步 访问
        2.局部 刷新
    使用场合:
        1.搜索建议
        2.表单验证
        3.前后端完全分离
2.AJAX核心对象 - 异步对象
    1.异步对象 - XMLHttpRequest
        简称为 xhr
        称为"异步对象",代替浏览器向服务器发送异步的请求并接收响应
    2.创建异步对象
        主流的异步对象是 XMLHttpRequest 类型的,并且主流的浏览器(IE7+,Chrome,Firefox,Safari,Opera)全部都支持XMLHttpRequest。但在IE低版本的浏览器中(IE7以及以下),就不支持XMLHttpRequest。使用 ActiveXObject() 来创建异步对象

        支持XMLHttpRequest:
            var xhr = new XMLHttpRequest();
        不支持XMLHttpRequest:
            var xhr = new ActiveXObject("Microsoft.XMLHTTP");
    练习:根据不同的浏览器支持性创建不同的异步对象
        1.声明一个方法 - createXhr()
        2.方法中判断浏览器支持 XMLHttpRequest 还是 ActiveXObject
        3.根据支持性创建不同的异步对象并返回

11、Pythonweb-后端框架-Django

Day01

Django

1.Django框架的介绍

2005年发布,采用Python语言编写的开源框架
早期的时候Django主要做新闻以及内容管理的网站
Django中自带强大的后台管理功能
版本:2.1.5
使用:1.11

官网:http://www.djangoproject.com
中文文档:http://djangobook.py3k.cn/2.0/

2.Django的框架模式

MTV:
    M -- Models
    T -- Templates
    V -- Views

3.Django的安装

1.查看已安装的版本
    1.进入到python交互模式
        python3 / ipython3
    2.输入 import django
    3.输入 django.VERSION
2.安装
    使用 pip3 
        pip3 install django
        (安装Django的最新版本)     
        pip3 install django==1.11.8
        (安装Django的指定版本)

4.Django框架的使用

1.创建项目的指令
2.Django项目的目录结构
1. 创建项目的指令
    指令:django-admin
    语法:django-admin startproject 项目名
2.Django项目的目录结构
    1.manage.py
    功能:包含项目管理相关的子命令
        如:
            启动服务:runserver
            创建应用:startapp
            创建管理员:createsuperuser
            数据迁移:migrate
            .... ....
    2.主文件夹(与项目名称一致的文件夹)
        1. __init__.py
            项目初始化文件,服务启动时自动运行
        2.wsgi.py
            Web服务网关接口的配置文件
            部署项目时使用
        3.urls.py
            项目的基础路由配置文件
            所有动态路径必须走该文件进行匹配
        4.settings.py
            功能:项目的主配置文件,启动服务时自动调用
            1.BASE_DIR
                作用:表示当前项目的绝对路径
            2.DEBUG
                作用:是否启用条用模式
                取值:
                    1.True
                        使用调试模式
                        (开发阶段推荐使用)
                    2.False
                        不使用调试模式
                        (生产环境中要使用)
            3.ALLOWED_HOSTS
                作用:设置允许访问到本项目的地址列表
                取值:
                    1.如果为空
                        表示只有localhost或127.0.0.1能访问
                    2.['*']
                        任何表示本机的地址都能访问当前项目
                        如:
                            localhost / 127.0.0.1 / 0.0.0.0 / IP地址
                        注意:如果要在局域网内被访问的话
                            ./manage.py runserver 0.0.0.0:端口号
            4.INSTALLED_APPS
                作用:指定已安装的应用
            5.MIDDLEWARE
                作用:注册中间件
            6.TEMPLATES
                作用:指定模板的配置信息
            7.DATABASES
                作用:指定数据库的配置信息
            8.LANGUAGE_CODE
                作用:指定语言设置
                取值:中文:zh-Hans
            9.TIME_ZONE
                作用:指定时区
                取值:中国时区:Asia/Shanghai

5.URL的使用

1.urls.py
    默认在主文件夹中,主路由配置文件,包含最基本的路由-视图的映射关系
    该模块文件中会包含 urlpatterns 的列表,用于描述路由-视图的映射
    在urlpatterns中,通过若干 url() 来表示具体的路由-视图映射关系
2.url() 的语法
    from django.conf.urls import url
    语法:
        url(regex,views,kwargs=None,name=None)
            1.regex:字符串类型,匹配的请求路径,可以是正则
            2.views:指定地址所对应的视图处理函数的名称
            3.kwargs:向views传参
            4.name:为url起别名,在地址反向解析时使用
3.带参数的url   
    http://localhost:8000/show-02/2019
    http://localhost:8000/show-02/1996
    使用正则表达式的子组进行传参 - ()
    一个子组是一个参数,多个参数的话要使用多个子组,并且使用 / 隔开

    http://localhost:8000/show-02/xxxx
    xxxx表示的是四位数字
    urlpatterns = [
        url(r'^show-02/(\d{4})/$',views.show_02)
    ]

    def show_02(request,year):
        year:表示的就是地址中的第一个子组对应的参数


练习:
    访问地址: http://localhost:8000/show_03/四位整数/两位整数/两位整数
    最终输出:生日为:xxxx年xx月xx日

    ex: http://localhost:8000/1977/11/11
    最终输出:生日为:1977年11月11日

6.Django中的应用 - app

1.什么是应用
    应用是WEB项目中的一个独立的业务模块,可以包含自己的路由,视图,.... ....
    在Django中,主文件夹不再处理用户的具体请求。主文件夹的主要工作就是项目的初始化以及请求的分发(分布式请求处理),具体的请求由应用(app)进行处理的
2.创建 & 配置应用
    1.创建应用的指令
        ./manage.py startapp 应用名称
        ex:
            ./manage.py startapp music
    2.配置应用
        在 settings.py 中进行应用的注册
        INSTALLED_APPS = [
            ... ...,
            '自定义的应用名称'
        ]
    3.应用的结构组成
        1.migrations 文件夹
            保存数据迁移的中间文件
        2.__init__.py
            应用的初始化文件
        3.admin.py
            应用的后台管理配置文件
        4.apps.py
            应用的属性配置文件
        5.models.py
            与数据库相关的模型映射类
        6.tests.py
            应用的单元测试文件
        7.views.py
            定义视图处理函数的文件
    4.分布式路由系统
        如果访问路径是:
        http://localhost:8000/music/xxx
        则将请求转交给music应用中的urls进一步处理
作业:
    1.创建一个Django项目 - DjangoDemo01
    2.创建以下应用们,并注册:
        1.创建 index 应用
        2.创建 music 应用
        3.创建 sport 应用
        4.创建 news  应用
    3.创建分布式路由访问系统
        主文件夹只做路由的分发
        每个应用只处理与自己相关的业务(路由和视图)
    1.localhost:8000/index/index 
        交给 index 应用中的 index() 函数处理
    2.localhost:8000/music/index
        交给 music 应用中的 index() 函数处理
    3.localhost:8000/sport/index
        交给 sport 应用中的 index() 函数处理
    4.localhost:8000/news/index
        交给 news  应用中的 index() 函数处理

Day02

1.路由系统

1.路由改版
    访问路径 :localhost:8000/music/index
    改版路径 :localhost:8000/music/
        访问 index() 视图处理函数

    访问路径 :localhost:8000/index/index
    改版路径 :localhost:8000/
        访问 index 应用中的 index()视图函数
        
    访问路径 :localhost:8000/login
        访问 index 应用中的 login()视图函数
        
    访问路径 :localhost:8000/register
        访问 index 应用中的 register()视图函数

2.Django中的模板 - Templates

1.Django中的模板
    Django中的模板引擎是由Django自己提供,并不是Jinja2,索引Django中的模板语法与      Flask中的模板语法会稍有不同
2.模板的配置
    在 setting.py 中有一个 TEMPLATES 变量
    1.BACKEND:指定模板的引擎
    2.DIRS:指定存放模板的目录们
        1.如果写东西:则按照写好的路径去查找模板
        2.保存为空:Django会自动的到每个应用中的templates目录中去查找模板文件

        推荐:'DIRS': [os.path.join(BASE_DIR, 'templates')]
    3.APP_DIRS
        是否要搜索应用中的指定名称的目录们
3.模板的加载方式
    1.通过loader获取模板,通过HttpResponse响应
        from django.template import loader

        #1.通过 loader 加载模板
        t = loader.get_template("模板名称")
        #2.将模板转换成字符串
        html = t.render()
        #3.再通过HttpResponse进行响应
        return HttpResponse(html)
    2.使用 render() 直接加载并响应模板
        from django.shortcuts import render
        return render(request,'模板的名称')
    4.模板的语法
        1.变量
            1.作用
                传递后端的数据到模板上进行显示
            2.允许做为变量的数据类型
                字符串,数字,列表,元组,字典,函数,对象
            3.变量的语法
                变量必须封装到字典中才允许传递到模板上
                dic = {
                    "变量1":"值1",
                    "变量2":"值2",
                    ... ...
                }
                1.使用 loader 加载模板
                    t=loader.get_template('xxx.html')
                    html=t.render(dic)
                    return HttpResponse(html)
                2.使用 render 渲染模板
                    return render(request,'xxx.html',dic)
             4.在模板中使用变量:{{变量名}}
        2.标签
             1.作用
                将服务器端一些功能嵌入到模板中
             2.语法
                {% 标签内容 %}
                {% 结束标签 %}
                1.for 标签
                    1.语法:
                        {% for 变量 in 可迭代变量 %}
                        {% endfor %}
                    2.内置变量 - forloop
                        1. forloop.counter
                            得到当前循环遍历的次数
                        2. forloop.counter0
                            得到当前循环遍历的下标
                        3. forloop.first
                            是否为第一次循环
                        4. forloop.last
                            是否为最后一次循环
                2.if 标签
                    1.作用
                        在模板中完成判断的操作
                    2.语法
                        1. if 
                            {% if 条件 %}
                                满足条件时执行的内容
                            {% endif %}
                        2. if ... else
                            {% if 条件 %}
                                满足条件执行的内容
                            {% else %}
                                不满足条件时执行的内容
                            {% endif %}
                        3. if ... elif ... else
                            {% if 条件1 %}
                            {% elif 条件2 %}
                            {% elif 条件3 %}
                            {% else %}
                            {% endif %}
        3.过滤器
            1.作用: 在变量输出前对变量的值进行筛选或过滤
            2.语法: {{变量|过滤器:参数值}}
            3.常用过滤器
4.静态文件
        4.静态文件
            1.静态文件的配置
                在 settings.py 中设置以下两点:
                1.静态文件访问路径
                    通过哪个地址访问静态的资源们
                    STATIC_URL = '/static/'
                    static 就是访问静态资源的路径
                2.静态文件存储路径
                    指定静态文件要存放在服务器的哪个目录
                    STATICFILES_DIRS=(os.path.join(BASE_DIR,'static'),)
            2.访问静态文件
                1.使用 静态文件访问路径 进行访问
                    http://localhost:8000/static/xxxx
                    ex:
                        <img src="http://localhost:8000/static/images/b04.jpg">

                        <img src="/static/images/b04.jpg">
                2.使用{% static %}进行访问
                    {% static %} 表示的就是静态资源访问路径

                    1.加载 static
                        {% load static %}
                    2.使用静态资源时
                        <img src="{%%20static%20'images/a.jpg'%20%}"> 
练习:
    1.创建Django项目 - FruitDay
    2.创建应用 - index 
    3.配置路由
        http://localhost:8000/xxxx 
        一律交给index的路由做进一步的处理
    4.将html阶段中
        将 果园的首页,登录页 以模板的方式设置到 FruitDay项目中以及配置好所有的静态文件
    5.
        首页:http://localhost:8000
        登录:http://localhost:8000/login/
5.模板的继承
        5.模板的继承
            1.语法
                1.在父模板中
                    要标识出哪些内容在子模板是允许被修改的
                    {% block 块名 %}
                    {% endblock %}

                    block作用:
                        1.在父模板中,正常显示
                        2.在子模板
                            不重写,采用父模板中的效果
                            重写,则按照重写的效果显示
                2.在子模板中
                    1.指定继承自哪个模板
                        {% extends '父模板名称' %}
                    2.重写父模板中的内容
                        {% block 块名 %}
                        {% endblock %}                   
6.url()的name参数
        6.url()的name参数
            1.url的语法
                url(regex,views,kwargs,name='别名')
                name:为了给当前的url起别名,反向解析时使用

                url(r'^user_login/$',views.login,name='log')
            2.反向解析
                1.在模板上做反向解析
                    {% url '别名' %}
                    {% url '别名' '参数1' '参数2' %}
                2.使用场合
                    1.访问路径过长时,推荐使用别名访问
                    2.访问地址经常变换时,推荐使用别名    

Day03

1.模型 - Models

1.ORM框架
    ORM :Object Relational Mapping
    三大特征:
        1.表 到 类的映射
        2.数据类型的映射
        3.关系映射
2.创建 和 配置数据库
    1.创建数据库
        create database webdb default charset utf8 collate utf8_general_ci;
    2.Django中的数据库配置
        settings.py中找到DATABASES变量
        DATABASES = {
            'default': {
                    'ENGINE': 'django.db.backends.sqlite3',
                    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
            }
        }
        1.ENGINE
            指定数据库引擎,mysql引擎如下:
            'ENGIN':'django.db.backends.mysql'
        2.NAME
            指定要连接的数据库的名称
            'NAME':'webdb'
        3.USER
            指定登录到数据库的用户名称
            'USER':'root'
        4.PASSWORD
            指定登录到数据的用户密码
            'PASSWORD':'123456'
        5.HOST
            指定要连接到的主机地址
            'HOST':'localhost'
        6.PORT
            指定要连接到的主机的端口号
            'PORT':3306

    3.Django中的数据库迁移
        1. ./manage.py makemigrations
            作用:
                将每个应用下的models.py文件生成一个中间迁移文件,并将中间文件保存在      migrations的目录中
        2. ./manage.py migrate
            作用:
                将每个应用下migrations目录中的中间文件同步回数据库
    4.编写Models
        1.编写示例
            见代码 
        2.Models的语法规范    
        class CLASSNAME(models.Model):
            NAME=models.FIELDTYPE(FIELDOPTIONS)
        1.CLASSNAME
            实体类名称,表名组成的一个部分
            默认表名组成规范:
                应用名称_CLASSNAME
        2.NAME
            属性名,映射回数据库就是字段名称
        3.FIELDTYPE
            字段类型:映射到表中的字段的类型
            1.BooleanField()
                编程语言中使用True或False表示该列值
                数据库中使用 1 或 0 表示具体的值
                数据类型为:tinyint
            2.CharField()
                数据类型为:varchar
                注意:
                    必须要指定max_length参数值
            3.DateField()
                编程语言中使用字符串来表示该列值
                数据库中使用的日期来表示
                数据类型为:date
            4.DateTimeField()
                数据类型为:datetime
            5.DecimalField()
                编程语言中使用小数表示该列的值
                数据库中使用定点小数表示值
                数据类型:decimal
                    money=models.DecimalField
(max_digits=7,decimal_places=2)     
            6.FloatField()
                数据库以及编程语言中都使用小数表示
                数据类型为:float
            7.EmailField()
                编程语言中使用字符串表示该列的值
                数据库中也是字符串
                数据类型为:varchar
            8.IntegerField()
                编程语言和数据库中都使用整数
                数据类型为:int
            9.URLField()
                编程语言和数据库中都使用字符串
                数据类型为:varchar
            10.ImageField()
                存储图片的路径
                编程语言和数据库中都是用字符串
                image=models.ImageField(upload_to='image/users/')
                注意:
                    必须指定上传路径
                    所以在后台上传时会自动的将文件保存在指定目录处
        4.FIELDOPTIONS
            字段选项,指定创建列的额外信息
            1.primary_key
                如果设置为True,表示该列为主键
            2.null
                如果设置为Ture,表示该列允许为空
                默认为False
            3.default
                设置所在列的默认值
            4.db_index
                如果设置为True,则为所在列添加索引
            5.unique
                如果设置为True,表示所在列的值要唯一
            6.db_column
                指定映射到列的列名,如果不指定的话则采用属性名称作为列名
    练习:
        在 index 应用中再追加两个model类
        1.Author - 作者
            1.name - 姓名
            2.age - 年龄
            3.email - 邮箱(允许为空)
        2.Book - 图书
            1.title - 书名
            2.publicate_date - 出版时间

    5.相关指令
        1.通过数据库自动导出models
            ./manage.py inspectdb > 文件名.py
        2.数据的版本切换
            1. ./manage.py migrate
                执行所有应用中最新版本的数据库迁移文件
            2. ./manage.py migrate 应用名称 版本号
                ./manage.py migrate index 0001
3.数据的CRUD
    1.增加数据
        1.Entry.objects.create(属性=值,属性=值)
            返回值:返回创建好的实体对象
        2.创建 Entry 的对象,并调用save()进行保存
            obj = Entry(属性=值,属性=值,...)
            obj.属性=值
            obj.save()
            无返回值,保存成功后,obj会被重新赋值
        3.使用字典创建对象,并调用save()进行保存
            dic = {
                '属性1':"值1",
                '属性2':"值2",
                ... ...
            }
            obj=Entry(**dic)
            obj.save()
练习:
    使用以上三种方式,向Book和Publisher表中各增加至少三条数据
2.查询数据(重点)
    通过 Entry.objects 属性调用查询接口
    ex:
        Entry.objects.all()
        Entry.objects.filter()
        Entry.objects.values()
        .... ....
        1.基本查询操作
            语法:all()
            用法:Entry.objects.all()
            作用:查询Entry实体中所有行所有列的记录
                SQL:select * from Entry 
            返回:QuerySet
                1.所有的QuerySet都可以通过query属性得到对应的SQL语句
                2.所有的QuerySet都可以当成列表操作
        2.查询返回指定列
            语法:values() | values('列1','列2',)
            用法:
                Entry.objects.values('列1','列2')
                Entry.objects.all().values('列1','列2')
            返回值:QuerySet
                会将查询出来的数据封装到字典中再封装到列表中
        3.查询返回指定列
            语法:values_list('列1','列2')
            用法:
                Entry.objects.values_list()
                Entry.objects.all().values_list()
            返回:QuerySet
                会将查询出来的数据封装到元组中再封装到列表中    
    练习:
        1.创建路由 /03-queryall
        2.查询Author实体中所有的数据
            并渲染到03-queryall.html模板上
        3.在03-queryall.html模板上
            显示所有的数据
            姓名 年龄 邮箱 操作
            xx   xx   xxx  删除 修改
        4.根据条件查询部分行数据(重难点)
            语法:filter(条件)
            用法:Entry.objects.filter(条件)
            返回:QuerySet
            ex:
                1.查询id为1的Author的信息
                    authors=Author.objects.filter(id=1)
                2.查询publicate_date为2018-10-12的Book的信息
                    books=Book.objects.filter(publicate_date='2018-10-12')
                3.查询id为1并且publicate_date为2018-10-12的Book的信息
                    books=Book.objects.filter(id=1,publicate_date='2018-10-12')
            如果要非等值查询条件,需要使用查询谓词
            Django:Field Lookup
            查询谓词:是一个独立的查询功能
                语法:filter(属性__查询谓词=值)
                ex:
                    __exact : 等值匹配
                    __contains : 包含指定值
                    __in : 在指定范围内的值
                    __gt : 大于指定值
                    __gte:
                    __lt :
                    __lte:
                    __startswith : 以 xx 作为开始
                    __endswith : 以 xx 作为结束
                    __range : 在指定区间范围
                    __date : 获取日期部分数据
                    __year : 获取年
                    __month
                    __day
                    .. ..
    练习:
        1.查询Author表中age 大于等于95的Author的信息
        2.查询Author表中所有姓"鲁"的人的信息
        3.查询Author表中Email中包含'sh'的人的信息
        4.查询Author表中Age大于"鲁迅"的age的人的信息
        5.不等的条件筛选
            语法:exclude(条件)
            用法:Entry.objects.exclude(条件)
        6.排序
            语法:order_by('列1','-列2')
            用法:Entry.objects.order_by('列')
            说明:
                默认是按升序排序,降序则在列前增加'-'即可
        7.查询只返回一条数据
            语法:get(条件)
            用法:Entry.objects.get(条件)
            注意:
                该方法必须只能返回一条数据
                返回多条数据:抛异常
                无数据返回  :抛异常
<QuerySet 
    [
        {'name': '莫言', 'id': 1, 'age': 65, 'email': 'moyan@163.com', 'isActive': True}, 
        {'name': '老舍', 'id': 2, 'age': 105, 'email': 'laoshe@163.com', 'isActive': True}, 
        {'name': '鲁迅', 'id': 3, 'age': 95, 'email': 'zhoushuren@163.com', 'isActive': True}, 
        {'name': '巴金', 'id': 4, 'age': 100, 'email': 'eightJin@163.com', 'isActive': False}
    ]

<QuerySet [
<Author: Author object>,
<Author: Author object>,
<Author: Author object>, 
<Author: Author object>]>

SELECT `index_author`.`id`, `index_author`.`name`, `index_author`.`age`, `index_author`.`email`, `index_author`.`isActive` FROM `index_author`

Day04

1.ORM 数据操作

1.查询
    1.聚合查询(不带分组)
        语法:aggregate()
        用法:Entry.objects.aggregate(名=聚合函数('列'))
            聚合函数()
                from django.db.models import Avg,Sum,Count,Max,Min
    2.聚合查询(带分组)
        语法:annotate()
        用法:
            Entry.objects
                .values('分组列名')
                .annnotate(名=聚合函数('列'))
                .values('查询列名')

    练习:
        1.查询 Book 表中共有本图书
            result = Book.objects.aggregate(count=Count('*'))
        2.查询 每个时间 所发布的书籍的数量
            Book.objects.values('publicate_date')
                .annotate(count=Count('*'))
        3.查询 2015 年之后所出版的图书数量
            Book.objects.filter(publicate_date__year__gte=2015)
.aggregate(count=Count('*'))
        4.查询 Publisher中,City为北京的出版社数量
            Publisher.objects.filter(city='北京').aggregate
(count=Count('*'))
2.修改
    1.修改单个实体
        1.查
            通过 get() 得到要修改的实体对象
        2.改
            通过得到的对象去修改属性值
            对象.属性=值
        3.保存
            通过对象.save()保存数据回数据库
    2.批量修改
        直接调用QuerySet的update(属性=值)实现批量修改
3.删除
    调用实体对象/查询结果集的 delete() 实现删除
    1.删除单个对象
        Author.objects.get(id=1).delete()
    2.批量删除
        Author.objects.filter(isActive=False).delete()
4.F查询 和 Q查询
    1.F查询 - F()
        1.作用:
            在执行操作过程中用于获取某列的值
        2.语法:
            from django.db.models import F
            F('列名')
        3.示例
            更新Author表中所有的数据的age都加10岁
            Author.objects.all().update(age=F('age')+10)
    2.Q查询 - Q()
        1.作用:
            在查询条件中来实现 or 的操作的
        2.语法:
            from django.db.models import Q
            Q(条件1)|Q(条件2)
        3.示例:
            查询Author表中id=1或age>=90的人的信息
            Author.objects.filter(Q(id=1)|Q(age__gte=90))
5.原生的数据库操作方法
    1.查询
        1.语法:
            raw(sql语句)
        2.用法
            Entry.objects.raw('sql')
        3.返回值
            QuerySet
    2.增删改
        from django.db import connection
        def doSQL(request):
            #更新index_author表所有数据的isActive=1
            with connection.cursor() as cursor:
                cursor.execute("update index_author set isActive=1")
            return ''

2.使用后台管理models

1.后台的配置
    登录地址:http://localhost:8000/admin
    使用指令创建后台管理员
    ./manage.py createsuperuser
2.基本的数据管理
    1.在应用中的 admin.py 中注册要管理的数据
        1.admin.py
            作用:
                注册要管理的Models类
        2.注册Models
            from django.contrib import admin
            from .models import *
            admin.site.register(Entry)
            admin.site.register(Entry)
    2.定义Models的展现形式
        1.通过 __str__ 定义展现形式
            class Author(models.Model):
                xxxx xxxx
                def __str__(self):
                    return self.name
        2.通过 verbose_name 字段选项,修改名称
            name=models.CharField(
                max_length=30,
                verbose_name='姓名'
            )
        3.通过Meta内部类 修改展现形式
            class Author(models.Model)
                class Meta:
                    1.db_table
                        指定当前类映射到的表名
                        (设置完成后立马同步数据库)
                    2.verbose_name
                        定义实体类在admin中的显示名称
                        (单数)
                    3.verbose_name_plural
                        效果同上(复数)
                    4.ordering
                        指定数据的排序方式
                        取值为一个列表
    练习:
        1.修改 Publisher 后台管理功能
            1.更改表名为 publisher
            2.修改后台的展示名称 - 出版社
            3.修改每个属性对应的中文名称
        2.修改 Book 后台管理功能
            1.更改表名为 book
            2.修改后台的展示名称 - 书籍
            3.修改每个属性对应的中文名称
            4.指定排序方式 - 按出版时间倒序排序
3.高级管理
    1.在 admin.py 中创建高级管理类并注册
        1.定义类EntryAdmin,继承自admin.ModelAdmin
            class AuthorAdmin(admin.ModelAdmin):
                pass
        2.注册高级管理类
            admin.site.register(Entry,EntryAdmin)
    2.在EntryAdmin中所管理的功能
        通过 属性 管理功能
        1.list_display
            作用:定义在列表页上允许显示的字段们
            取值:由属性名组成的列表或元组
        2.list_display_links
            作用:定义在列表页中能连接到详情页的字段们
            取值:同上
            注意:取值必须要出现在list_display中
        3.list_editable
            作用:定义在列表页中就允许修改的字段们
            取值:同上
            注意:取值必须出现在list_display中但不能出现在list_display_links中
        4.search_fields
            作用:添加允许被搜索的字段们
            取值:同上
        5.list_filter
            作用:列表页右侧增加一个过滤器快速筛选
            取值:同上
        6.date_hierarchy
            作用:列表页中增加时间分层选择器
            取值:只能取一个值,必须是DateField或DateTimeField的
        7.fields
            作用:在详情页中,指定要显示的字段以及顺序
            取值:由属性名称组成的元组或列表
        8.fieldsets
            作用:详情页中,对字段们进行分组
            注意:fieldsets与fields不能共存的
            取值:
                fieldsets = (
                    #分组1
                    ('组名',{
                        'fields':('属性1',"属性2",),
                        'classes':('collapse',)
                    }),
                    #分组2
                    ()
                )
    练习:完成Publisher的高级管理功能
        1.在列表页中显示name,address,city属性
        2.address 和 city 是可编辑的
        3.右侧增加过滤器,允许按照city筛选
        4.顶部增加搜索框,允许按照name和website搜索
        5.详情页中分组显示
            1.name,address,city : 基本信息
            2.conuntry,website : 高级信息,并可折叠

3.关系映射

1.一对一映射
    1.语法
        在关联的两个类中的任何一个类中:
        属性=models.OneToOneField(Entry)
        2.示例
        class Author(models.Model):
            xxxx xxxx
        class Wife(models.Model):
            xxxx xxxx
            author=models.OneToOneField(Author)
        Author中也会有一个隐式属性 - wife
练习:
    1.查询 巴金 的夫人的信息
    2.查询 金夫人 的对应的Author的信息
2.一对多映射
    1.语法
        在"多"实体中增加对"一"实体的引用
        属性 = models.ForeignKey(Entry)

        ex:
            一个出版社允许出版多本图书
            一本图书只能属于一个出版社
            出版社(1) : 图书(多)
            class Publisher(models.Model):
                xxxx 

            class Book(models.Model):
                xxxx
                publisher = models.ForeignKey(Publisher)
 2.数据管理
    1.增加数据
        1.通过 book.publisher_id 插入关联数据、
            book = Book(xxx xxx)
            book.publisher_id = 1
            book.save()
        2.通过 book.publisher 插入关联数据
            book = Book(xxx)
            pub = Publisher.objects.get(id=2)
            book.publisher = pub
            book.save()
    2.查询数据
        1.正向查询
            通过 Book 查询 Publisher 
            book = Book.objects.get(id=1)
            pub = book.publisher
        2.反向查询
            通过 Publisher 查询对应的所有的 Book
            Django会在Publisher中增加一个属性表示对Book的查询引用
            属性 :book_set --> (Entry.objects)
3.多对多映射
    1.语法
        在关联的两个类的任意一个类中,增加:
        属性 = models.ManyToManyField(Entry)
        class Author(models.Model):
            xxx
        class Book(models.Model):
            xxx
            author_set = models.ManyToManyField(Author)
    2.数据管理
        1.增加数据
            通过关联属性的add()方法实现数据的增加
        2.删除数据
            通过关联属性的remove()实现删除数据
        3.查询数据
            1.正向查询
                通过Book查询Author,可以通过关联属性来表示对Author的查询对象 --> objects
                示例:查询射雕英雄传对应所有的作者
                 book=Book.objects.get(title='射雕英雄传')
                 book.author_set.all()
            2.反向查询
                通过Author查询Book,可以通过Django增加的隐式属性book_set来获取对应的book的查询对象 --> objects
                author=Author.objects.get(name='金庸')
                books = author.book_set.all()

Day05

1.Django ORM

1.自定义查询对象 - objects
1.声明类EntryManager继承自models.Manager
    Entry.objects的类型为 models.Manager
    允许在EntryManager中添加自定义函数
    示例:
        class EntryManager(models.Manager):
                ef 函数名(self,自定义参数列表):
                .... ....
                return .... ....
2.使用EntryManager覆盖Models类中原有的objects
    class Entry(models.Model):
        objects = EntryManager()
        name = models.CharField(xxxx)
练习:通过自定义的objects类型完成
    1.查询Author中姓名中包含指定字符的所有信息
    2.查询Book中出版时间是指定年份的所有信息

2.HttpRequest - 请求对象

1.什么是HttpRequest
    HttpRequest,在Django中就是请求对象。
    在Django中,请求对象被封装到视图处理函数中的参数里-request
2.request中的重要内容
    1.request.scheme : 请求协议
    2.request.body   : 请求主体
    3.request.path   : 请求具体资源路径
    4.request.get_full_path : 请求完整路径
    5.request.get_host() : 请求的主机/域名
    6.request.method : 请求方式
    7.request.GET    : get请求方式中封装的数据
    8.request.POST   : post请求方式中封装的数据
    9.request.COOKIES : 请求中cookie的相关数据
    10.request.META : 请求的元数据(消息头)
       request.META.HTTP_REFERER : 请求源地址
3.获取请求提交的数据
    1.使用get方式
        1.语法
            request.GET['参数名']
            request.GET.get('参数名')
            request.GET.getlist('参数名')
        2.能够产生get请求方式的场合
            1.地址栏的请求
                1.<a href="地址?参数=值&参数=值">
                2.location.href='地址?参数=值&参数=值'
            2.表单中method为get
                <form method='get'>
                    姓名: <input type="text" name='uname'>
                </form>
            注意:Django中URL的参数是不能用此方式
                url(r'^01-xxx/(\d+)',...)
                此写法属于Django,只在Django中有效而并非HTTP协议标准
    2.使用post方式          
        1.语法
            request.POST['参数名']
            request.POST.get('参数名')
            request.POST.getlist('参数名')
        2.CSRF
            Cross-Site Request Forgery
            跨    站点 请求    伪装
            (跨站点请求攻击)

            解决方案:
                1.取消 csrf 验证(不推荐)
                 删除 settings.py 中 MIDDLEWARE 中的 CsrfViewMiddleware 中间件
                2.开放验证
                    在视图处理函数上增加 : @csrf_protect
                    @csrf_protect
                    def post_views(request):
                        pass
                3.通过验证
                    需要在表单中增加一个标签
                    {% csrf_token %}
练习-果园项目的注册部分
        1.创建数据库 - fruitday
        2.创建实体类 - Users
            1.uphone - varchar(11)
            2.upwd - varchar(200)
            3.uemail - varchar(245)
            4.uname - varchar(20)
            5.isActive - tinyint,默认值为 1(True)
        3.完善注册 - /register/
            1.如果是get请求,则去往 regsiter.html
            2.如果是post请求,则处理请求数据
                验证uphone是否存在,如果存在回到前端并给出提示

3.使用forms模块处理表单

​ 1.forms模块的作用

    通过forms模块,允许将表单与class相结合
    允许通过class 生成 表单

​ 2.使用forms模块

    1.在应用中创建 forms.py 文件
    2.导入 django 提供的 forms 模块
        from django import forms
    3.创建 class , 一个class会生成一个表单
        class ClassName(forms.Form)
    4.在 class 中创建属性
        一个属性对应到表单中称为一个控件

​ 3. forms.Form 的语法

    属性=forms.类型(参数) 
    1.类型
        forms.CharField()
        forms.DateField()
        .... ....
        每个类型都会生成一个表单控件
    2.参数
        1.label
            控件前的文本
        2.initial
            控件的初始值
        3.widget
            指定小部件
        4.error_messages
            指定数据错误时的提示文本
        .... ....

​ 4. 在模板中解析form对象

        1.注意
            1.需要自定义<form>
            2.表单中的按钮需要自定义
        2.解析form对象
            在视图中创建form对象并发送到模板中解析
            ex:
                form = RemarkForm()
                return render(request,'xx.html',locals())
            1.手动解析
                {% for field in form %}
                    {{field.label}}:控件中label的值
                    {{field}}:表示的就是控件
                {% endfor %}
            2.自动解析
                1.{{form.as_p}}
                    将form中的每个属性都使用p标记进行表示
                2.{{form.as_ul}}
                    将form中的每个属性使用li标记包裹再显示
                    注意:必须手动提供<ol></ol>或<ul></ul>
                3.{{form.as_table}}
                    将form中的每个属性使用tr标记包裹
                    注意:必须手动提供<table></table>

Day06

1.forms模块

1.通过 forms 模块获取表单数据
    1.通过forms.Form的子类的构造器来接收post数据
        form = RemarkForm(request.POST)
    2.必须使form通过验证,才能取值
        form.is_valid()
            返回True:通过验证
            返回False:未通过验证
    3.获取表单数据
        通过 form.cleaned_data 来接收表单数据
练习:
        1.创建一个数据库 - djangodb
        2.创建实体类 - Users
            uname - varchar(30),upwd - varchar(30)
            uage - int,uemail - varchar(30)
        3.创建forms模块 - forms.py
            1.创建RegisterForm -> forms.Form
            2.属性根据Users实体类创建
        4.解析forms并接收数据
            1.将 RegisterForm 的对象发送到模板
                04-register/ -> 04-register.html
            2.post提交时接收数据,并将数据保存回数据库
2.forms模块的高级处理

​ 将 Models 和 Forms 结合到一起使用

    1. 在forms.py中创建class
        继承自 forms.ModelForm
    2. 创建内部类 Meta,关联Model
        1.model : 指定要关联的实体类
        2.fields : 指定从Model中取哪些字段生成控件
            1.取值为 "__all__"
                取全部属性生成控件
            2.取值为 列表
                将允许生成控件的属性名放在列表中
        3.labels : 指定每个属性对应的label值
            取值为字典
                labels = {
                    'uname':'登录名称',
                    ... ...
                }

练习:使用ModelForm完成
    1.从 Users 类中取出 uname,upwd两个字段生成表单
    2.提交数据时验证登录的成功与否
3.内置小部件 - widget
    1.什么是小部件
        表示的是生成到网页上的控件的类型以及其他的一些html属性
    2.常用小部件类型
        1.TextInput : type="text"
        2.PasswordInput : type="password"
        3.NumberInput : type="number"
        4.EmailInput :type="email"
        5.URLInput :type="url"
        6.HiddenInput : type="hidden"
        7.CheckboxInput : type="checkbox"
        8.CheckboxSelectMultiple : type="checkbox"
            以 <ul>和<li> 生成多个 checkbox 控件
        9.RadioSelect : type="radio"
            以 <ul>和<li> 生成多个 radio 控件
        10.Textarea : <textarea></textarea>
        11.Select :<select></select>
        12.SelectMultiple:
            <select multiple></select>

    3.小部件的使用
        1.继承自forms.Form
            1.基本版
                1.语法
                    属性=forms.CharField(
                        label='xxx',
                        widget=forms.小部件类型
                    )
                2.示例
                    upwd = forms.CharField(
                        label='用户密码',
                        widget=forms.PasswordInput
                    )
            2.高级版
                1.特征
                    在指定控件类型的基础之上还能指定控件的一些html属性
                2.语法
                    属性 = forms.CharField(
                        label = '标签',
                        widget = forms.小部件类型(
                            attrs={
                                'html属性名':'值',
                                'html属性名':'值',
                            }
                        )
                    )
        2.继承自forms.ModelForm
            class LoginForm(forms.ModelForm):
                class Meta:
                    model = Users,
                    fields = ['uname','upwd']
                    labels = {
                        'uname':'用户名称',
                        'upwd':'用户密码',
                    }
                    #指定小部件
                    widgets = {
                        'upwd':forms.PasswordInput(
                            attrs={
                                'html属性名':'值'
                            }
                        ),
                    }
练习:果园登录,改版成forms与models的结合

2.cookie 和 session

1.cookie 实现
  1.Django中使用cookie
        使用 响应对象 将cookie保存进客户端
        1.响应对象
            1.HttpResponse()
                resp = HttpResponse("响应一句话")
            2.render()
                resp = render(request,'xxx.html',locals())
            3.redirect()
                resp = redirect('/')
        2.保存cookie
            响应对象.set_cookie(key,value,expires)
                key:cookie的名字
                value:cookie的值
                expires:默认是以 s 为单位的数字
                    取值为0表示要删除该cookie值
        3.获取cookie
            request.COOKIES
            封装了当前站点下所有的cookie - 字典
2.session 实现
    1.保存session的值到服务器
        request.session['KEY']=VALUE
    2.从服务器中获取session的值
        VALUE=request.session['KEY']
    3.删除session值
        del request.session['KEY']
    4.在 settings.py中有关session的设置
        1.SESSION_COOKIE_AGE
            作用:指定sessionid在cookies中保存时长
            SESSION_COOKIE_AGE=60*60*24*2
        2.SESSION_EXPIRE_AT_BROWSER_CLOSE = True
            只要浏览器关闭,session就失效

12、Python-网络爬虫

Day01

1、网络爬虫

1、定义:网络蜘蛛、网络机器人,抓取网络数据的程序
2、总结:用Python程序模仿人去访问网站,模仿的越像越好
3、爬取数据目的:通过有效的大量数据分析市场走势

2、企业获取数据的方式

1、公司自有数据
2、第三方数据平台购买
     数据堂、贵阳大数据交易所
3、爬虫爬取数据
     市场上没有,价格太高,利用爬虫程序爬取

3、Python做爬虫优势

请求模块、解析模块丰富成熟,强大的scrapy框架
PHP :对多线程、异步支持不太好
JAVA:代码笨重,代码量很大
C/C++:虽然效率高,但是代码成型很慢

4、爬虫分类

1、通用网络爬虫(搜索引擎用,遵守robots协议)
    https://www.taobao.com/robots.txt
2、聚焦网络爬虫
    自己写的爬虫程序:面向需求的爬虫

5、爬取数据步骤

1、确定要爬取的URL地址
2、通过HTTP/HTTS协议获取相应的页面
3、提取响应中有用的数据
     1、所需数据,保存
     2、页面中有其他的URL,继续第 2 步

6、Anaconda和Spyder

1、Anaconda :集成的开发环境
2、Spyder快捷键
    1、注释/取消注释 :ctrl + 1
    2、运行程序 :F5

7、Chrome浏览器插件

1、安装步骤(打开浏览器)
    1、右上角 - 更多工具 - 扩展程序
    2、点开右上角 - 开发者模式
    3、把插件 拖拽到 浏览器页面,释放鼠标,点击添加扩展程序
2、插件介绍
    1、Proxy SwitchOmega : 代理切换插件
    2、Xpath Helper      : 网页解析数据插件
    3、JSON View         : 查看JSON格式的数据

8、WEB回顾

 1、HTTP和HTTPS
    HTTP:80
    HTTPS:443,HTTP的升级版,加了安全套接层
 2、GET和POST
    1、GET :查询参数在URL地址上显示出来
    2、POST:查询参数和需要提交的数据隐藏在Form表单中,不会在URL地址上都显示
 3、URL :统一资源定位符
    https://item.jd.com/37289659363.html#detail
      协议  域名/IP地址  访问资源路径   锚点
 4、User-Agent
    记录用户浏览器、操作系统等,为了让用户获取更好的页面效果
       Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1

9、爬虫请求模块

 1、python2: urllib、urllib2
     python3: 合并,urllib.request
 2、常用方法     
1、urllib.request.urlopen(‘URL地址’)
 1、作用 :向网站发起请求并获取响应对象
        字节流 = response.read()
    字符串 = response.read().decode('utf-8')
    encode() : 字符串->bytes
    decode() : bytes ->字符串
 2、不支持重构User-Agent
2、urllib.request.Request(‘url’,headers={})
  1、使用流程
        1、创建请求对象(Request())
      req = urllib.request.Request(...)
  2、发请求获响应(urlopen())
      res = urllib.request.urlopen(req)
  3、获取响应内容(read().decode('utf-8'))
      html = res.read().decode('utf-8')
3、响应对象(res)的方法
   1、read()
   2、getcode() : 返回HTTP的响应码
         200 :成功
         4XX :服务器页面出错
         5XX :服务器出错
   3、geturl() : 返回实际数据的URL地址

10、URL编码模块:urllib.parse

 1、urlencode({字典})
     key = {'wd':'美女'}
     data = urllib.parse.urlencode(key)
     ## data为编码后的字符串
     示例:在终端输入搜索内容,得到百度的搜索结果,保存到本地文件
  2、quote('字符串')
     s = urllib.parse.quote('旭叔')
     ## s为编码后的字符串
  3、unquote('%E8%E7%D5...')

11、练习 :百度贴吧数据抓取

  1、要求
     1、输入抓取的贴吧名称
     2、输入起始页
     3、输入终止页
     4、保存到本地 : 第1页.html 第2页.html ...
  2、步骤
     1、找URL规律
       1、不同吧:http://tieba.baidu.com/f?kw=??
       2、不同页
         第1页:http://tieba.baidu.com/f?kw=??&pn=0
     第2页:http://tieba.baidu.com/f?kw=??&pn=50
     第n页: pn=(n-1)*50
     2、获取网页内容(发请求获响应)
     3、保存(本地文件、数据库)

12、请求方式及实例

 1、GET
    1、特点 :查询参数在URL地址中
    2、案例 :抓取百度贴吧
 2、POST(在Request()中添加data参数)
    1、urllib.request.Request(url,
                              data=data,
                      headers=headers)
        data : 表单数据以bytes类型提交
    2、处理表单数据data为bytes类型
       1、先把data定义为字典 {}
       2、urlencode(data).encode()

Day01回顾

1、请求模块(urllib.request)
   1、Request(url,data=data,headers=headers)
   2、urlopen(请求对象)
2、响应对象res的方法
   1、res.read() ##bytes
      res.read().decode('utf-8') ##字符串
   2、res.getcode()
   3、res.geturl()
3、url编码模块(urllib.parse)
   1、urlencode({字典})
      1个查询参数 :{'kw':'美女吧'}
        ##编码后 'kw=%E8....'
      2个查询参数 :{'kw':'美女吧','pn':'50'}
        ##编码后 'kw=%E8...&pn=50'
   2、quote('字符串')
      s = '屠龙刀'
      quote(s) : '%E5....'
   3、unquote('编码后的字符串')
      s = '%E5....'
      unquote(s) : 屠龙刀
4、数据爬取步骤
   1、找URL规律(拼接)
   2、获取响应内容
   3、保存
5、请求方式
   1、GET :查询参数在URL地址上显示
   2、POST:参数名data,查询参数在Form表单里
      注意 :data一定要以bytes数据类型提交
      data = {....}
      data = urllib.parse.urlencode(data).encode()
6、json模块
   Dict = json.loads('json格式的字符串')

Day02

1、解析模块

1、数据的分类
    1、结构化数据
      特点:固定格式,HTML,JSON,XML
    2、非结构化数据
      图片,音频,视频,一般存储为二进制
2、正则解析模块re使用流程
    1、rList = re.findall(r'表达式','字符串',re.S)
    2、写法2
      1、创建编译对象
         p = re.compile(r'',re.S)
      2、进行字符串匹配
         rList = p.findall(html)
3、元字符
     .  : 匹配任意1个字符(不包括\n)
     \d : 1个数字
     \s : 空白字符
     \S : 非空白字符 #[\s\S]可匹配任意1个字符
     [] : 包含[]内容
     \w : 普通字符
     \W : 特殊字符
     
     * : 0次或N次
     + : 1次或N次
     ? : 0次或1次
     {m} : m次
4、贪婪匹配和非贪婪匹配
    1、贪婪匹配(.*) : 在整个表达式匹配成功的前提下,尽可能多的匹配*
    2、非贪婪匹配(.*) : 在整个表达式匹配成功的前提下,尽可能少的匹配*
5、分组(findall())
    ## 在网页中,你想要什么数据,你就加()
    先按照整体正则匹配出来,然后再匹配()中 
    如果有2个(),则以元组形式显示
6、正则分组练习
    <div class="animal">
      <p class="name">
        <a title="Tiger"></a>
      </p>

      <p class="contents">
        Two tigers two tigers run fast
      </p>
    </div>

    <div class="animal">
      <p class="name">
        <a title="Rabbit"></a>
      </p>

      <p class="contents">
        Small white rabbit white and white 
      </p>
    </div>
    第1步实现:[("Tiger","Two ..."),("Rabbit","Sm..")]
    第2步实现:
        动物名称 :Tiger
        动物描述 :Two tigers two tigers ...
        ******************************
        动物名称 :Rabbit
        动物描述 :Small whilte rabbit ...

2、csv模块使用流程

1、导入模块
     import csv
2、打开csv文件
     ## 一定要加newline='',否则会多出空行
     with open('XX.csv','w',newline='') as f:
3、初始化写入对象
     writer = csv.writer(f)
4、写入数据
     writer.writerow([列表])

3、猫眼电影top100榜单

1、网址 :猫眼电影 - 榜单 - top100榜
2、目标 :电影名称、主演、上映时间
3、步骤
    1、找URL规律
      第1页:https://maoyan.com/board/4?offset=0
      第2页:https://maoyan.com/board/4?offset=10
      第n页:offset=(n-1)*10
    2、写正则表达式
      '<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?class="releasetime">(.*?)</p>',re.S
    3、代码实现

4、Anaconda环境安装模块

1、(管理员方式)进入到Anaconda Prompt
2、执行安装命令
     conda install pymongo
     conda install pymysql

5、数据持久化存储

1、pymongo回顾
    1、连接对象
       conn = pymongo.MongoClient('IP',27017)
    2、库对象
       db = conn['库名']
    3、集合对象
       myset = db['集合名']
    4、执行插入语句
       myset.insert_one({字典})

      >>>show dbs
      >>>use 库名
      >>>show collections
      >>>db.集合名.find().pretty()
      >>>db.集合名.count()
      >>>db.dropDatabase()
2、pymysql回顾
     1、创建数据库对象
     2、创建游标对象
     3、执行命令
     4、(重要)提交到数据库执行
3、warnings模块
     import warnings
     # 过滤警告/忽略警告
     warnings.filterwarnings('ignore')
4、猫眼电影存入MySQL数据库
    1、建库
      mysql> create database mydb charset=utf8;
    2、建表
      use mydb;
      create table top100(
      id int primary key auto_increment,
      name varchar(50),
      star varchar(150),
      time varchar(50)
      )charset=utf8;
    3、写程序
    4、SQL查询
      1、查询1990-2000年的电影信息
        select name,time from top100  where time>='1990-01-01' and time<'2001-01-01'
      2、查询20年以前的电影
        select name,time from top100 where time<=(now()-interval 20 year);

6、远程存入MySQL数据库

1、开启远程连接
    sudo -i
    cd /etc/mysql/mysql.conf.d/
    subl mysqld.cnf
    把下面这行注释掉
    #bind-address = 127.0.0.1
    重启数据库服务
    /etc/init.d/mysql restart
    service mysql restart
2、添加授权用户
    mysql> grant all privileges on *.* to 'lion'@'%' identified by '123456' with grant option;
    mysql> flush privileges;
3、关闭Ubuntu防火墙
    sudo ufw disable

7、Ubuntu中防火墙(ufw)基本操作

 1、打开防火墙
      sudo ufw enable
 2、关闭防火墙
      sudo ufw disable
 3、添加防火墙规则
      sudo ufw allow 端口号
      sudo ufw allow 3306
 4、查看状态
      sudo ufw status

8、Fiddler抓包工具

1、配置Fiddler
    1、Tools->Options
       1、HTTPS
          1、Decrypt Https Traffic (选中,自动添加证书信任窗口)
      2、...from browsers only
       2、Connections
          1、监听端口 :8888
      2、手机抓包 :Allow remote computers to connect(选中)
    2、重启Fiddler(重要)
2、配置浏览器代理
    1、浏览器右上角:SwitchOmega->选项->+新建情景模式->AID1809(名字)->创建
    2、HTTP://     127.0.0.1    8888(Fiddler端口)
    3、点击 :应用选项
    4、点击SwitchOmega可切换代理(AID1809)

9、Fiddler常用菜单

1、Inspector:查看抓到的数据包详细内容
     整体氛围请求(Request)和响应(Response)两部分
2、常用菜单
     1、Headers
       显示客户端发送到服务器的请求头,包含客户端信息、cookie、传输状态
     2、WebForms
       显示POST请求的数据<body>中
     3、Raw
       将整个请求显示为纯文本
allChars = sting.whitespace + string.punctuation
username = input("请输入用户名:")

for u in username:
     if u in allChars:
         print('用户名不能包含特殊字符')

Day02回顾

1、关于正则分组
  1、分组(想要抓取什么内容就加小括号())
  2、正则方法
    p = re.compile(r'',re.S)
    rList = p.findall(html)
    结果:[(),(),(),()]
  3、贪婪匹配 .*
  4、非贪婪匹配 .*? 或者 [\s\S]*?
2、爬取网站思路
  1、找URL规律,分析POST请求数据
  2、写正则表达式
  3、定义类,写程序框架
  4、补全代码
3、存入csv文件
  import csv 
  with open('XXX.csv','w',newline='') as f:
      writer = csv.writer(f)
      writer.writerow([])
4、MySQL流程
  1、db = pymysql.connect('IP地址',......)
  2、cursor = db.cursor()
  3、cursor.execute('sql命令',[])
  4、db.commit()
  5、cursor.close()
  6、db.close()
5、MongoDB流程
  1、conn = pymongo.MongoClient('IP地址',27017)
  2、db = conn['库名']
  3、myset = db['集合名']
  4、myset.insert_one({字典})
  ## 命令行操作
  >>> show dbs
  >>> use 库名
  >>> show collections | show tables
  >>> db.集合名.find().pretty()
  >>> db.集合名.count()
  >>> db.dropDatabase()
6、远程连接MySQL数据库
  1、开启远程连接
    sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
    #bind-address = 127.0.0.1
  2、重启数据库服务
    sudo /etc/init.d/mysql restart
    sudo service mysql restart
  3、授权
    mysql>grant all privileges on *.* to '用户名'@'%' identified by '密码' with grant option;
    ## 刷新权限
    mysql>flush privileges;
  4、设置防火墙,允许外部访问本机3306端口
    sudo ufw allow 3306
    sudo ufw allow 27017
7、Ubuntu中防火墙(ufw)基本操作
  1、状态 :sudo ufw status
  2、打开 :sudo ufw enable
  3、关闭 :sudo ufw disable
  4、规则 :sudo ufw allow 端口号
8、Anaconda安装模块
  1、右键,以管理员身份打开:Anaconda Prompt
  2、(base)C:\Users\Administrator:执行安装命令
     conda install 模块名
9、Fiddler常用菜单
  1、Inspector :请求/响应两部分
  2、常用选项
     1、Headers
     2、WebForms :Form表单数据<body>
     3、Raw :将整个请求显示为纯文本

Day03

1、requests模块

1、安装
    管理员Anaconda Prompt: conda install requests
2、常用方法
    1、requests.get(url,headers=headers)
       向网站发起请求并获取响应对象res
    2、响应对象(res)属性
       1、encoding : 响应字符编码
          res.encoding = 'utf-8'
       2、text   :字符串
       3、content: 字节流
       4、status_code : HTTP响应码
       5、url :返回实际数据的URL
    3、非结构化数据保存(图片)
       html = res.content
       with open('XXX','wb') as f:
           f.write(html)

2、get()方法中参数

1、查询参数(params)
    params : 字典
    res = requests.get(url,params=params,header..)
    # 自动对params字典进行编码,然后和url进行拼接
    输入搜索内容,爬取第2页的内容
2、代理参数(proxies)
    1、获取代理IP的网站
       西刺代理网站
       快代理
       全网代理
    2、普通代理
      1、格式:proxies={'协议':'协议://IP:端口号'}
      2、测试网站
         http://httpbin.org/get
     https://www.whatismyip.com/ (每天5次)
    3、私密代理
       1、格式
         proxies = {"协议":"协议://用户名:密码@IP地址:端口号'}
3、Web客户端验证(auth)
    1、auth=('用户名','密码')
       auth=('tarenacode','code_2013')
    2、达内笔记下载
      1、网址:http://code.tarena.com.cn
      2、正则:<a href="(.*?)/.*?</a>
      3、参数:auth=('tarenacode','code_2013')
4、SSL证书认证参数(verify)
    1、verify=True:默认,进行SSL证书认证
    2、verify=False:不去检查认证
    3、res = requests.get(url,headers=headers,verify=False)
    抛出异常:SSLError

3、request.post()

1、requests.post(url,data=data,headers=headers)
2、data :Form表单数据,字典,不用编码,不用转码

4、有道翻译破解案例

1、F12,抓包,多抓几次观察Form表单中数据变化
    salt、sign、ts、bv(没变)
2、加密一定为js文件做的,抓js文件,找到相关加密算法
3、F12,浏览器重新向有道翻译发起请求,抓到1个js文件:fanyi.min.js, Preview选项查看js代码,放到本地文件
4、Ctrl+F搜索想要的字段,salt、sign,找到8240多行
      var t = n.md5(navigator.appVersion)
        , r = "" + (new Date).getTime()
        , i = r + parseInt(10 * Math.random(), 10);
      return {
          ts: r,
          bv: t,
          salt: i,
          sign: n.md5("fanyideskweb" + e + i + "p09@Bn{h02_BIEe]$P^nG")

5、分开查找这几个字段

1、ts :r = "" + (new Date).getTime()
       时间戳(13位):1548320769934
       r = int(time.time()*1000)
 2、salt 
       i = r + parseInt(10 * Math.random(), 10)
       i = int(time.time()*1000)+random.randint(0,10)
 3、sign 
       sign: n.md5("fanyideskweb" + e + i + "p09@Bn{h02_BIEe]$P^nG")
       ## e:要翻译的单词

       sign = "fanyideskweb" + key + str(salt) + "p09@Bn{h02_BIEe]$P^nG" 
       s = hashlib.md5()
       s.update(sign.encode())
       sign = s.hexdigest()

3、内涵段子脑筋急转弯(mongodb)

1、网址 :www.neihan8.com
2、步骤
    1、找URL规律
      第1页:https://www.neihan8.com/njjzw/
      第2页:https://www.neihan8.com/njjzw/index_2.html
    2、写正则
      <div class="text-column-item.*?title=.*?>(.*?)</a>.*?<div class="desc">(.*?)</div>
    3、写代码
第一次:
    salt: 15483207699341
    sign: 267b98fe9abb20763b0d9a4560fb5b0b
    ts: 1548320769934
    bv: 363eb5a1de8cfbadd0cd78bd6bd43bee
第2次:
    salt: 15483208701106
    sign: b2c45f55e8b58b58046eba0a89c17a61
    ts: 1548320870110
    bv: 363eb5a1de8cfbadd0cd78bd6bd43bee
第3次:
    salt: 15483209185268
    sign: 300bd04be8c337d5dcf6054a3936bb92
    ts: 1548320918526
    bv: 363eb5a1de8cfbadd0cd78bd6bd43bee

Day03回顾

1、requests模块
 1、get()
    1、查询参数:params->{}
    2、代理参数:proxies->{}
       {'协议':'协议://IP:端口号'}
       {'协议':'协议://user:pwd@IP:端口'}
    3、Web验证:auth->(元组)
       auth=('tarenacode','code_2013')
    4、SSL认证:verify->True/False
       verify=False : 忽略证书认证
  2、post()
    data -> 字典,Form表单数据
  3、响应对象res的属性
    1、text : 字符串
    2、content : 字节流
    3、encoding: 字符编码
    4、status_code :HTTP状态码
    5、url :实际数据URL

Day04

1、xpath工具(解析)

1、在XML文档中查找信息的语言,同样适用于HTML文档的检索
2、xpath辅助工具
    1、Chrome插件:XPath Helper
       打开/关闭:Ctrl + Shift + x
    2、Firefox插件:XPath Checker
    3、XPath编辑工具:XML Quire
3、xpath匹配演示
    1、查找所有的book节点 ://book
    2、查找book下的title子节点中,lang属性为'en'的节点
       //book/title[@lang="en"]
    3、查找bookstore下的第2个book节点下的title子节点
      //bookstore/book[2]/title
    4、查找所有book/title节点中lang属性的值
      //book/title/@lang
4、选取节点
    1、// :从所有子节点和后代节点中查找
            //price 、 //book//price
    2、@  :选取某个节点的属性值
       选取1类节点 : //title[@lang="en"]
       获取节点属性值: //title/@lang
    3、匹配多路径: |
       xpath表达式1 | xpath表达式2
    4、函数
       1、contains()
         匹配一个属性值中包含某些字符串的节点
         找到所有lang属性值包含'e'的title节点
       //title[contains(@lang,'e')]
       2、text() : 获取文本
           //title[contains(@lang,'e')]/text()

2、lxml解析库及xpath使用

1、lxml库安装 
    Anaconda Prompt: conda install lxml
2、使用流程
    1、导模块
      from lxml import etree
    2、创建解析对象
      parseHtml = etree.HTML(html)
    3、调用xpath
      rList = parseHtml.xpath('xpath表达式')
    ## 只要调用xpath,结果一定是列表 ##

3、抓取百度贴吧帖子中所有的图片(视频)

1、目标:抓取指定贴吧所有图片
2、思路
    1、获取贴吧主页URL,下一页:找URL规律
    2、获取1页中所有帖子的URL
       [帖子1链接,帖子2链接,...]
    3、对每个帖子URL发请求,获取所有图片的URL
       [图片1链接,图片2链接,...]
    4、对每个图片URL发请求,以wb方式写入到本地文件
3、思路梳理
    帖子链接列表 = parseHtml.xpath('....')
    for 1个帖子链接 in [帖子链接列表]:
        图片链接列表 = 对帖子发请求后xpath出来的
        for 1个图片链接 in [图片链接列表]:
        html = 对1张图片链接发请求
        with open(filename,'wb') as f:
            f.write(html)
4、步骤
    1、获取贴吧主页URL,找URL规律
      http://tieba.baidu.com/f?kw=??&pn=50
    2、找到页面中所有帖子的URL
      xpath表达式: //div[@class="t_con cleafix"]/div/div/div/a/@href
    3、帖子中图片链接xpath表达式
      //div[@class="d_post_content j_d_post_content  clearfix"]/img[@class="BDE_Image"]/@src
    4、帖子中视频xpath表达式
      //div[@class="video_src_wrapper"]/embed/@data-video
      # 百度对响应内容做了更改,向1个帖子发起请求,获取到响应内容保存到本地,进行页面分析

4、糗事百科(xpath高级)

1、网址:
2、xpath匹配
    1、基准xpath表达式:匹配所有段子节点对象
      [<div1>,<div2>,.....]
      //div[contains(@id,"qiushi_tag_")]
    2、用户昵称: ./div/a/h2
       段子内容: .//div[@class="content"]/span
       好笑数量: .//i[@class="number"]
       评论数量: .//i[@class="number"]

Day04回顾

1、lxml使用流程
  1、from lxml import etree
  2、parseHtml = etree.HTML(html)
  3、rList = parseHtml.xpath('')
2、xpath匹配规则
  1、获取节点对象 : //div[@class="tiger"]
  2、获取属性值   : //div[@class="a"]//a/@src
  3、函数 ://div[contains(@id,"aa")]//a/@href
3、xpath高级
  1、基准xpath表达式(节点对象列表)
  2、for r in [节点对象列表]:
         username = parseHtml.xpath('./....')

Day05

1、Ajax动态加载网站数据抓取

1、特点 :滚动鼠标滑轮时加载
2、抓包工具(F12) :QueryString

2、豆瓣电影(Ajax)数据抓取

1、网址 :豆瓣电影-排行榜-剧情
2、目标 :电影名称、评分
3、F12/抓包工具
    滚动鼠标滑轮抓包,找到2个数据
      1、Request URL(Raw) :GET的地址
      2、QueryString(WebForms) : 发送的数据
4、代码实现
    type: 11
    interval_id: 100:90
    action: 
    start: 100
    limit: 20

3、selenium+phantomjs/Chrome强大网络爬虫组合

1、selenium
    1、定义 :Web自动化测试工具,用于Web自动化测试
    2、特点
      1、可运行在浏览器,根据指定命令操作浏览器,让浏览器自动加载页面
      2、只是工具,必须与第三方浏览器结合使用
    3、安装selenium
      Anaconda Prompt: conda install selenium
2、phantomjs浏览器
    1、定义 :无界面浏览器(无头浏览器)
    2、特点 :把网站在内存进行页面加载,运行高效
    3、安装
      1、下载对应安装包(.exe),将文件放到Python安装目录的Scripts目录下
        D:\Anaconda3\Scripts
3、chromedriver安装
    1、下载网址 https://chromedriver.storage.googleapis.com/index.html
    2、安装
      1、查看本机Chrome浏览器版本
        设置-帮助-关于Google Chrome
      2、下载对应版本的chromedriver.exe(notes.txt)
    3、拷贝到Python安装目录的Scripts目录下
    4、cmd终端 :chromedriver -v
4、示例代码1
5、示例代码2
6、常用方法
    1、driver.get(url)
    2、driver.page_source : 获取响应的html源码
    3、driver.page_source.find('字符串')
       作用:从html源码中搜索指定字符串
             -1 :查找失败
    4、单元素查找(返回值为1个节点对象)
      1、driver.find_element_by_id('').text
      2、driver.find_element_by_name('')
      3、driver.find_element_by_class_name('')
      4、driver.find_element_by_xpath('表达式')
    5、多元素查找(节点对象列表)
      1、driver.find_elements_by_...('')
    6、节点对象.send_keys('内容')
    7、节点对象.click()
    8、driver.quit()

4、chromedriver设置无界面模式

1、opt = webdriver.ChromeOptions()
2、opt.set_headless()
3、driver = webdriver.Chrome(options=opt)

5、京东商品爬取

1、网址 :https://www.jd.com/
2、目标 :输入搜索商品,爬取内容如下:
     1、商品名称
     2、商品价格
     3、评论数量
     4、商家名称
3、准备工作
     1、搜索框属性值  : class->text
     2、搜索按钮属性值: class->button
     3、下一页属性值
        能点  :class->pn-next
    不能点:pn-next disabled
     4、页面商品节点对象列表xpath表达式
        //div[@id="J_goodsList"]/ul/li
4、保存数据

6、浏览器对象driver执行JS脚本

 ## 把下拉菜单拉到最底部
 driver.execute_script(
 'window.scrollTo(0,document.body.scrollHeight)'
 )

7、作业

1、网址 :https://www.douyu.com/directory/all
2、目标
     1、主播名称
     2、观众人数
3、统计一共有多少个主播,观众总数是多少

8、多线程爬虫

1、进程
    1、系统中正在运行的一个程序
    2、1个CPU核心1次只能执行1个进程,其他非运行
2、线程
    1、进程中包含的执行单元,1个进程可包含多个线程
    2、线程可使用所属进程空间
    3、互斥锁:防止多个线程同时使用共享空间
3、GIL:全局解释锁
    执行通行证,仅此1个,拿到通行证可执行,否则阻塞
4、应用场景
    1、多进程 :大量的密集计算
    2、多线程 
       爬虫 :网络I/O
       写文件:本地磁盘I/O

#######操作共享资源的问题产生的原理######
number = 5000

f1 : number=number+1 加100次
f2 : number=number-1 减100次

计算值执行:
x1 = number+1  x1:5001
number = x1    number:5001

x2 = number-1  x2:5000
number = x2    number:5000

x1 = number+1  x1:5001
x2 = number-1  x2:4999
number = x2    number:4999
number = x1    number:5001

Day05回顾

1、Ajax动态加载
  1、抓包工具抓参数 :WebForms -> QueryString
  2、params = {QueryString一堆的查询参数}
  3、URL地址 :抓包工具抓到Raw下的GET地址
2、selenium+phantomjs
  1、selenium : 自动化测试工具
  2、phantomjs: 无界面浏览器(内存中页面加载)
  3、使用流程
    1、from selenium import webdriver
    2、driver=webdriver.PhantomJS(executable_path=)
    3、driver.get(url)
    4、driver.find_element_by_id('').send_keys('')
    5、driver.find_element_by_id('').click()
    6、driver.quit()
  4、常用方法
    1、driver.get(url)
    2、driver.page_source
    3、driver.page_source.find('')
       -1  失败
    4、driver.find_element_by_name('').text
    5、driver.find_element_by_class_name('').text
    6、driver.find_element_by_xpaht('')
    7、节点对象.text
3、selenium+chromedriver
  1、下载对应版本chromedriver
  2、将chromedriver.exe放到python安装目录的Scripts
  3、设置无界面模式
     1、opt = webdriver.ChromeOptions()
     2、opt.set_headless()
     3、driver = webdriver.Chrome(options=opt)
  4、driver执行JS
    driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
4、多线程爬虫
  1、多进程 :大量密集的计算
  2、多线程 :I/O密集(爬虫网络I/O频繁)

Day06

1、多线程爬虫

1、原理 :图
2、知识点
    1、队列(from multiprocessing import Queue)
       1、put()
       2、get()
         1、get(block=True,timeout=2)
        ## 阻塞2秒钟,没有得到值抛出超时异常
         2、get(block=False)
            ## 不阻塞,获取不到值马上抛异常
    2、线程模块(from threading import Thread)
       t = Thread(target=函数名)
       t.start()
       t.join()

2、小米应用商店抓取(多线程)

1、网址 :百度搜 小米应用商店
2、目标 :应用分类(聊天社交)
     1、应用名称
     2、应用链接
3、抓取查询参数,F12->QueryString
    URL :http://app.mi.com/categotyAllListApi?
    params = {
        page: ??
        categoryId: 2
        pageSize: 30
    }

3、BeautifulSoup解析模块

1、定义 :HMTL或XML解析器,依赖于lxml
2、安装
    Anaconda Prompt: conda install beautifulsoup4
3、使用流程
    1、导入模块
      from bs4 import BeautifulSoup
    2、创建解析对象
      soup = BeautifulSoup(html,'lxml')
    3、对象调用方法查找节点
      rList = soup.find_all(条件)
4、BeautifulSoup支持的解析库
    1、lxml :速度快,文档容错能力强
    2、html.parser :Python标准库,速度一般,容错一般
    3、xml :速度快,文档容错能力强
5、常用方法
    1、find_all() :返回列表
       rList = soup.find_all('div',{'id':'test'})
    2、节点对象.get_text()
    3、节点对象.string

4、链家二手房数据抓取(BeautifulSoup)

1、网址 :https://bj.lianjia.com/ershoufang/
2、目标
     1、名称
     2、户型
     3、面积
     4、年份
     5、楼层
     6、地点
     7、单价
     8、总价

5、scrapy框架

1、定义 :异步处理框架,可配置和可扩展程度非常高,Python中使用最广泛的爬虫框架
2、安装
    1、Windows安装
      Anaconda Prompt :conda install Scrapy
    2、Ubuntu安装
      1、安装依赖库
        sudo apt-get install libssl-dev
    sudo apt-get install libffi-dev
    sudo apt-get install build-essential
    sudo apt-get install python3-dev
    sudo apt-get install liblxml2
    sudo apt-get install liblxml2-dev
    sudo apt-get install libxslt1-dev
    sudo apt-get install zlib1g-dev
      2、升级pyasn1模块
        sudo pip3 install pysan1==0.4.4
      3、sudo pip3 install Scrapy

6、Scrapy框架组成

1、引擎(Engine) : 整个框架核心
2、调度器(Scheduler) : 接受从引擎发来URL入队列
3、下载器(Downloader)
     下载网页源码,返回给爬虫程序
4、项目管道(Item Pipeline) 
     数据处理
5、爬虫程序(spider)
6、下载器中间件(Downloader Middlewares)
     引擎 ---->  下载器
7、蜘蛛中间件(Spider Middlewares)
     引擎 ---->  爬虫程序
8、item :定义爬取的数据结构

7、制作爬虫项目步骤

1、新建项目
     scrapy startproject 项目名
2、明确目标(items.py)
3、制作爬虫程序
     scrapy genspider 文件名 域名
4、数据处理(pipelines.py)
5、全局配置(settings.py)
6、运行爬虫
     scrapy crawl 爬虫名

8、scrapy项目文件详解

1、目录结构
    Baidu
    ├── Baidu               # 项目目录
    │   ├── items.py        # 定义数据结构
    │   ├── middlewares.py  # 中间件实现
    │   ├── pipelines.py    # 数据处理
    │   ├── settings.py     # 全局配置
    │   └── spiders 
    │       └── baidu.py    # 爬虫文件
    └── scrapy.cfg
2、setting.py配置
    *1、是否遵守robots协议
      ROBOTSTXT_OBEY = False
    2、设置并发数量
      CONCURRENT_REQUESTS = 32
    3、下载延迟时间
      DOWNLOAD_DELAY = 1
    *4、请求头(添加User-Agent)
      DEFAULT_REQUEST_HEADERS = {}
    *5、项目管道
      ITEM_PIPELINES = {
       'Baidu.pipelines.BaiduPipeline': 300,}

9、抓取百度首页源码,保存到 百度.html 中

1、scrapy startproject Baidu1
2、cd Baidu1
3、scrapy genspider baidu1 www.baidu.com
4、修改items.py(此项目不用改)
5、修改爬虫文件baidu1.py
     def parse(self,response):
         print('*'*50)
     with open('百度.html','w',encoding='utf-8') as f:
         f.write(response.text)
     print('*'*50)
6、修改管道文件pipelines.py(此项目不用更改)
7、修改settings.py
     1、是否遵守robots协议->False
     2、DEFAULT_REQUEST_HEADERS = {添加User-Agent}
8、运行爬虫文件
     scrapy crawl baidu1

10、pycharm运行爬虫项目

1、创建begin.py(和scrapy.cfg文件同目录)
2、begin.py内容:
    from scrapy import cmdline
    cmdline.execute('scrapy crawl baidu1'.split())

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mkYdH79T-1603206326270)(C:\Users\Administrator\Desktop\python复习\scrapy框架流程_看图王.png)]

Day06回顾

1、多线程爬虫
  1、URL队列 :put(url)
  2、PARSE队列:get(url)->put(html)
  3、创建多个线程
2、一边采集,一边解析
  while True:
      try:
        ....get(block=True,timeout=2)
        ...
      except:
        break
3、先采集,再解析
  while True:
      if not parseQueue.empty():
          ...get()
      else:
          break 
4、BeautifulSoup
  1、使用流程
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html,'html.parser')
    rList = soup.find_all('div',{})
    rObj = soup.find('div',{})
  2、支持解析库
    lxml、html.parser、xml
  3、soup.find_all('div',{'class':'abc'})
  4、soup.find('div',{'class':'abc'})
  5、节点对象.get_text() : 文本(包含子节点)
     节点对象.string     : 文本(不包含子节点)
5、scrapy框架 :异步处理框架
  1、组成
    Engine、Scheduler、Downloader、Item Pipeline、Spider、Downloader Middlewares、Spider Middlewares
  2、流程
    1、Engine向Spider索要URL(第1个要爬取的)
    2、交给Scheduler入队列
    3、出队列,通过Downloader Middlewares给下载器
    4、下载完后,通过Spider Middlewares交给Spider
    5、Spider数据提取:
       1、数据交给Item Pipeline
       2、需要跟进URL,交给Scheduler入队列
6、创建项目流程
  1、scrapy startproject Lianjia
  2、cd Lianjia
  3、scrapy genspider lianjia lianjia.com
  4、items.py : 定义要爬取的数据结构
     class LianjiaItem(scrapy.Item):
         name = scrapy.Field()
     price = scrapy.Field()
  5、lianjia.py
    import scrapy
    class LianjiaSpider(scrapy.Spider):
        name = 'lianjia'
    allowed_domains = ['lianjia.com']
    start_urls = ['http://www.lianjia.com/']
    
    def parse(self,response):
        pass 
  6、pipelines.py
    class LianjiaPipeline(object):
        def process_item(self,item,spider):
        pass
    class LianjiaMysqlPipeline(object):
        def process_item(self,item,spider):
        pass
  7、settings.py
    1、ROBOTSTXT_OBEY = False
    2、USER_AGENT = 
    3、DEFAULT_REQUEST_HEADERS = {}
    4、ITEM_PIPELINES = {
        'Lianjia.pipelines.LianjiaPipeline' : 100,
    'Lianjia.pipelines.LianjiaMysql...' : 200,
      }
  8、scrapy crawl lianjia
7、pycharm运行爬虫项目
  1、begin.py(scrapy.cfg同级目录)
   from scrapy import cmdline
   cmdline.execute('scrapy crawl lianjia'.split())

Day07

1、yield回顾

1、作用:把1个函数当做1个生成器来使用
2、特点:让函数暂停,等待下1次调用

2、Csdn项目

1、网址 :https://blog.csdn.net/cpongo4/article/details/86613730
2、标题、发布时间、阅读数
    标题: //h1[@class="title-article"]/text()
    时间: //span[@class="time"]/text()
    数量: //span[@class="read-count"]/text()
3、流程
    1、scrapy startproject Csdn
    2、scrapy genspider csdn blog.csdn.net
    3、item.py
    4、csdn.py
       from Csdn.items import CsdnItem
       def parse(self,response):
           item = CsdnItem()
       ...
       yield item
    5、pipelines.py
       def process_item(self,item,spider):
           ....
       return item
    6、settings.py
       ITEM_PIPELINES = {
           'Csdn.pipelines.CsdnPipeline' : 300,
       }
    7、scrapy crawl csdn

3、知识点

1、extract() : 获取选择器对象中的文本内容
    response.xpath('') 
      结果: [<selector ... data='文本内容'>,<>]
    response.xpath('').extract()
      结果: ['文本内容1','文本内容2']
2、pipelines.py中必须有1个函数叫:
     def process_item(self,item,spider):
         return item

4、警告级别(日志文件)

 LOG_LEVEL = ''
 LOG_FILE = '文件名.log'
 5层日志级别
     1、CRITICAL : 严重错误
     2、ERROR    : 普通错误(显示ERROR和严重错误)
     *3、WARNING : 警告信息(显示WARNING及以上信息)
     4、INFO     : 一般信息(显示INFO及以上级别)
     5、DEBUG    : 显示DEBUG及以上级别信息

5、腾讯招聘项目

1、网址调试信息:https://hr.tencent.com/position.php?start=??
2、xpath表达式
    基准 : 
      //tr[@class="even"] | //tr[@class="odd"]
    1、职位名称:  ./td[1]/a/text()
    2、职位类别:  ./td[2]/text()
    3、招聘人数:  ./td[3]/text()
    4、招聘地点:  ./td[4]/text()
    5、发布时间:  ./td[5]/text()
    6、职位链接:  ./td[1]/a/@href

6、保存为csv、json文件(-o选项)

1、json文件
    scrapy crawl tengxun -o tengxun.json
    设置导出编码 : FEED_EXPORT_ENCODING = 'utf-8'
2、csv文件
    scrapy crawl tengxun -o tengxun.csv
    csv文件出现空行解决方法(修改源码)
      D:\Anaconda3\Lib\site-packages\scrapy\exporters.py 做如下修改(搜索'csv'):
        self.stream = io.TextIOWrapper(
            file,
            newline='', # 添加此行

8、图片管道(360美女图片抓取)

1、通过F12抓包,抓取到QueryString中参数如下:
    ch: beauty # 图片分类
    sn: 90
      # sn表示图片编号,0(1-30张),30(31-60张)
    listtype: new
    temp: 1
2、Request URL:
    http://image.so.com/zj?ch=beauty&sn=90&listtype=new&temp=1
  ***3、项目实现
    1、在items.py中定义图片链接字段
    2、爬虫文件,可重写start_requests方法
       1、去掉 start_urls = ['']
       2、def start_requests(self):
               ... ...
           yield scrapy.Request(url,callback=)
    3、管道文件pipelines.py
       # 导入scrapy定义好的图片管道类
       from scrapy.pipelines.images import ImagesPipeline
       # 定义类,继承图片管道类
       class SoPipeline(ImagesPipeline):
           # 重写方法
       def get_media_requests(self,item,info):
          # 把图片链接发给调度器
          yield scrapy.Request(item['imgLink']
    4、settings.py中定义图片存储路径
       IMAGES_STORE = 'D:\\爬虫'

作业:

盗墓笔记:http://www.daomubiji.com/dao-mu-bi-ji-1

标题名称
章节数量
章节名称
链接

Day07回顾

1、response.xpath('')
  结果:列表,选择器对象
    extract():提取文本内容,将列表中所有元素序列化为Unicode字符串
2、MongoDB持久化存储
  1、settings.py设置相关变量
  2、pipelines.py自定义管道类
     class CsdnMongoPipeline(object):
         def __init__(self):
         pass 
     def process_item(self,item,spider):
         return item
     # 爬虫程序结束时执行此方法
     def close_spider(self,spider):
         pass
  3、settings.py添加ITME_PIPELINES={}
    ITME_PIPELINES={
      'Csdn.pipelines.CsdnMongoPipeline':500,
    }
3、settings.py常用变量
  LOG_LEVEL = ''
  LOG_FILE = ''
  FEED_EXPORT_ENCODING = ''
  IMAGES_SOTRE = ''
4、日志级别
  DEBUG < INFO < WARNING < ERROR < CRITICAL
5、保存为csv、json文件
  1、scrapy crawl 爬虫名 -o XXX.json/XXX.csv
  2、FEED_EXPORT_ENCODING = 'gb18030'
  3、解决csv文件空行问题
     找到exporters.py改一下源码(csv的类):
       files,
       newline = '',
6、图片管道类
  1、items.py
    imgLink = scrapy.Field()
  2、pipelines.py
    from scrapy.pipelines.images import ImagesPipeline
    import scrapy
    class SoPipeline(ImagesPipeline):
        # 重写方法
    def get_media_requests(self,item,info):
        yield scrapy.Request(item['imgLink'])
  3、settings.py
    IMAGES_STORE = ''
7、重写爬虫文件start_requests()方法
  1、作用 :不再爬取start_urls地址
  2、流程
    1、把start_urls去掉
    2、def start_requests(self):
           pass 
8、scrapy.Request(url,callback=解析方法名)

Day08

1、scrapy shell使用

1、scrapy shell URL地址
*2、request.headers : 请求头(字典)
*3、request.meta : 定义代理等相关信息(字典)
4、response.text : 字符串
5、response.body : 字节流
6、response.xpath('')

2、scrapy.Request()常用参数

1、url
2、callback
3、headers
*4、meta        : 定义代理等相关信息{}
*5、dont_filter : 是否忽略域组限制
   默认False,检查allowed_domains=['']
6、encoding    : 默认utf-8,不用配置

3、升级Scrapy

1、安装pip
    1、从官网下载pip安装包,并解压
    2、cd到解压路径,执行如下命令
       python setup.py install
    ####################################
    如果pip版本低则升级pip
    python -m pip install --upgrade pip
    ####################################
  2、升级Scrapy
    python -m pip install --upgrade Scrapy    

4、下载器中间件(随机User-Agent)

1、以前setting.py(少量User-Agent)
     1、USER_AGENT=''
     2、DEFAULT_REQUEST_HEADERS={}
2、现在middlewares.py设置中间件
    1、项目目录新建useragents.py,存放大量agent
       uaList = ['','','','']
    2、middlewares.py中创建中间件类
       from Testmid.useragents import *
       class RandomUAmiddleware(object):
         def process_request(self,request,spider):
            # 此处注意 headers 属性
        request.headers['User-Agent'] = ...
    3、开启中间件(settings.py)
       DOWNLOADER_MIDDLEWARES={
         'Testmid.middlewares.RandomUAmiddleware':300,
       }

5、下载器中间件(随机代理)

 request.meta['proxy']=random.choice(proxyList)

6、机器视觉与tesseract(验证码)

1、OCR
    光学字符识别,通过字符形状-->电子文本
2、tesseract-ocr(OCR的一个底层识别库,不能导入)
    1、安装(windows)
      1、windows下载安装,并添加到环境变量
        https://sourceforge.net/projects/tesseract-ocr-alt/files/tesseract-ocr-setup-3.02.02.exe/download
      2、环境变量路径 
        C:\Program Files (x86)\Tesseract-OCR
    2、安装(Ubuntu和Mac)
      sudo apt-get install tesseract-ocr
      brew install tesseract
3、验证(测试)识别
    cmd终端: tesseract test1.jpg test1
4、pytesseract模块
    1、安装
      Anaconda Prompt: pip install pytesseract
    2、使用示例

7、在线打码平台

1、tesseract-ocr识别率很低,很多文字变形,干扰,导致无法识别
2、在线打码
    1、云打码平台 :http://www.yundama.com/
    2、注册用户 - 充值 - 下载接口(开发文档)
    3、题分价格(类型码,在程序中写正确)
3、示例
    1、调整接口文档(YDM.py)
    2、写主体程序

8、redis安装

1、Windows
    1、直接下载安装
    2、启动并连接
       1、服务端启动
         cmd -> redis-server.exe redis.conf
       2、客户端连接
         cmd -> redis-cli.exe
    3、安装图形界面管理工具RedisDesktopManager
       左下角新建连接 + Connect to Redis Server
2、Ubuntu
    1、安装 :sudo apt-get install redis-server
    2、启动 :redis-server
    3、连接 :redis-cli -h IP地址

9、分布式爬虫

1、原理 :多台机器共享1个爬取队列
2、实现 :重写scrapy调度器(scrapy_redis模块)
     安装 :Anaconda Prompt:
            pip install scrapy_redis
3、为什么使用redis
    1、Redis是非关系型数据库,key-value形式存储
    2、Redis集合,存储每个request的指纹

10、打开GitHup登录,搜索scrapy_redis,查看

11、修改腾讯招聘案例

 1、在settings.py中添加如下代码
    # 使用scrapy_redis调度器
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 使用scrapy_redis的去重机制
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 不清除请求指纹
    SCHEDULER_PERSIST = True
    # 设置管道
    ITEM_PIPELINES = {
      'scrapy_redis.pipelines.RedisPipeline':500,
    }
    REDIS_HOST = '192.168.1.103'
    REDIS_PORT = 6379
 2、运行爬虫,数据会存储到Redis数据库
     tengxun:dupefilter : 请求指纹
     tengxun:items      : 数据
     tengxun:requests   : 请求头信息

12、腾讯招聘都存入mongodb数据库

1、把ITEM_PIPELINES管道设置为mongodb的管道
2、把代码拷贝一份到Ubuntu,同时启动爬虫
3、查看mongdb中的集合数据,不会有重复

13、使用redis_key改写,同时存入MongoDB

## 在12步的基础之上改写爬虫文件tengxun.py
1、from scrapy_redis.spiders import RedisSpider
2、class TengxunSpider(RedisSpider):
    # 去掉start_urls,添加redis_key
    redis_key='tengxunspider:start_urls'
3、多台机器同时启动项目
4、进入redis命令行,发送执行
     >>>lpush tengxunspider:start_urls https://hr.tencent.com/position.php?start=0

14、手机端app抓取(见图)

1、设置手机
     1、设置无线DHCP服务为手动
        IP地址 :你电脑的IP(ipconfig)
    端口号 :8888
     2、手机打开浏览器,输入 http://IP:8888 下载证书并安装
2、设置电脑(见图,更改注册表)
    
3、设置Fiddler
    1、Tools -> Options
      1、HTTPS选项卡 :...from all processes
      2、Connections选项卡
         1、端口号:8888
     2、Allow remote computers to Connect
4、重启Fiddler

版权声明:本文为weixin_43976257原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。