Python爬虫学习
目录
当前正在通过网课从0基础学习python爬虫相关的知识,用csdn平台进行知识点的总结,总结内容根据自己掌握的内容进行,有些简单的内容有所忽略。
各位大佬如果在阅读中发现有什么错误/不合理的地方,或者有更好的见解,欢迎在评论区留言。
Python
数据类型
基本数据类型
-
数字类型(number)
int整数 float浮点数
-
布尔类型(boolean)
-
字符串类型(string)
-
列表类型(list)
-
元组(tuple)
-
集合类型(set)
-
字典(dict)
数据类型转换
查看数据类型:内置函数type()
str = '123'
num = 123
type1 = type(str)
type2 = type(num)
print(f"str的类型是{type1}, num的类型是{type2}.")
1、int():
- 文字类和小数类字符串不能进行转换
- 浮点数转化为整数:抹零取整
# 声明字符型整数
str1 = '123'
# 转换
num1 = int(str1)
# 声明浮点型
f = 23.4
# 转换
num2 = int(f)
# 检验类型和结果
print(f"str1是{type(str1)}型, 值是{str1}; num1是{type(num1)}型, 值是{num1}.")
print(f, num2)
2、str():也可以用引号进行转换
# 声明字符串的两种方式
str1 = '123'
str2 = str(123)
# 判断两者是否一样
if str1 == str2:
print("等价")
else:
print("不等价")
3、float():
- 与int()同理,文字类不能转换为浮点数
- 整数转换为浮点数,末尾添.0
str = '12.3'
float1 = float(str)
print(str, float1)
# 声明整型并直接打印转换后的结果
num = 124
print(float(num))
列表(list)
声明
方式一:[ ]
方式二:list()函数声明,更多用于其他类型转化为列表。注意:括号里必须是一个值(可以是字典,元组、字符串等),不能直接放多个参数
# 方式一
list1 = [1, 3, 'list']
# 方式二
list2 = list([12, 'sad', 'python'])
常规函数
- +作为拼接符号
# 将list1和list2拼接
print(list1+list2)
- *用于复制列表内容,后面接一个数字
# 将list1复制3次
print(list1*3)
- max()获取列表中的最大值,min()获取列表中的最小值
注意:比较的列表中的所有的值必须是同一类型。
num_list = [12, 34, 21, 65]
print(f'num列表中最大的是:{max(num_list)}, 最小的是{min(num_list)}')
-
count()用于统计出现在列表中的某个值的次数
print(list1.count(1))
-
index()统计字符串第一次出现的下标(索引值)
print(list2.index('sad'))
-
sum()列表数值求和
-
列表切片分割:列表名[开始: 截止(不包括本身): 倒序/间隔]
检测判断
定义变量 = "元素值" (not) in 列表,得到的结果是True/False
# 检验list2
print('python' in list2)
# 检验list1
p0rint(2 in list1)
操作函数
添加元素
- append(需要添加的元素值):在列表结尾追加一个值
print(list1.append('sedfwse'))
print(list1)
- extend([需要添加的元素列表内容]):在列表结尾追加批量元素
print(list1.extend([123, 'sere', '']))
print(list1)
- inasert(下标, "元素值"):在列表的指定位置添加元素
print(list2.insert(2, "handsome"))
print(list2)
删除元素
- remove(需要删除的元素值):删除第一个指定的元素
print(list1.remove(1))
print(list1)
- pop():给指定元索引删除对应位置的元素,不指定默认删除元素的最后一位,若索引位置不存在报错IndexError
# 删除最后一位元素
print(list1.pop())
print(list1)
- clear():清空列表,也可以用切片的方式删除指定部分的元素
print(list2.clear())
print(list2)
- del指令用于彻底删除列表
注意与clear()之间的区别,clear()是清空,del是彻底删除。
del list2
print(list2)
# 会报错list2不存在
修改列表元素值
直接和声明的形式一样,重新进行赋值即可。
列表排序
sort()实现列表从小到大排序,从大到小将属性reverse修改为True
# 声明一个数字列表
num_list = [23, 122, 3, 543, 90, 45, 232]
# 从小到大排序
print(num_list.sort())
# 从大到小排序
print(num_list.sort(reverse=True))
列表生成式
声明列表的元素时通过表达式生成而不是完全按照文本输入
# 举例
number = [a for a in range(10)]
print(nunber)
列表迭代器
enumerate()枚举,迭代输出,可同时得到列表的下标和对应的元素值。但是直接打印只会得到一个迭代器enumerate对象的默认显示格式。用变量接受,一次只能得到一个数据,如果要得到所有的数据需要通过循环遍历迭代器。
# 声明一个数字列表
num_list = [23, 122, 3, 543, 90, 45, 232]
# 直接打印迭代器,会得到类似<enumerate object at 0x0000020F86F15E90>的表示迭代器的结果
print(enumerate(num_list))
# 用单变量接受迭代器,得到多个元组,每个元组内容包括元素下标和元素值
for a in enumarate(num_list):
print(a)
# 用两个变量接收迭代器,同时得到下标和元素值
for i,j in enumerate(num_list):
print(i,j)
元组(tuple)
声明
方式一:用()表示直接声明
方式二:用tuple()声明,括号里只能有一个数据,可以用函数声明,更多用于其他类型转化为列表。注意:括号里必须是一个值(可以是字典,元组、字符串等),不能直接放多个参数
如果需要声明单个元素的元组,括号里需要在元素后面添加一个","号
# 用方式一声明
tuple1 = (1, 2, 3, 4)
# 用方式二声明
tuple2 = tuple((6, 7, 8))
# 声明单个元素的元组
tuple3 = (3,)
list VS tuple
两者在形式上特别相似,但两者有一定区别:
- list声明用[ ];tuple声明用( )
- list能够对数据进行操作(如增删改查);tuple不能对数据进行操作(只能查)
- list性能稍慢,占用内存稍大;tuple性能稍快,占用内存稍小
- list不能作为字典键;tuple可以(前提是所有的元素都可哈希)
集合(set)
用{ }表示。有两个特性:
- 无序性:集合的元素没有顺序,每次打印的集合内容顺序可能不一致,且无法通过索引得到需要的值。
- 唯一性:自动去除声明的集合中重复出现的元素。
声明
方式一:用{ }声明
方式二:用set()函数声明,从其他数据对象快速创建集合并去重。
***注意:声明空集合必须使用set()函数,如果直接使用"{ }"会默认是声明字典(dict)。
# 方式一声明
set1 = {"apple", 12, "124"}
# 方式二声明
set2 = set(["pear", 'pig'])
# 声明空集合
set_empty = set()
print(set1)
print(set2)
print(set_empty)
字典(dict)
形式
{key: value} “键值对”
注意:字典中对应的key就有对应的value,key是唯一的,value可以不唯一。如果key重复声明,后面的key会覆盖前面的key的内容。
# 创建字典
dic = {"姓名": "张三", "年龄": "13", "性别": "女"}
print(dic)
print(type(dic))
常规方法
获取value
方式一:切片获取,索引值是key
方式二:get(key)
# 接着上面的内容
# 方式一获取value
print(dic["姓名"])
# 方式二获取value
print(dic.get('年龄'))
查询方法
获取所有的key——keys()
获取所有的value——values()
获取所有的key和value——items()
# 接着dic
# 获取所有的值
print(dic.values())
# 获取所有的key
print(dic.keys())
# 获取所有的键值对
print(dic.items())
添加键值对
单个添加:直接声明即可。需要注意,新key不能和先前的key相同,否则会修改以前的值
批量添加:使用update()函数。
# 单个添加
dic["爱好"] = "自行车"
print(dic)
# 批量添加update()
dic.update({"梦想": "财富自由", "婚配状态": "未婚"})
print(dic)
字典生成式
zip()方法:将两个其他的数据对象合并成一个字典,最终得到的是一个迭代器,里面的内容需要通过遍历提取出来(与前面提到的列表迭代器enumerate差不多)
# 把两个列表通过zip()函数合成一个字典
# 如果长度不一致,以短的为准
list1 = ["name", "age", "gender"]
list2 = ["Alis", "12", "female"]
dic = zip(list1, list2)
print(type(dic))
print(dic)
for i in zip(list1, list2):
print(i)
字典检测
in / not in
删除字典
del 指令
del dic['爱好']
不同意义符号
运算符
常见符号:
+加 -减 *乘 /除 %取余
特殊符号:
- **幂运算
- //整除运算(与%进行对比)
-
print(f"//整除:59//7={59//7}\n%取余:59%7={59%7}")
转义字符
“\”+符号:表示那些无法直接输入或具有特殊含义的字符。常见的有:
- \n换行符
- \t制表符(如果
\t前面的字符串长度为n,那么\t显示出来的空格数量为8 - (n % 8)) - \a响铃符(发出系统警告声)
- \'表示一个单引号
- \\表示一个“\”符号
格式化字符
1、格式化字符
%s字符串 %d整数 %f浮点数
print("%s真的只有%d岁吗?"%('我', 3))
2、占位符
用“{序号}”进行需要填充的位置占位
name = '我'
age = 3
print("{0}真的{1}岁吗?".format(name, age))
# 指定数据类型
print("{0:s}真的{1:d}岁吗?".format(name, age))
3、f-string(推荐)
name = '我'
age = 3
print(f"{'我'}真的{3}岁吗?")
print(f"{name}真的{age}岁吗?")
逗号表达式
进行多个声明或使用时,可以通过逗号隔开,将多个变量放在一起表达。
"""
# 原本的声明
a = 1
b = 2
c = 3
print(a, b, c)
"""
# 逗号表达式
a, b, c = 1, 2, 3
print(a, b, c)
复合运算表达式
格式:运算符+‘=’
# 例子
a = 3
a += 4
# 等同a = a + 4
比较运算符
< > <= >= !=不等于 ==等于(值的比较)
所有比较得到的是布尔类型的值:True或者False
str1 = '123'
str2 = '123'
str3 = '234'
num = 123
print(str1 == str2)
print(str1 == str3)
print(str1 == num)
逻辑运算符
主要用于多个条件放在一起的判断
- and与(并且)
- or或
- not非(取反)
用户输入:input()
用于接收用户主动输入的值,括号里可以添加提示词。
input()接收的内容全部是字符串类型,按照需求需要用数据类型转换函数进行转换。
age = input("please input your age:")
# 用type()函数查询此时age的类型
print(type(age))
# 转换成整型
age = int(age)
print(age)
if语句
整体形式:
if 条件1:
执行指令1
# 如果有多种情况
elif 条件2:
执行指令2
...
# 如果以上条件都不满足
else:
执行指令
三目运算
格式
<值_if_真> if <条件> else <值_if_假>
相比传统if_else结构使代码显得更加简洁
if嵌套
e.g.
age1, age2 = int(input().split())
if age1>18:
if age2>18:
print("两个小孩都成年了\n")
else:
print("第一个小孩成年了\n")
else:
if age2<18:
print("两个小孩都没成年了\n")
else:
print("第二个小孩成年了\n")
循环
while循环
格式:
while 条件:
执行指令
在使用print()时,默认是输出一次自动换行,有时候不需要,需要根据需求进行空格或者连接后面的内容,需要对print()里的end属性进行覆盖
str = '123'
# 默认打印括号里的内容后换行(默认end='\n')
print(str)
# 输出str后,后面的内容根据制表符空一格单位
print(str, end='\t')
# 输出str后,后面的内容不会有任何处理,如果有打印值会紧接在后面
print(str, end='')
for循环
格式:
for 自定义用于遍历的变量 in 需要遍历的值:
执行指令
range函数
搭配for循环的内置函数,从小到大生成想要的数字。
range()函数必须有stop截止的值(stop>0),默认start起始值为0,也可以自定义起始值。也可以自定义步长,从起始开始,每隔step取一个值,默认步长为1。还需要注意,range()取值不包括stop值本身。
for i in range(start, stop[, step]):
执行指令
# 打印九九乘法表
# range(1, 10)最终只能取到9
for i in range(1, 10):
for j in range(1, i+1):
print(f"{j}*{i}={i*j}", end=' )print()
break&continue
一般在循环里嵌套if语句使用。
break
用于特殊条件提前跳出循环或者终止循环
for i in range(1, 10):
print(i, end='\t')
if i==5:
break
continue
用于特殊条件越过当前条件的循环体进入下一循环体
for i in range(1, 10):
print(i, end='\t')
if i==5:
continue
字符串
字符统计
len()用于统计当前字符串的长度,count(‘字符串’)查询字符串出现的次数
str = 'string is not difficult.'
# 查询str的长度
print(str.len())
# 查询str的i的数量和is的数量
print(str.count('i'))
print(str.count('is'))
字符串操作
注意:对原来的字符串没有更改,需要重新声明变量进行保存
字符切片
格式:变量[开始:截止(不包括本身):步长(值的正负决定字符的正序/倒序)]
# 继续上文的str字符串
# 按序取序号2到4的字符串
print(str[2:5:1])
# 倒序空隔一格输出字符串
print(str[::-2])
字符串查找
find()/rfind()查找字符串第一次/最后一次出现的位置,无则返回-1
index()/rindex()查找字符串第一次/最后一次出现的位置,无则返回ValuueError
# 继续上文的str字符串
print(str.index('is'))
print(str.find('is'))
字符串大小写处理
upper()把所有的小写字母转成大写字母
lower()把所有的大写字母转换成小写字母
# 继续str的操作
print(str.upper())
print(str)
print(str.lower()
字符串的分割
split('分割标志‘, maxsplit=分割长度):返回得到分割后的字符串列表
rsplit()从右侧开始分割
# 默认以空格进行分割
print(str.split())
# 以s为标准进行分割
print(str.split('s'))
替换字符串
replace('需要替换的字符串', '替换后的字符串')
# 在str上继续
print(str.replace('difficult', 'easy'))
去除指定字符串
strip()默认去除空格,只局限与字符串左右两边,中间不做处理。
判断输入是否是数字
isdigit()函数,返回true或者false
# 在str上继续
# 去除空格
print(str.strip(' '))
# 判断是否是数字
print(str.isdigit())
函数
声明
关键字:def
def 函数名(形参):
函数体
函数传参
一般情况下,需要函数外部传数据(实参)到函数里进行处理,在声明函数时,需要用形参代替实参作为数据表示运算过程。
函数传参主要有5种方式:
1、位置传参:按顺序对应,实参和形参数量必须一致
# 声明函数
def func1(name, age):
print(f"{name} is {age} yhears old")
# 调用函数
func1("张三", 23)
2、关键字传参:在调用时通过“ 键=值 ”的形式传递指定的参数,相比位置传参可以不用考虑传递的位置
# 对比func1
def func2(name, age):
print(f"{name} is {age} years old")
# 调用func2
func2(age=23, name="张三")
3、默认参数:在声明函数时,直接给形参进行默认赋值。如果调用时没给已经默认赋值的形参赋值,则用默认值参与计算。
NOTE:
- 默认参数必须放在非默认参数之后。
- 默认参数不能赋值默认可变对象(如字典,元组等):在第一次调用后可变对象的内容再次调用其内容不会重置,会保留前面赋予的值。
# 举例
def func3(name, age=20, hobby="run"):
print(f"{name} is {age} years old, and he likes {hobby}.")
# 调用
# 没有提供年龄,会直接使用提前给的20
func3(name='李四', hobby="chess")
4、可变参数:不确定传入多少数量参数时。
(1)*args:接受任意多个位置的参数,打包成元组(tuple)
(2)**kwargs:接受任意多个关键字参数,打包成一个字典(dict)
def func4(*args, **kwargs):
print(f"{args}")
print(f"{kwargs}")
func(1, 23, 3, a=34, b="red", c="234")
5、命名关键字参数:强制约束,要求必须用关键字传参。
格式:在*args或 * 后面的参数
def person(name, *, city, job):
print(f"{name} lives in {city}, works as {job}.")
person("王五", city="隔壁", job="Engineer")
混合使用参数时,需要遵守顺序:
位置传参➡️默认参数➡️可变参数(*args)➡️命名关键字➡️关键字参数(**kwargs)
函数返回值
返回值是函数或者方法在执行后返回给调用者的数据。返回值可以是任何数据类型或者None。可以将这些结果传给其他代码继续使用。
return在函数的作用:
- 终止函数的执行:函数在运行中,如果遇到return,不会再继续执行后面的代码,提前结束退出当前函数
- 返回执行结果:如果return后面有参数,会将参数对应的值返回给函数外或新的函数继续使用。
- 函数return本质是返回一个数组,也就是可以返回多个值
没有return,函数默认返回None。
# 返回参数
def func5(a):
return a
# 啥都没有直接返回
def func(a, b):
print(a+b)
return
# 返回多个值
def func1(a, b):
return a, b
# 调用函数
print(func5(4)) # 打印4
print(func(2,3)) # 打印None
print(func(2,3)) # 打印2 3
返回值的作用:
- 返回计算结果
# 返回得到的结果
def add(a, b):
return a+b
# 得到结果
result = add(23, 67)
print(result)
- 控制程序流程
def func(name, age):
if age<18:
return
print(name, age)
print(func("张三", 7))# 打印:None
print(func("李四", 34))# 打印:李四 34
- 代码复用
def func(a):
if a==1:
return 1
else:
return a+func(a-1)
"""
第一步:得到5+func(4)
第二步:得到func(4)=4+func(3)
第三步:得到func(3)=3+func(2)
第四步:得到func(2)=2+func(1)
第五步:得到func(1)=1
按照上述步骤,逐步将结果反代回去加和得到结果
最终实现的总逻辑是5+4+3+2+1
"""
print(func(5))
匿名函数lambda
优点:代码更简洁
缺点:不易解读的代码
格式:函数变量 = lambda 变量:表达式
v = lambda a, b: a + b
print(v(2, 5))
主要使用场景:作为参数传递给其他高阶函数,让代码更加简洁紧凑。
- 配合sorted()进行自定义排序
sorted():用于对可迭代对象进行排序,返回一个新的列表。通过key修改判断规则。
students = [
{'name': 'Alice', 'score': 85},
{'name': 'Bob', 'score': 92},
{'name': 'Charlie', 'score': 78}
]
# 按分数 (score) 从高到低排序
# key参数接受一个函数,这里用 lambda指定按 'score' 字段排序
sorted_students = sorted(students, key=lambda x: x['score'], reverse=True)
print(sorted_students)
# 输出: [{'name': 'Bob', 'score': 92}, {'name': 'Alice', 'score': 85}, ...]
- 配合map()进行数据转换
map():将传入的函数作用于可迭代对象的每一个元素,返回一个包含结果的迭代器。通常配合list()转换为列表。
格式:map(函数,对象)
nums = [1, 2, 3, 4, 5]
# 计算每个数字的平方
squared = list(map(lambda x: x ** 2, nums))
print(squared) # 输出: [1, 4, 9, 16, 25]
- 配合filter()进行数据过滤
filter():根据函数的返回值(True/False)来筛选可迭代对象中的元素,返回一个包含符合条件元素的迭代器。
格式:filter(函数,对象)
nums = [1, 2, 3, 4, 5, 6]
# 筛选出偶数
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens) # 输出: [2, 4, 6]
全局变量
能够在整个模块文件里都能访问的变量。
- 在函数外声明全局变量,直接声明即可,不用添加关键字。
# 声明全局变量
count = 100
def func():
# 函数内使用
print(count)
return
# 最终打印的结果都一样
func()
print(count)
- 在函数内修改全局变量,必须使用global关键字声明。如果不添加关键字,函数默认只是声明了一个同名的变量,只会在函数里临时保留数据,不会对全局变量造成任何影响。注意:如果全局变量是一个可迭代对象(如列表,字典等),在函数里修改全局变量不用声明global,且一定会修改该全局变量
# 声明全局变量
count = 100
# 声明临时同名变量
def func1():
# 声明与全局变量同名的临时变量
count = 200
print(count)
# 执行对比,全局变量不受影响
func1()
print(count)
# 用global在函数内修改全局变量
def func2():
global count
count = 300
print(count)
# 执行对比,全局变量被修改
func2()
print(count)
闭包(还得再学)
闭包的三个硬性条件:
- 嵌套:必须有一个内部函数(定义在函数内部)
- 引用:内部函数必须引用外部函数的变量(不是全局变量)
- 返回:外部函数必须返回定义的这个内部函数
# 外部函数
def outer_function(msg):
# msg 是外部函数的变量
# 内部函数
def inner_function():
# 引用了外部变量 msg
print(f"我记得这句话:{msg}")
# 返回内部函数
return inner_function
# 1. 调用外部函数,得到闭包
my_closure = outer_function("Hello, 闭包!")
# 2. 此时 outer_function 已经执行结束了,但 msg 变量依然被 my_closure 记着
my_closure()
# 输出: 我记得这句话:Hello, 闭包!
文件操作
文件模式
r只读取文件
w写入文件(如果没有目标文件就创建文件,有该文件会覆盖原有文件重写当前内容)
b字节,以二进制打开文件,不能单独使用
- wb写入字节文件
- rb读取字节文件
a在文件后面追加数据,没有就创建目标文件
文件操作
方式一:open(文件(相对地址/绝对地址),文件模式,encoding=‘文件编码格式’)
该方式打开文件必须创建对象保存,通过创建的对象操作,且结束后必须close()关闭文件。
# 打开文件,没有就创建一个
file = open('file.txt', 'w', encoding='utf-8')
# write()用于写入文件
file.write('写几个字\n')
# 操作完了关闭文件
file.close()
# 再次打开文件
file = open('file.txt', 'r', encoding='utf-8')
# read()读取文件里所有的文本内容
print(file.read())
# 关闭文件
file.close()
方式二:with open(文件(相对地址/绝对地址),文件模式,encoding=‘文件编码格式’) as f
自动控制文件的打开和关闭,不用考虑close(),只需要操作文件即可
with open('file.txt', 'a+', encoding='utf-8') as f:
f.write('继续添加\n')
针对文本文件,有三种读取方式:
- read():一次性读取所有文件内容
- readlines():按行读取,返回得到列表
- .strip():迭代逐行读取
注意:在处理音频、图像等文件时,需要"文件模式+b",不用给文件编码格式。因为这些文件一般用二进制存储在内存。
# 图片和视频操作
with open(r'C:\Users\ljian\Pictures\Screenshots\1.png','rb')as f:
print(f.read())
异常处理
格式
try:
需要执行的代码
except:
若try对应的代码有问题,则执行这个范围的代码
except Exception as e:(Exception为系统的能检测的异常)
print(e)(显示异常,只有一个)
else:
若try里的代码没有异常,则一定会执行此处代码
面向对象(需要继续学习)
Web前端
文档使用的注释形式:
- HTML:<--注释内容-->
- CSS:/*注释内容*/
- Javascript(JS)://注释内容
HTML
初识HTML文件结构
<!DOCTYPE html>
<!-- html是根标签,顶级标签,所有的标签文件都要写在这里面-->
<html lang="en">
<!--head头部标签,规定文件的相关配置,导入外部文件-->
<head>
<!--mate视口标签,字符编码格式声明,解决中文乱码问题-->
<meta charset="UTF-8">
<!--title定义文档标题,会显示在浏览器的标签页或标题栏-->
<title>Web Basic Knowledge</title>
</head>
<body>
<!--body可视化区域,整个页面的主体-->
</body>
</html>
标签特点
- 成对出现(双标签):开始标签,结束标签<p></p>、<label></label>
- 单个出现(单标签):子闭合标签e.g.<hr>、<br>、<input>
标签关系
- 并列关系:<ul></ul>与<ol></ol>
- 包含关系:<ul><li></li></ul>
常见标签
根据标签的功能和用途分类
基础与结构标签
- <html>定义整个 HTML 文档的根元素
- <head>包含文档的元数据(如字符集、标题、引入的样式和脚本等)
- <body>定义文档的主体,包含所有用户可见的网页内容
- <div>通用的块级容器,常用于页面布局和对其他元素进行分组
- <span>通用的行内容器,常用于包裹文本并为其设置样式
文本与排版标签
- <h1>~<h6>定义不同级别的标题,<h1>级别最高,<h6> 级别最低
- <p>定义一个文本段落
- <br>插入一个换行符
- <hr>插入一条水平分割线
- <strong>定义重要的文本,通常浏览器会将其显示为加粗
- <em>定义强调的文本,通常浏览器会将其显示为斜体
链接和媒体标签
- <a>定义超链接,通过href属性指定跳转的目标地址
- <img>插入图片,通过src属性指定图片的路径
- <audio>嵌入音频内容
- <video>嵌入视频内容
列表和表格标签
- <ul>定义无序列表(通常显示为带项目符号的列表)
- <ol>定义有序列表(通常显示为带数字或字母的列表)
- <li>定义列表中的具体项目
- <table>定义一个表格
- <tr>定义表格中的一行
- <th>定义表格的表头单元格(内容通常居中且加粗)
- <td>定义表格中的标准数据单元格
表单与交互标签
- <form>定义一个表单,用于向服务器提交数据
- <input>定义输入控件,通过type属性可以变为文本框、密码框、单选框、复选框等
- <textarea>定义多行的文本输入区域
- <button>定义一个可点击的按钮
- <select>定义一个下拉选择菜单
- <option>定义下拉菜单中的具体选项
语义化标签
- <header>定义网页或某个独立区块的页眉
- <nav>定义页面的导航链接区域
- <selection>定义文档中的一个独立章节或区块
- <article>定义独立、完整的内容块(如一篇博客文章、新闻报道)
- <aside>定义与主要内容关联不大的侧边栏或附属内容
- <footer>定义网页或某个独立区块的页脚
元数据与脚本标签
- <meta>提供页面的元数据(如字符编码、视口设置、页面描述等)
- <title>定义网页的标题,显示在浏览器的标签页上
- <link>引入外部资源,最常用于引入 CSS 样式表
- <script>用于引入或编写 JavaScript 脚本
- <style>用于在页面内部编写 CSS 样式
CSS
基本语法
选择器+声明块的结构
/*以键值对的形式声明,注意每个键值对需要“;”结尾*/
选择器{
键: 值;
键: 值;
}
引入方式
主要有4种方式
- 行内样式:在标签里通过style属性声明
<p style="color:blue; font-size:5px;">段落标签</p>
- 内部样式:在head标签里添加style标签,在style标签里声明CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>内部样式</title>
<!--style标签引入,在按照常规CSS声明格式声明-->
<style>
div{
background-color: red;
width: 200px;
height: 300px;
}
</style>
</head>
<body>
<div>盒子标签</div>
</body>
</html>
- 外部样式:单独创建一个CSS文件写CSS样式代码,在head标签里通过link标签的href属性导入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>内部样式</title>
<!--假设在该html文件同目录下创建了一个example.css文件,里面的内容是:
div{
background-color: red;
width: 200px;
height: 300px;
}
-->
<!--导入CSS文件的路径-->
<link rel="stylesheet" href="example.css">
</head>
<body>
<div>盒子标签</div>
<!--呈现效果与上个样例相同-->
</body>
</html>
- 导入样式(了解但不推荐)
CSS选择器
基础选择器
- 标签选择器:直接使用HTML的标签名
/*盒子标签*/
div{
width: 200px;
height: 300px;
}
- 类选择器:以.开头
/*该段落标签的类命名为para*/
/*<p class="para">段落标签</p>*/
.para{
color: red;
}
- ID选择器:以#开头
/*该段落标签的ID命名为para*/
/*<p id="para">段落标签</p>*/
#para{
color: red;
}
- 通配选择器:用*表示,选中页面的所有元素,常用于清除默认边距
组合与伪类选择器
- 后代选择器:用空格隔开。
/*div标签下所有的p标签进行处理*/
div p{
color: red;
}
- 伪类选择器:用于定义元素的特殊状态。常见的是鼠标状态。
常见的有:
格式::+英语单词
hover:鼠标悬浮时
link:鼠标未触碰时
active:鼠标点击时
visited:鼠标点击后
核心概念:盒模型与布局
在 CSS 中,所有的 HTML 元素都可以看作是一个个“盒子”。
- 盒模型:每个盒子由 内容(content)、内边距(padding)、边框(border) 和 外边距(margin) 四部分组成。简单理解就是:
padding是盒子里面的填充物,margin是盒子外面与其他盒子的距离。 - 布局技术:现代网页布局主要依靠 Flexbox(弹性盒子) 和 Grid(网格布局),它们能非常轻松地实现各种复杂的排版和对齐,完美适配电脑和手机屏幕。
盒模型
盒子模型的宽度=width+padding+border+margin
padding:内边距,在边框border里面内容到边框的距离
border:盒子边框
margin:外边距边框到外面的距离
注意:padding、border、margin有倍数,计算时要考虑到。

弹性布局
在父容器display属性声明flex,那么该父容器下所有的子容器全部为flex弹性项目。通过父容器和子容器的参数调整进行布局。
<style>
.box {
width: 100%;
height: 100px;
border: 1px solid #a24add;
/*设置弹性布局*/
display:flex;
}
.box-item1 {
width: 100px;
height: 100px;
border: 1px solid #ff1e40;
/*文字水平居中*/
text-align: center;
/*文字竖直居中*/
line-height:50px;
/*划分子标签占比*/
flex:1;
}
.box-item2 {
width: 100px;
height: 100px;
border: 1px solid #d8f41f;
/*划分子标签占比*/
flex:2;
}
.box-item3 {
width: 100px;
height: 100px;
border: 1px solid #0dcccc;
/*划分子标签占比*/
flex:1;
}
</style>
JavaScript
基础知识
导入方式
关键词script标签
- 在head标签里嵌入js代码
- 在body主体的结尾嵌入代码
既可以直接嵌入js代码,也可以导入专门的js文件路径。
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
<!--方式1:写在head标签里,嵌入js代码-->
<!-- <script>-->
<!-- //Javascript的注释是双斜杠-->
<!-- alert("弹窗1")-->
<!-- </script>-->
</head>
<body>
<!--方式2:写在body结束语句前-->
<!--<script>-->
<!-- alert("弹窗2")-->
<!--</script>-->
<!--采用路径导入js文件-->
<!--<script src="../JavaScript/1.js"></script>-->
</body>
js的基础知识
整个内容和python知识点很像,只对知识点进行了整理。
基本数据类型
数字number,字符串string,对象object(数组/列表,字典),布尔值boolean
查询:typeof()
算术运算符
+ - * /
比较运算符
==/!=只比数值大小不比数据类型、===/!==两者都要比较
隐式转换(当数字和字符串一起进行运算)
加号:会将数字自动转为字符串进行拼接
其他符号:会将字符串转换为数字进行数字的加减
字符串-->数字
方式一:字符串*1
方式二:Number(字符串)(推荐)
分支语句
if判断语句
格式:
if(判断条件){
执行内容
}else if(){
执行内容
}else{
执行内容
}
switch判断语句
switch(被判断的变量等){
注意:case后面的值是一个准确值,不能是一个表达式
case 值1:
执行语句
break
case 值2:
执行语句2
break
...
default:
执行语句
}
while循环
while循环语句
while(判断条件){
执行语句
}
for_in循环
for(变量 in 对象(数组/字典)){
注意:变量得到的是对象的下标
执行语句
}
for循环
for(声明变量; 判断条件; 更新循环变量){
执行语句
}
js对html的操作
步骤:获取标签->进行处理
<script>
//修改标签内容
//1、获取标签(三种方式)
a = document.getElementsByTagName('p')
console.log(a)
//2、进行修改
//(1)innerText单纯修改文本
a[0].innerText = "hello"
//(2)innerHTML对整个标签进行修改
a[1].innerHTML = '<h1>一级标题标签</h1>'
</script>
js函数声明
格式:
<script>
function 函数名(形参){
函数体
}
</script>
常见的js操作
修改html内容,修改css,获取/修改网页显示的数据等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js</title>
<style>
.box1{
width:100px;
height:100px;
background-color: orange;
}
</style>
</head>
<body>
<p>段落标签1</p>
<p>段落标签2</p>
<p>段落标签3</p>
<button>单击</button>
<button>单击</button>
<button>双击</button>
<hr>
<button>修改css</button>
<div class="box1">盒子</div>
<div>空盒子</div>
<hr>
<input type="text"><button>获取内容</button>
<script>
//修改标签内容
//1、获取标签(三种方式)
a = document.getElementsByTagName('p')
console.log(a)
//2、进行修改
//(1)innerText单纯修改文本
a[0].innerText = "hello"
//(2)innerHTML对整个标签进行修改
a[1].innerHTML = '<h1>一级标题标签</h1>'
//事件处理
//1、获取标签(续上面)
b = document.getElementsByTagName('button')
//2、onclick鼠标的单击事件
//方式1:先声明再调用
//javaScript的函数声明:function 函数名(){}
function fix(){
a[2].innerText = '通过点击事件修改p标签'
}
//只要函数名不要括号在onclick后执行函数,加括号后会直接执行
b[0].onclick = fix
//方式2:直接声明使用
b[1].onclick = function (){
a[1].innerHTML = '<h2>点击后为了h2标签</h2>>'
}
b[2].ondblclick = function(){
console.log("双击事件")
}
//鼠标事件
//1、获取标签
c = document.getElementsByTagName('div')
//2、onmouseenter鼠标划入
c[0].onmouseenter = function (){
console.log("鼠标划入")
}
c[0].onmouseleave = function (){
console.log('鼠标划出')
}
//修改css
b[3].onclick = function (){
//语法格式:
//(1)标签.style.属性 = "修改值"
//(2)标签.style["属性"] = "修改值"
//注意:组合名称的第二个字母之间的-去掉,首字母大写
c[0].style.width = '500px'
c[0].style["backgroundColor"] = "green"
console.log("修改成功")
//设置css
//格式:标签.setAttribute('属性名', '属性值')
//如无该属性添加属性,有该属性修改属性
c[1].setAttribute('class', 'box2')
//移除属性:标签.removeAttribute('属性')
// c[1].removeAttribute('class')
}
//输入框内容
content = document.getElementsByTagName('input')
button = document.getElementsByTagName('button')
button[4].onclick = function(){
//获取输入框的内容
//语法格式:具体标签.value
value = content[0].value
console.log(value)
//自定义值
// content[0].value = '设置自定义值'
//清空输入框
//content[0].value = ''
}
</script>
</body>
</html>
js常规内置函数
主要就是时间和延时器的获取以及操作,具体看代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js内置函数</title>
</head>
<body>
<button>获取当前时间</button>
<script>
//内置时间
button = document.getElementsByTagName('button')
button[0].onclick = Get_Time()
function Get_Time() {
//创建实时时间对象
date = new Date()
// 获取年份
year = date.getFullYear()
console.log(year)
// 获取月份(起始是0,真正月份需要+1)
month = date.getMonth()
console.log(month)
// 获取天数
day = date.getDay()
console.log(day)
}
//内置window
// 定时器:以指定的时间间隔执行代码
//html默认时间间隔是1ms
// 方式一:定时器+函数
// setInterval(函数, 时间间隔(单位毫秒))
time1 = setInterval(Get_Time, 1000)
// 清楚定时器
// 格式:clearInterval(定时器)
clearInterval(time1)
// 方式二:函数嵌套在定时器里
time2 = setInterval(function () {
console.log(111)
}, 1000)
clearInterval(time2)
//延时器
// setTimeout(函数, 时间间隔)
//延时器是真专门用于延时
</script>
</body>
</html>
JQuery库
jQuery 的核心理念是 “Write Less, Do More”(写得更少,做得更多)。它把那些复杂的原生 JS 代码封装成了极其简洁的方法,让你能用短短一行代码,就完成以前需要几十行代码才能搞定的事情。
基础知识
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQuery</title>
<!--导入外部js-->
<!--<script src="myjq.js"></script>-->
<style>
.button{
background-color: #0dcccc;
}
#box1{
width:300px;
height:400px;
color:green;
background-color: #09d2ed;
}
#box2{
width:300px;
height:400px;
color:deepskyblue;
background-color: #ea5721;
}
.box{
font-family: kaiti,serif;
}
div{
width:300px;
height:300px;
background-color: deepskyblue;
}
</style>
</head>
<body>
<p class="p1" id="para1">段落标签1</p>
<p class="p1" id="para2">段落标签2</p>
<p class="p1" id="para3">段落标签3</p>
<button class="button">单击</button>
<button class="button">双击</button>
<div id="box1">盒子1</div>
<div id="box2">盒子2</div>
<label for="input"><input id="input"></label><button>获取信息</button>
<p></p>
<hr>
<button>显示</button>
<button>隐藏</button>
<button>显示和隐藏</button>
<div></div>
<!--在body结束标签之前导入js文件(推荐)-->
<script src="myjq.js"></script>
<!--再次script进行调用-->
<script>
//jq获取标签
//通过jq选择器$()
//方式一:通过标签关键字获取
ap1 = $('p')
//得到的是所有的p标签
console.log(ap1)
//方式二:通过class属性进行获取
ap2 = $('.p1')
console.log(ap2)
//具体到单个标签:eq()
console.log(ap1.eq(0))
console.log(ap2.eq(0))
//方式三:通过id属性获取
ap3 = $('#para1')
console.log(ap3)
//修改标签文本内容
//text()用于修改文本内容
ap1.eq(0).text('NO.1')
//html()连同标签一起修改
ap1.eq(1).html('<h1>Over!</h1>')
//用什么方式获取标签就要用什么方式设置标签(js/jq)
//设置简单事件
//按钮事件
//获取按钮
button = $('button')
div = $('div')
//方式一:声明函数名再调用
//方式二:直接用函数体
button.eq(0).click(function(){
ap1.eq(0).text('再次修改内容')
//修改css样式
//单个样式修改格式:css(键,值)
div.eq(0).css('width', '500px')
//修改属性
//格式:attr(属性名,属性值)
//属性不存在时添加属性,属性存在时进行原有的修改
div.eq(0).attr("class", "box")
})
button.eq(1).dblclick(function (){
ap1.eq(2).text('双击修改了这个内容')
//同时修改多个样式:css(字典样式{})
div.eq(1).css({
"width": "200px",
"height": "200px",
"background-color": "red"
})
//移除属性
//格式:removeAttr(属性名)
div.eq(0).removeAttr("class")
})
//鼠标滑动事件
div.eq(0).mouseenter(function (){
console.log('划入box')
})
div.eq(0).mouseleave(function(){
console.log('划出box')
})
//获取输入框的内容
input = $('input')
//射设置点击事件
button.eq(2).click(function(){
//获取输入框信息
//格式:val()
result = input.eq(0).val()
console.log(result)
//设置文本框内容
//input.eq(0).val("设置的内容")
//清空内容
input.eq(0).val('')
//展示获取到的信息
ap1.eq(3).text(result)
})
//显示和隐藏
//slide和fade默认400ms,show和hide默认0ms
button.eq(3).click(function(){
//div.eq(2).show(2000)//改变宽度高度透明度显示
div.eq(2).slideDown(2000)//改变高度向下显示
//div.eq(2).fadeIn(2000)//改变透明度显示
})
button.eq(4).click(function(){
//隐藏div:hide()/slideUp()/fadeOut()
//如果括号里为空,直接隐藏,如果有数字,在范围内逐渐隐藏(单位ms)
//div.eq(2).hide(4000)
div.eq(2).slideUp(1000)//改变高度隐藏
//div.eq(2).fadeOut(1000)//只改变透明度隐藏
})
button.eq(5).click(function(){
//自行判断显示/隐藏toggle()默认瞬间完成
div.eq(2).toggle(2000)//改宽高透明
div.eq(2).slideToggle(2000)//改高透明
div.eq(2).fadeToggle(2000)//改透明
})
</script>
</body>
</html>
以上内容是JQuery的最常规的操作,可以和js进行对比。
JQuery生成简单动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQ动画</title>
<style>
div {
width: 200px;
height: 300px;
background-color: #24a1df;
position: relative;
margin-top: 10px;
}
</style>
</head>
<body>
<button>动 画</button>
<button>停止动画</button>
<button>延迟动画</button>
<div></div>
<script src="myjq.js"></script>
<script>
button = $('button')
div = $('div')
button.eq(0).click(function (){
//添加动画
//格式:animate(css样式字典,时间)
div.eq(0).animate({
"width": "300px",
"height": "800px",
"position": "relative",
//重新定位
"top": "50px",
"left": "90px",
//动画过程对颜色无效
},5000)
})
//停止动画
button.eq(1).click(function(){
div.eq(0).stop()
})
//延迟动画
button.eq(2).click(function(){
div.eq(0).delay(2000).animate({
"width": "300px",
"height": "800px",
"position": "relative",
//重新定位
"top": "50px",
"left": "90px",
//动画过程对颜色无效
})
})
</script>
</body>
</html>
json数据
html文件中
<script>
//json数据
//可以被任何语言识别,并转换为任意语言的基本数据类型(字典形式数据类型)
//数据教化格式
//本质属于字符串类型
//js字典对象
var obj1 = {"name": "Alen", "age": 13}
console.log(typeof(obj1))
//json数据:本质是字符串
var obj2 = '{"name": "Alen", "age": 13}'//必须内双外单
console.log(typeof(obj2))
//js和json的数据转换
//js->json
var obj3 = JSON.stringify(obj1)
//json->js
var obj4 = JSON.parse(obj3)
</script>
python文件:
# 与json相关的有内置模块,可直接导入
import json
# 定义python数据对象,字典类型
obj1 = {'name': "张三", 'age': 23}
print(type(obj1))
# py->json
obj2 = json.dumps(obj1)
print(type(obj2))
# json->py
obj3 = json.loads(obj2)
print(type(obj3))
前后端交互
这一块看代码,解析+具体内容(以一个超简易的计算器为例)
counter.html前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算器</title>
</head>
<body>
<label for="num1"><input type="text" id="num1"></label>
+
<label for="num2"><input type="text" id="num2"></label>
=
<label for="num3"><input type="text" id="num3"></label>
<button>计算</button>
<script src="myjq.js"></script>
<script>
var input = $('input')
var button = $('button')
button.eq(0).click(function (){
var num1 = input.eq(0).val()
var num2 = input.eq(1).val()
console.log(num1, num2)
$.ajax({
"type": "post",
"url": "http://127.0.0.1:5000/count",
"data": {
"num1": num1,
"num2": num2,
},
"success": function(res){
data = JSON.parse(res)["result"]
input.eq(2).val(data)
},
"error":function(err){
}
})
})
</script>
</body>
</html>
post.py定义路由并进行数据计算
# 导入模块
from flask import Flask, request
from flask_cors import CORS
import json
# 初始化flask服务
app = Flask(__name__)
CORS(app)
# 设置路由:一个路由绑定一个函数
# 后端路由:用来返回不同的数据
# 根路由
@app.route("/")
def index():
return "根路由"
@app.route("/hello", methods=["GET", "POST"])
def hello():
# request获取前端给后端的所有的内容
apple = request.form.get("apple")
print(apple)
return "Hello World!"
@app.route("/count", methods=["GET", "POST"])
def count():
num1 = request.form.get("num1")
num2 = request.form.get("num2")
result = float(num1) + float(num2)
# 通过json格式将结果传递给前端
return json.dumps({"result": result})
if __name__ == "__main__":
# 开启服务
app.run(debug=True)
网址知识补充
组成格式:主体?参数(参数名=参数值,多个参数之间用&连接)
主体组成:
1、网络协议:网页在互联网上传递数据需要签订协议,不同协议传递不同的数据
http:超文本传输协议
https:超文本传输安全协议
2、格式:(1)网络协议://ip地址:端口号/路由
(2)网络协议://域名/路由
ip地址:每台设备在互联网上的唯一识别
端口号:程序在当前设备中的唯一识别
域名:IP和端口号的结合版
路由:网页在网站的路径
注意:前端采用了Ajax进行数据的获取,后端基于Flask框架开发。
Ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax数据请求</title>
</head>
<body>
<button>获取数据</button>
<p></p>
<script src="../../../web_base/JQuery/myjq.js"></script>
<script>
button = $('button')
para = $('p')
button.eq(0).click(func1)
function func1(){
console.log("已请求")
//使用jQuery的Ajax请求申请
//格式:$.ajax({提交方式})
$.ajax({
//提交方式:post,get等
"type": "post",
//提交路径:和后端的路由路径一致
"url": "http://127.0.0.1:5000/hello",
//传递数据
//数据内容是字典,用于后端json处理
"data": {
"apple": "苹果",
"banana": "香蕉"
},
//发送成功或者失败对应的键名是固定的
//成功回调函数
//data:接收对应路由函数的return的结果
"success": function(data){
console.log(data)
res = JSON.parse(data)[""]
console.log(res)
//
para.eq(0).text(res)
},
//失败回调函数
//err:接收错误的信息
"error": function(err){
console.log(err)
}
})
}
</script>
</body>
</html>
flask
# pip list查看已安装的模块
# 导入模块
from flask import Flask
# 导入CORS,设置跨域请求
from flask_cors import CORS
# 初始化flask服务
app = Flask(__name__)
# 允许跨域请求
CORS(app)
# 设置路由:一个路由绑定一个函数
# 后端路由:用来返回不同的数据
# 根路由
@app.route("/")
def index():
return "根路由"
@app.route("/hello")
def hello():
return "Hello World!"
if __name__ == "__main__":
# 开启服务
app.run(debug=True)
爬虫
数据分析
pandas
numpy
matplotlib
Django框架
MySQL数据库
更多推荐
所有评论(0)