安装配置
安装相关
python
1.windows 版本的 下载路径 https://www.python.org/downloads/windows/
pycharm
1.安装后 pycharm 的路径 C:\Program Files\JetBrains\PyCharm 2022.3.1\bin
2.pycharm 的 破解方法 https://www.exception.site/article/1702
3.破解文件在 chrome tomorrow\python\pycharm_steup\破解pycharm
配置相关
pycharm
1.配置 不同的 虚拟 python 解释器
1.点设置 project 下面 python Interpreter
2.点下来箭头 点 show all 点 + 号 选 add local interpreter
3.location 表示 虚拟的位置 base interpreter 表示你要选择的 python 的版本
4.可以 增加 删除 修改 过滤 修改可以修改 虚拟环境的名字 只是名字而已 和 路径 解释器 本身版本无关
基本操作
pycharm
pip基操
pip list
pip install requests
pip install -r requirements.txt
pip freeze > requirements.txt # 导出依赖
pip uninstall requests
pip install –upgrade requests==2.1.0
pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple #指定源
pip --version # 查看版本
常见的安装源:
https://pypi.tuna.tsinghua.edu.cn/simple # 清华
https://mirrors.aliyun.com/pypi/simple/ # 阿里
https://mirrors.163.com/pypi/simple/ # 网易
https://pypi.douban.com/simple/ # 豆瓣
https://mirror.baidu.com/pypi/simple/ # 百度
https://pypi.mirrors.ustc.edu.cn/simple/ # 中科大
https://mirrors.huaweicloud.com/repository/pypi/simple/ # 华为
https://mirrors.cloud.tencent.com/pypi/simple/ # 腾讯
快捷键:
格式化代码:"Ctrl+Alt+L"
注释代码:"Ctrl+/"
复制当前行或选定的代码块:"Ctrl+D"
剪切当前行或选定的代码块:"Ctrl+X"
粘贴剪贴板内容:"Ctrl+V"
撤销上一步操作:"Ctrl+Z"
重做上一步操作:"Ctrl+Shift+Z"
查找文件:"Ctrl+Shift+N"
查找类、方法或变量:"Ctrl+N"
在文件中查找文本:"Ctrl+F"
在文件中替换:"Ctrl+R"
在整个项目中查找文本:"Ctrl+Shift+F"
跳转到定义:"Ctrl+左键单击"
显示参数信息:在函数或方法后面输入"("并按下"Ctrl+P"
运行单元测试:在测试方法上点击右键,然后选择"Run"或按下快捷键"Ctrl+Shift+F10"
调试单元测试:在测试方法上点击右键,然后选择"Debug"或按下快捷键"Shift+F9"
跳到新的下一行 shift + 回车
python 语法
1.变量
1.Python是动态语言,它处理变量的概念与一般静态语言不同。静态语言如C C++当定义变量时内存就会预留空间存储变量内容。
2.变量所使用的是参照地址的概念,设定一个变量x=10时,Python会在内存某个地址存储10,此时我们简历变量x像是一个标志,
其内容是存储10的内存地址。如果有另一个变量y=10 则y的标志内容也是存储10的内存地址。相当于变量时名称,不是地址。
使用内置函数id()获取变量内存地址。
3.x = 10
y = 10
print(id(x)) //21430544
print(id(y)) //21430544
4.命名规则
1.必须有英文字母、_下划线或中文开头,建议用英文字母。
2.只能由英文字母、数字、_下划线或中文组成,下划线开关的变量会被特别处理。
3.英文字母大小写敏感,Name和name是两个变量名。
4.Python系统保留字或关键字不能当做变量名,这会让程序报错。内置函数名不建议当变量名
5.具体命名:
命名:
驼峰命名
1.appName:第一个单词首字母小写 第二个单词首字母大写
2.AppName (class):第一个单词首字母大写,第二个单词首字母大写,以此类推
下划线命名
app_name :用于函数名称 用下划线连接单词名称
APP_NAME:全大写用于常量
小结:
变量命名:变量,函数用下划线 类用大驼峰
全局变量(常量):大写,多个单词用下划线连接
5.下划线变量
_test
这样定义为私有变量、函数或方法,不想直接被调用时用单下划线开头
结尾下划线例如:
dict_
为了避免与系统关键字或内置函数名称相同
前后双下划线例如:
__test__
这是python内部保留变量或方法
前边双下划线例如:
__test
私有方法或变量的命名,无法直接使用本命存取
2.多重赋值
可以多个变量等于一个值
可以多个变量等于多个值 左右必须个数对称
x = y = z = 10
a, b = 10, 4
print(x, y, z)
print(a, b)
3.删除变量
如果某个变量不再需要,可以使用del将其删除,并回收内存空间
x = 1
del x
print(x) // 报错 UnboundLocalError: local variable 'x' referenced before assignment
4.常量
与变量相反,常量是不可变的量
但是在Python中,没有严格意义上的常量(constant)概念,即不能直接声明一个不可更改的值。
然而,Python约定俗成地使用全大写字母命名的变量来表示常量,以表示这些变量的值不应该被修改。
虽然这些变量的值可以被改变,但是开发者应该遵守约定,不去修改它们。
例如,以下是使用全大写字母命名的变量作为常量的示例:
PI = 3.1415926
在实际使用中,开发者应该避免修改这些被视为常量的变量,以保持代码的可读性和一致性。
5.+ - * / %
x = 1 + 2
print("x:", x) # 3
y = 6 - 5
print("y:", y) # 1
z = 3 * 4.5
print("z:", z) # 13.5
k = 10 / 3
print("k:", k) #k: 3.3333333333333335
l = 10 % 3
print("l:", l) #l: 1
6.连续写法
+= a = a + b 可以写成a += b
-= a = a - b 可以写成a -= b
*= a = a * b 可以写成a *= b
/= a = a / b 可以写成a /= b
%= a = a % b 可以写成a %= b
//= a = a // b 可以写成a //= b
7.关于注释
1.三个引号 (单 双 都可以) #
8.编码问题导致输出中文乱码
在程序的开头写入如下代码:
# -*- coding:utf-8 -*-
或者
# coding=utf-8
9.查看数据类型 type
1.常见
x = 10
y = x / 3
print(type(x)) # <class 'int'>
print(type(y)) # <class 'float'>
print(type(type(x))) # <class 'type'>
2.不仅仅是变量的数据类型可以看;函数,列表,字典,元组等都可以用这个内置函数查看它的类型
def print_hi(name):
a = ["1", "2"] # <class 'list'>
b = ("2",) # <class 'tuple'>
c = [1, 2, 3] #<class 'list'>
d = {"a": '1'} #<class 'dict'>
def e(): #<class 'function'>
pass
print(type(a))
print(type(b))
print(type(c))
print(type(d))
print(type(e))
10.数据类型
1.整数
1.碎片知识
整数的英文是integer,在计算机程序语言中用int表示,python和其他语言不一样,没有long,为什么呢?
因为python3最牛逼,可以是任意值 也可以这么写
a = 1_1_0
print(a) # 110
这么写的原因是?请看下边,你能一眼看出来这是多少吗?
a = 1000000000000 等价于 a = 1_000_000_000_000 print(a) #1000000000000
2.整数 强转函数 int()
1.可以将一个字符串或者浮点数转换成整数
2.浮点型
1.强转函数 float()
2.常见方法
1.round(4.56,1) //4.6 保留一位小数 四舍五入
2.is_integer(5.0) # True ; is_integer(5.1) # False
3.is_integer(5.0) # True
3.as_integer_ratio() 以元组的形式 返回一个小数的 分数
1.print(0.5.as_integer_ratio()) # (1,2
2.print(60.as_integer_ratio()) # (60,1)
3.布尔型
1.强转函数 bool
2.Python中,布尔值是True和False 就python首字母大写!其他都是小写
3.可以转换所有数据类型!包括列表字典元组,也不能说转换吧,他会输出True或者False
如果定义的数据为空或者0 他就是输出False 反之则True
print(bool("0") )#True
print(bool([0])) #True
print(bool({"a": 0})) #True
print(bool((0,))) #True
print(bool((0))) #False
print(bool(())) #False
print(bool({})) #False
print(bool([])) #False
print(bool(0)) #False
print(bool(None)) #False
4.逻辑运算符
1.and or not
4.字符串 str()
0.字符串函数
1.len
2.字符串切片
1.关于索引 正数 0 1 2 3 最后一个是 -1 -2 -3 -4
2.一些切片的列子
name = 'ab宇哥不是说相声的'
print(len(name)) #10
print(name[0]) #a
print(name[-1]) #的
print(name[0:2]) #ab 左开右闭 右边不被选中
print(name[2:]) # 宇哥不是说相声的
print(name[:-2]) # ab宇哥不是说相 仍然符合 右闭的特点 右边不被选中
print(name[:2] + name[2:]) # ab + 宇哥不是说相声的
print(name[:5] + name[5:]) # ab宇哥不 + 是说相声的
print(name[10]) # 越界报错!因为最大索引是 9 ,IndexError: string index out of range
print(name[2:20]) # 虽然后面越界 但是切片会自动处理 取最大数值 即可 # 宇哥不是说相声的
3.关于切片的步长 (可以为 正数 也 可以为 负数)
name = '宇哥不是说相声的'
print(name[::]) # 宇哥不是说相声的
print(name) # 宇哥不是说相声的
print(name[0:-1:1]) # 宇哥不是说相声 默认步长是 1
# 步长为正数
name = '宇哥不是说相声的'
print(name[0:-1:2]) # 宇不说声 隔一个取一个
# 步长为负数
name = '宇哥不是说相声的'
print(name[6:1:-1]) # 声相说是不 等于反过来取了 字符串也是反的
print(name[::-1]) # 的声相说是不哥宇 相当于反转字符串
3.其他的一些函数
a.strip() 返回去除字符串两端空格的版本。
a.split() 将字符串按照空格分割成多个子字符串,并返回一个列表。
a.join(iterable) 使用字符串作为连接符,将可迭代对象 `iterable` 中的元素连接成一个字符串。
a.replace(old, new) 返回将字符串中所有出现的旧子串 `old` 替换为新子串 `new` 的版本。
a.find(substring) 查找子串 `substring` 在字符串中第一次出现的索引位置,找不到返回 -1。
a.count(substring) 统计子串 `substring` 在字符串中出现的次数。
a.startswith(prefix) 检查字符串是否以指定前缀 `prefix` 开头,返回布尔值。
a.endswith(suffix) 检查字符串是否以指定后缀 `suffix` 结尾,返回布尔值。
a.lower() 返回字符串的小写。
a.upper() 返回字符串的大写。
a.capitalize() 返回字符串的首字母大写版本。
a.title() 返回字符串中每个单词的首字母大写版本。
a.islower() 检查字符串中的字母是否都是小写。
a.isupper() 检查字符串中的字母是否都是大写。
a.isdigit() 检查字符串是否只包含数字字符。
a.isalpha() 检查字符串是否只包含字母字符。
a.isnumeric() 检查字符串是否只包含数字字符(包括Unicode字符)。
字符串更多方法参考文档:https://docs.python.org/zh-cn/3.9/library/stdtypes.html#string-methods
4.print 函数
1.print(value,...,sep=" ",end="\n",file=sys.stdout,flush=False)
1.参数意义如下:
value:表示想要输出的数据
sep:当输出多个数据时,可以插入各个数据分隔字符,默认是一个空格。
end:当数据输出结束时所插入的字符,默认回车。
file:数据输出的位置。默认是sys.stdout,也就是屏幕,可以使用此设定输出导入其他文件或设备
flush:是否清除数据流的缓冲器,预设是不清除
2.比如 下面两个 会输出到一行 1 2 abc
print("1","2",end = "\t")
print("a","c",sep = "b")
2.格式化输出 %输出
1.常见的 %
%s 格式化字符串输出
%d 格式化整数输出
%f 格式化浮点数输出
%c 字符
%u 无符号十进制整数
%o 格式化8进制整数输出
%x 格式化16进制整数输出
%X 格式化大写16进制整数输出
%e 科学计数法小写e
%E 格式化科学计数法大写E的输出
%g %f和%e的简写
%G %f和%E的简写
2.常见例子
a = "123" ; print("%s 这是一个字符串格式化输出" % a) # 123 这是一个字符串格式化输出
print("%d 这是一个整数格式化输出" % 111) #111 这是一个整数格式化输出
print("这是多个格式化输出:整数:%d,字符串:%s" % (123,'www')) #这是多个格式化输出:整数:123,字符串:www
text = "这是一个测试格式化输出的变量,字符串:%s,%s" % ("hello1","world") #这是一个测试格式化输出的变量,字符串:hello1,world
text2 = "这是一个测试格式化输出的变量,字符串:%s" ; print(text2 % "hello2") #这是一个测试格式化输出的变量,字符串:hello2
3.{}和format() print("...输出格式区...".format( 变量系列区, ...))
1.一些列子
print("大爷!您今儿吃什么?,大爷说:吃{},{},{}".format("翔1","翔2","翔3")) #大爷!您今儿吃什么?,大爷说:吃翔1,翔2,翔3
print("大爷!您今儿吃什么?,大爷说:吃{2},{1},{0}".format("翔1","翔2","翔3")) #大爷!您今儿吃什么?,大爷说:吃翔3,翔2,翔1
#在format里边赋值
print("大爷!您今天吃什么?,大爷说:吃{a},{b},{c}".format(a="翔1", b="翔2", c="翔3")) #大爷!您今天吃什么?,大爷说:吃翔1,翔2,翔3
4.f-strings格式化字符串 在Python3.6x版后有一个改良format格式化方式,称f-strings
name = "yuge"
work = "dsb"
print(f"{name}天天{work}") # yuge天天dsb
name = "yuge"
work = "dsb"
print(f"{name=}天天{work=}") #name='yuge'天天work='dsb'
1.碎片知识
设定空字符串 x = str() x = str("ABC") # 同 x = "ABC"
强制转换 x = str(123) # 这里的123是int类型
2.字符串拼接
x = "hello"
y = "world"
print(x + "," + y + "!!!")
3.多行字符串
1.三个引号
str3 = "你大爷还是你大爷。" \
"你大妈还是你大妈"
print("str3:",str3)
str4 = ("你大爷还是你大爷"
"你大爷还是你二大爷")
print("str4:",str4)
4.转义字符
1.例子
print("Hello\nWorld") # 输出两行,Hello和World分别位于不同行
print("This is a\ttab") # 输出带有制表符的文本
print("She said, \"Hello!\"") # 输出包含双引号的字符串
print('He\'s happy') # 输出包含单引号的字符串
print("C:\\path\\to\\file") # 输出包含反斜杠的字符串路径
2.字符串加r 取消 转义 print(r"abc\nvvv") # abc\nvvv
5.字符串相乘
1.可以重复输出n次字符串 print("=" * 100)
5. bytes数据
1.碎片
1.字节集的创建
1.在Python中,bytes()是一个内置函数,用于创建一个不可变的字节对象。bytes()函数可以接受不同类型的参数,
1.并将其转换为字节对象
2.创建空的字节对象:empty_bytes = bytes() 下面两个等价:
str_bytes = bytes("Hello", encoding="utf-8") # type 后 显示 <class 'bytes'>
str_bytes1 = b"Hello" # type 后 显示 <class 'bytes'>
3. 从可迭代对象创建字节对象:iterable_bytes = bytes([72, 101, 108, 108, 111]) # hello
4. 从十六进制字符串创建字节对象 hex_bytes = bytes.fromhex("48656c6c6f")
hex_bytes = bytes.fromhex("48656c6c6f")
print(str(hex_bytes, "utf8")) #hello
5.从已有的字节对象创建新的字节对象:existing_bytes = bytes(b"Hello")
2.字节集可以转字符串
iterable_bytes = bytes([72, 101, 108, 108, 111])
print(str(iterable_bytes, 'utf-8')) # hello 可以把字节集转为 字符串
iterable_bytes1 = [72, 101, 108, 108, 111] #不可以直接把 list 转为字符串
print(str(iterable_bytes1, 'utf-8')) # 这里报错 TypeError: decoding to str: need a bytes-like object
6.数据类型总结
几种数据类型: 转换用内置函数
int类型:整数,如:1234567 int()
float类型:浮点数,小数,如:3.1415 float()
String类型:字符串 如:'123' "321" str()
Bool类型:布尔类型 如:True False bool()
List类型: 列表 如:['哈哈','呵呵'] list()
1.切片: 起始索引:结束索引:步长
pc_list = ["爬虫","逆向","前端","后端","框架"]
print(pc_list[0])
print(pc_list[-1])
pc_list = ["爬虫","逆向","前端","后端","框架"]
print(pc_list[0:-1:2])
print(pc_list[::-1]) # 反转
2.append() al.append("22222") 末尾增加一个元素
3.insert() al.insert(2,"这是三")
4.extend() 将可迭代对象的元素分别插入到列表末尾
al = [1, 2, "3", "4", 5, 6]
al.extend(["123","333","444"])
print(al) //[1, 2, '3', '4', 5, 6, '123', '333', '444']
5.copy() 浅拷贝 复制列表
fruits = ["apple", "banana", "orange"]
fruits_copy = fruits.copy()
print(fruits_copy) // 输出: ["apple", "banana", "orange"]
6.mergin = [1,2] + [3,4] 也属于浅拷贝
7.List1 * 2 列表元素成倍增加
8.len(List1) 列表长度
9.remove() al.remove("3")
10.pop() 删除指定位置的元素,如果不传参数,则删除最后一位
al = [1, 2, "3", "4", 5, 6]
al.pop(0)
al.pop(-1)
print(al) // [2, '3', '4', 5]
11.clear() a.clear() 清空
1.同样可以重新赋值达到清空的效果 a = []
12.del语句
a = ["1","2","3",["4","5"]]
del a[1] // ['1', '3', ['4', '5']]
print(a)
// 同上 清空
del a[:]
print(a) // []
13.index()
al = [1, 2, "3", "4", 5, 6]
res = al.index(2) // 1
14.count() 统计指定元素在列表中出现的次数
name_list = ["小王","小张","小刘","小王吧","小王"]
name_list_count = name_list.count("小王")
print(name_list_count) //2
15.sort() 排序 默认升序
fruits = ["apple", "banana", "orange"]
fruits.sort()
print(fruits) # 输出: ["apple", "banana", "orange"]
a = [2,35,1,123,35,6]
a.sort(reverse=False) # 是否反转,False就是正序
a.sort(reverse=True)
print(a)
16.reverse() 反转列表 同[::-1]
fruits = ["apple", "banana", "orange"]
fruits.reverse()
print(fruits) # 输出: ["orange", "banana", "apple"]
a = ["1","2","3",["4","5"]]
a[0:2] = "3","2","1" # ["3","2","1"]
print(a) # ['3', '2', '1', '3', ['4', '5']]
a = ["1","2","3",["4","5"]]
a[0:2] = "321"
print(a) # ['3', '2', '1', '3', ['4', '5']]
a[0] = "11111"
print(a) # ['11111', '2', '1', '3', ['4', '5']]
17.in 和not in in 判断一个元素是否在列表里返回布尔
a = ["1","2","3"]
b = "1" in a
c = "1" not in a
print(b) # True
print(c) # False
18.is ,is not
a = 3
print(a is 3) #True
print(a is not 3) #False
19.可循环
l = []
for i in ["hello","world"]:
if i == "hello":
l.append(i)
print(l) #['hello']
20.join 严格来说属于字符串的功能
txt = ""
l = ["hello","world","宇哥","爬虫"]
print(txt.join(l)) # helloworld宇哥爬虫
txt = ","
l = ["hello","world","宇哥","爬虫"]
print(txt.join(l)) # hello,world,宇哥,爬虫
21.列表嵌套
a = [1,2,3,4,5,[6,7,8]]
print(a[5]) # [6,7,8]
print(a[5][0]) # 6
Dict类型:字典 如:{'a':'b'} dict()
1.访问
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
print(pc_dict["name1"]) #ppl
print(pc_dict.get("name1")) #ppl
2.keys()
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
k = pc_dict.keys()
print(type(k)) # <class 'dict_keys'>
print(k) # dict_keys(['name1', 'name2', 'name3'])
3.values()
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
v = pc_dict.values()
print(v) # dict_values(['ppl', 'pry', 'yuge'])
4.items()
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
kv = pc_dict.items()
print(kv) # dict_items([('name1', 'ppl'), ('name2', 'pry'), ('name3', 'yuge')])
5.get()
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
aaa = pc_dict.get("aaa","bbb") # 不存在返回bbb
print(aaa)
6.pop()
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
res1 = pc_dict.pop("name1")
res2 = pc_dict.pop("123123","不存在")
print(res1,res2) # ppl 不存在
print(pc_dict) # {'name2': 'pry', 'name3': 'yuge'}
7.update()
1.将另一个字典中的键值对更新到当前字典中。如果键存在,则会覆盖对应的值;如果键不存在,则会添加新的键值对
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
pc_dict.update({"name1":"ndy"})
print(pc_dict)
2.直接定义更新 pc_dict["name1"] = "ndy" # 有就更新没有就添加
8.clear() del copy() len() 和 List中的用法相同 参考上面
9.遍历
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
for k,v in pc_dict.items():
print(f"key:{k}")
print(f"value:{v}")
获取key
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
for k in pc_dict.keys():
print(f"key:{k}")
// 什么都不加默认是key
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
for k in pc_dict:
print(f"key:{k}")
// 获取value
pc_dict = {"name1":"ppl","name2":"pry","name3":"yuge"}
for v in pc_dict.values():
print(f"value:{v}")
10.字典推导式
pc_dict = {k:v for k,v in {"name1":"ppl","name2":"pry","name3":"yuge"}.items() if v == "ppl"}
print(pc_dict) #{'name1': 'ppl'}
11.enumerate会返回数据的index
pc_dict = {k:v for k,v in enumerate(["ppl","pry","yuge"])}
print(pc_dict) # {0: 'ppl', 1: 'pry', 2: 'yuge'}
12.字典嵌套
pc = {"name": "sb56", "age": 100, "国籍": "xrz",
"额外": {"name": "23333",
"name1": {
"name": "zs",
"name1": "li",
}
}
}
for k,v in pc["额外"]["name1"].items():
print(k,v) # name zs name1 li
set类型:集合 如:{123,321321,4244,5432546} set()
1.一种无序且不重复的数据集合
pc = {"爬虫","爬虫","JS逆向"} # 即使定义了相同数据,他也不会输出,因为是不重复的
print(pc) # {'爬虫', 'JS逆向'}
2.几个特性:
无序性:集合中的元素是无序的,不能通过索引访问或修改特定位置的元素。
唯一性:集合中的元素是唯一的,不会出现重复的元素。如果尝试向集合中添加已经存在的元素,集合不会发生改变。
可变性:集合是可变的,可以添加、删除和修改元素。
不可哈希性:集合本身是不可哈希的,因此不能作为字典的键或其他集合的元素
3.定义
pc = set()
pc = {1,2,3,4,5,"爬虫"}
4.取值 无序所以不能取 因为没有索引,而且元素也是唯一,通常用一下方式进行判断
1.用in 来判断这个值是不是在集合里边
2.遍历 为什么数字就有序,字符串就无序
5.add pc.add("devtools")
6.update pc1.update(pc2, pc3)
7.remove() pc.remove("devtools") # 不存在会报错KeyError
8.discard() 移除元素 和 remove 类型 pc.discard("sb56") # 重复删除或者删除了不存在的元素不会报错
9.pop() 随机删除元素
10.clear() 清空元素 pc.clear()
11.copy() pc3.copy() 浅拷贝
12.union() 或 | 并集 找出两个或多个集合的并集 就是两个集合加一起去掉重复的
pc1 = {"爬虫","逆向","JS语言","Python语言","sb56"}
pc2 = {"爬虫","逆向","JS","Python","sb"}
print(pc1 | pc2) #{'JS', '逆向', 'sb56', 'Python', 'JS语言', 'Python语言', '爬虫', 'sb'}
print(pc1.union(pc2)) #{'JS', '逆向', 'sb56', 'Python', 'JS语言', 'Python语言', '爬虫', 'sb'}
print(pc1|pc2|pc3)
print(pc1.union(pc2,pc3))
13.intersection() 或 & 交集
pc1 = {"爬虫","逆向","JS语言","Python语言","sb56"}
pc2 = {"爬虫","逆向","JS","Python","sb"}
print(pc1 & pc2) # {'爬虫', '逆向'}
print(pc1.intersection(pc2)) # {'爬虫', '逆向'}
14.difference() 或 - 前边集合有的后边集合没有的 取差集
pc1 = {"爬虫","逆向","JS语言","Python语言","sb56"}
pc2 = {"爬虫","逆向","JS","Python","sb"}
print(pc1 - pc2) #{'sb56', 'Python语言', 'JS语言'}
print(pc1.difference(pc2)) #{'sb56', 'Python语言', 'JS语言'}
# 反过来结果不同
print(pc2 - pc1) #{'sb', 'JS', 'Python'}
print(pc2.difference(pc1)) #{'sb', 'JS', 'Python'}
15.symmetric_difference() 或 ^ 对称差集 两个集合中不重复的元素的集合。
1.对称差集包括了两个集合中除了交集部分之外的所有元素。换句话说,对称差集是两个集合的并集减去交集
pc1 = {"爬虫","逆向","JS语言","Python语言","sb56"}
pc2 = {"爬虫","逆向","JS","Python","sb"}
print(pc1 ^ pc2) #{'Python', 'JS', 'sb56', 'Python语言', 'sb', 'JS语言'}
print(pc1.symmetric_difference(pc2)) #{'Python', 'JS', 'sb56', 'Python语言', 'sb', 'JS语言'}
16.isdisjoint() 判断两个集合的相同元素 没有返回 True 有一个相同的就返回 False
pc3 = {"爬虫","爬爬乐"}
pc4 = pc3.copy()
print(pc4.isdisjoint(pc3)) #False
pc1 = {"爬虫1","爬爬乐1"}
print(pc1.isdisjoint(pc3)) #True
17.issubset() 判断当前集合是否是另一个集合的子集 子集:一个集合内的所有元素被另一个集合所包含
pc1 = {"爬虫","逆向","JS语言","Python语言","sb56"}
pc2 = {"爬虫","逆向","JS","Python","sb"}
pc3 = {"爬虫","逆向"}
print(pc3.issubset(pc1)) #True
print(pc3.issubset(pc2)) #True
print(pc2.issubset(pc3)) #False
18.issuperset() 用于判断当前集合是否是另一个集合的超集
1.超集:如果一个集合A包含了另一个集合B的所有元素,那么集合A被称为集合B的超集。
换句话说,集合A至少拥有集合B中的所有元素,可能还包含其他元素
pc1 = {"爬虫","逆向","JS语言","Python语言","sb56"}
pc2 = {"爬虫","逆向","JS","Python","sb"}
pc3 = {"爬虫"}
print(pc1.issuperset(pc3)) #True
print(pc3.issuperset(pc2)) #False
print(pc2.issuperset(pc3)) #True
19.集合推导式
1.将集合中的元素字符全变大写并且生成一个新的集合
pc = {'sb56','halou','pc'}
pc = {x.upper() for x in pc}
print(pc) #{'SB56', 'HALOU', 'PC'}
2.创建一个20以内单数集合
seq = {x for x in range(1, 20) if x % 2 == 1}
print(seq) # {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
Tuple类型:元组 如:(1,) (1,2,3,4,5,6) ('11','22') tuple()
1.元组的定义
pc1 = ()
pc2 = tuple()
print(pc1,pc2) # () ()
print(type(pc1),type(pc2)) # <class 'tuple'> <class 'tuple'>
2.一个变量赋值多个值就会被打包成元组
pc = "爬虫","逆向","JS"
print(pc) # ('爬虫', '逆向', 'JS')
3.取值
1.切片 唯一不同的是 不能发生变化 也就是不能赋值
2.遍历 for 不支持 for k,v in my_tuple
my_tuple = (1, 2, 3)
for item in my_tuple:
print(item) # 1 2 3
4.count() 取某个数值的个数
pc = "爬虫","逆向","JS","爬虫"
res = pc.count("爬虫")
print(res) // 2
5.index() 返回第一个出现的值的索引/下标
pc = "爬虫","逆向","JS","爬虫"
res = pc.index("爬虫")
print(res) // 0
6.len() 统计个数
pc = "爬虫","逆向","JS","爬虫"
print(len(pc)) // 4
7.sorted(iterable, key=None, reverse=False) key 就是排序的函数
1.排序并返回列表sorted() 适用于列表,元组,字典,字符串等可迭代对象
my_list = [3, 1, 2, 5, 4]
sorted_list = sorted(my_list)
print(sorted_list) # 输出: [1, 2, 3, 4, 5]
my_tuple = (3, 1, 2, 5, 4)
sorted_tuple = sorted(my_tuple)
print(sorted_tuple) # 输出: [1, 2, 3, 4, 5]
my_string = "hello"
sorted_string = sorted(my_string)
print(sorted_string) # 输出: ['e', 'h', 'l', 'l', 'o']
# 按照绝对值排序
my_list = [-3, 1, -2, 5, -4]
sorted_list = sorted(my_list, key=abs)
print(sorted_list) # 输出: [1, -2, -3, -4, 5]
8.最大值 max() 最小值 min()
pc1 = (1,2,3,7,8,9,4,2,1)
print(max(pc1)) // 9
print(min(pc1)) // 1
9.元组推导式
sb56 = (x**2 for x in range(1, 6))
print(sb56) #<generator object <genexpr> at 0x01A874C0>
print(tuple(sb56)) #(1, 4, 9, 16, 25)
strings = "爬虫爬数据,数据用爬虫爬"
pc = tuple(char for char in strings if char == "爬")
print(pc) #('爬', '爬', '爬', '爬')
11.文件操作
1.open (open()是python中内置的函数,功能是打开一个文件,进行增删查改等操作)
1.碎片
1.知识
file_obj = open(file_name,mode="r")
file_name 就是文件名,如果不存在则会创建,不指定路径就在当前路径下
mode就是打开文件的模式,r是读,w是写,a是追加,b则是打开二进制时需要添加的模式,
x是打开一个新文件,如果打开的文件已经存在会报错,t打开文本文件模式(默认)
r 只读,默认模式,文件不存在就报错
w 只写,文件存在会覆盖内容,不存在则创建
a 写追加,打开文件用于追加内容。如果文件不存在,会创建新文件。
x 独占创建模式。打开文件用于写入,只能创建新文件,如果文件已存在则会引发 FileExistsError。
b 二进制模式。以二进制格式打开文件。(图片,视频等)
t 文本模式(默认)。以文本格式打开文件。
+ 读写模式。同时支持读取和写入操作。
经常用的w+,a+,r+,rb,wb等
2.常见用法
1.print()输入到文件内(你们肯定没玩过,一般老师不会讲,因为知识点没这么宽)
file_obj = open("1.txt",mode="w")
print("dsadadsa",file=file_obj)
file_obj.close() # 玩完了别忘了关闭
2.write方法写数据到文件
file_obj = open("1.txt",mode="w")
file_obj.write("111111111111111111")
file_obj.close()
3.writelines 方法 这里如果是 write 会提示 TypeError: write() argument must be str, not list
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open("example.txt", "w") as file:
file.writelines(lines)
4.writable()用于检查文件是否可写,返回布尔值
with open("example.txt", "r") as file:
print(file.writable()) # False
with open("example.txt", "w") as file:
print(file.writable()) # True
5.read 读
file_obj = open("1.txt",mode="r")
txt = file_obj.read()
print(txt)
file_obj.close() # 关闭文件,不关闭会占用文件句柄
6.readline() 逐行读
1.readline() 方法用于逐行读取文件内容。每次调用 readline() 方法
它会读取文件中的一行,并将其作为一个字符串返回。连续调用 readline() 方法可以逐行遍历文件的内容。
file_obj = open("1.txt",mode="r")
txt = file_obj.readline()
txt1 = file_obj.readline()
print(txt,txt1)
file_obj.close()
//去掉\n
file_obj = open("1.txt",mode="r")
txt = file_obj.readline().strip()
print(txt)
file_obj.close()
7.readlines()
1.方法用于一次性读取整个文件的所有行,并将每一行作为一个字符串存储在一个列表中返回。
列表中的每个元素对应文件中的一行。
file_obj = open("1.txt",mode="r")
txt = file_obj.readlines()
print(txt) # 存入列表中
file_obj.close()
// for循环遍历
file_obj = open("1.txt",mode="r")
for i in file_obj.readlines():
print(i.strip())
// txt = file_obj.readlines()
// print(txt) # 存入列表中
file_obj.close()
8.readable() 用于检查文件是否可读,返回布尔值
9.seek 指针定位seek
1.file.seek(offset[, whence])
2.offset参数表示偏移量,即指针要移动的字节数,可以是正数或负数;whence参数表示起始位置,可以是以下值之一:
1. 0:从文件开头开始偏移,默认值;
-2. (0,1):从当前位置开始偏移;
-3. (0,2):从文件末尾开始偏移。
-4. 负数 :从文件末尾往开头(-1,2) 或这从当前位置往开头(-2,1)
with open("1.txt", "a+") as file:
# 用 with 不用主动关闭文件 自己会关闭 下面直接拿file操作
# 读取文件的前5个字符
print(file.read(5)) # "abcdefg"
# 将指针移动到文件开头
file.seek(0)
# 读取整个文件内容
print(file.read()) # "all file"
# 将指针移动到文件末尾
file.seek(0, 2)
# 写入新的内容
file.write("\nNice to meet you!")
# 将指针移动到文件开头
file.seek(0)
# 读取整个文件内容
print(file.read())
5.需要注意的是,在使用 seek()方法改变指针位置之前,必须以读取模式或读写模式打开文件。
如果文件以写入模式打开,使用 seek() 方法改变指针位置会导致文件内容被截断。
3.关于负偏移量
1.需要注意的是,在使用 seek()方法改变指针位置之前,必须以读取模式或读写模式打开文件。
如果文件以写入模式打开,使用 seek() 方法改变指针位置会导致文件内容被截断。
2.seek()方法的负偏移量或相对于末尾的位置在文本模式下是不被允许的。这是因为在文本模式下,
文件的字节偏移与字符的解码方式有关,而负偏移量或相对于末尾的位置可能会导致无法正确解码字符。
3.如果你需要在文本模式下进行定位操作,可以考虑使用其他方法,比如逐行读取文件并跟踪行号,
或者使用tell()方法获取当前文件指针的位置。
4.请注意,在以二进制模式('rb'、'wb'、'ab'等)打开文件时,seek()方法可以使用负偏移量或相对于末尾的位置
进行定位操作。这是因为在二进制模式下,文件的字节偏移是明确的,不受字符解码的影响。
5.with语句
1.使用 with 语句可以确保文件在使用完后自动关闭,无需显式调用 close() 方法。
with open("1.txt",mode="r") as f:
text = f.read()
print(text)
12.输入 input()
1.input函数功能与print()函数功能相反,这个函数会从屏幕读取用户从键盘输入的数据
value = input("请输入一个爹:")
//value是变量,所输入的数据会存储到这个变量中,input接收你输入的无论是字符串或者数字,一律为字符串类型,
如果要执行数学运算需要int()转换为整形。
//input里边的字符串是提示内容,对于输入的内容不影响
print(f"类型为:{type(value)},{value}") #类型为:<class 'str'>,my
13.流程控制
1.if elif else
if x>3:
print("x is greater than 3")
elif x<3:
print("x is less than 3")
else:
print("x is equal to 3")
2.三元运算符
1.you = '学爬虫' if nx > 0 else '学个毛'
2.嵌套三元运算
1.you = '学爬虫' if nx > 1 else '学个毛' if nx < 0 else '人才啊'
2.等价于:
if nx > 1:
you = '学爬虫'
elif nx < 0:
you = '学个毛'
else:
you = '人才啊'
3.流程控制-循环语句for
1.关键字 for x in y:
for 是关键字
x 是变量名
in 是关键字
y 是一个可迭代对象类型
range() 内置函数,用于生成一个整数序列,常用于循环的对象
range() 用于生成一个整数序列。最多接收三个参数。常用与for循环
第一个参数,起始值
第二个参数,结束值
第三个参数,步长
列表
元组
字符串
集合
字典
2.基本操作
循环字符串
message = "Hello, wocao!"
for i in message:
print(i)
循环列表
hi = ["hello", "world", "wocao"]
for h in hi:
print(h)
循环字典
person = {"name": "yg", "age": 30, "city": "BJ"}
for key in person:
print(key)
person = {"name": "yg", "age": 30, "city": "BJ"}
for key, value in person.items():
print(key, value)
循环集合
p = {'hello',233,'world','wocao'}
for i in p:
print(i)
循环元组
y = (1,2,3,4,5,6)
for i in y:
print(i)
支持多个变量循环
a = ['1','2']
b = ['3','4']
for j,k in a,b:
print(j)
print(k)
嵌套循环
for i in range(10):
for j in range(10):
print('j',j)
3.break 和 continue 同其他语言
4.while 语句
while True:
print("hello world")
14.函数
1.格式定义
def 函数名(参数1,参数2,参数n):
"""函数批注"""
程序代码 # 缩进
return 返回值
2.解释
关键字:def
函数名:必须写而且唯一,后边必须加小括号,因为后续程序需要调用,命名规则和变量相同,
按照PEP8的话建议第一个英文字母用小写
参数:可有可无,根据程序需要是否传入参数进行处理,参数调用逗号分开。
函数批注:可有可无,大型程序设计时建议添加批注,比如写参数传的类型,函数的功能等三个单引号和三个双引号都可以,
可以是多行批注,写了就比较专业!
return:可有可无,如果没有return的话,调用赋值打印只会输出一个None,所以我们每个函数应该有返回值,方便调用也方便调试。
3.简单的函数
def myPrint(txt):
print(f"txt:{txt}")
def url1(btm_ppre,bb,cc="cc.00"):
url = "https://abc.com/control?"
res = f"{url}btm_ppre={btm_ppre}&bb={bb}"
return res
url = url1("a0.b0.c0.d0","bb.bb") # 动态传参
4.关键词参数 参数名=值 可以不按顺序传参 但是要以这种格式
1.url = url1(bb="bb.bb",btm_ppre="a0.b0.c0.d0") # 动态传参
2.默认传参 def url1(btm_ppre,bb,cc="cc.00") // cc 有个默认的数值 可以传可以不传
5.指定参数类型(注解)
1.可以让写代码的人和调用代码的人注意,应该传什么类型,代码并不会真的去验证,只是写代码的时候会变黄,规范性写法
2.def url1(page: int, btm_ppre: str, btm_prem: str, btm_show_id: str) -> None:
def url1(*pc):
print(pc)
url1("爬虫","JS","Python") # ('爬虫', 'JS', 'Python')
1.指定返回为None
6.参数传递的不能指定默认值 args和kwargs是约定俗成的接受传参的名字,也可以写成其他的
def url1(*args,**kwargs):
print(args) # ('爬虫', 'JS')
print(kwargs) #{'bb': 'Python'}
url1("爬虫","JS",bb="Python")
7.函数当参数传递
def f1():
return "实现第一个功能"
def f2(one):
# print(one)
return f"{one},实现第二个功能"
res = f2(f1()) # 这里也可以 f2(f1)) 传函数 而不执行 到函数内部执行
print(res) # 实现第一个功能,实现第二个功能
8.函数传参与args参数结合
def f1(*args):
return sum(args[0])
def f2(func, *args):
return func(args)
res = f2(f1, 1, 2, 3, 4, 5, 6)
print(res) # 21
9.返回 多个变量 tuple , Dict
def abc():
return 1,2,"a","b"
print(abc()) # (1, 2, 'a', 'b')
10.函数的嵌套
def c_tmd(a):
def string(x):
return f"传入了一个字符串:{x}"
def ints(x):
return f"传入了一个数字:{x}"
def lst(x):
return f"传入了一个列表:{x}"
def dicts(x):
return f"传入了一个字典:{x}"
res = type(a)
print(res == str) # True 这里 type 的结果居然 真等于 str 虽然 print 显示 <class 'str'>
if res == str:
return string(a)
elif res == int:
return ints(a)
elif res == list:
return lst(a)
elif res == dict:
return dicts(a)
else:
print("处理不了当前的传值")
res = c_tmd("123")
print(res) # 传入了一个字符串:123
11.闭包
1.具体来说,闭包包括以下几个要素:
1.内部函数:在某个函数内部定义另一个函数。
2.外部函数:定义内部函数的那个原始函数。
3.变量引用:内部函数能够通过外部函数中的变量进行操作。
4.返回值:当你在外部函数中使用`return`语句后,通常会返回一个指向内部函数的引用。
def outer():
b = 10
def inner(x):
return b + 1 + x
return inner
b = 2
f = outer()
print(f(b))
2.用闭包写一个计数器
def counter(start_at=0):
count = [start_at]
def incr():
count[0] += 1
return count[0]
return incr
calc = counter()
print(calc()) // 1
print(calc()) // 2
print(type(calc())) // <class 'int'>
12.递归
1.写一个阶乘函数
def factorial(n):
# 基础情况
if n == 0 or n == 1:
return 1
# 递归情况
else:
return n * factorial(n - 1)
res = factorial(5)
print(res)
2.斐波那契数列
def fibonacci(n):
# 基础情况
if n <= 0:
return 0
elif n == 1:
return 1
# 递归情况
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(5))
常见模块
1.requests
1.主要特点:
1.简单易学
2.功能全
3.会话管理,可以会话保持
4.支持上传下载
5.支持ssl证书验证
6.支持代理
7.支持cookie
8.默认自动重定向
9.异常处理
2.pip install requests 安装
3.请求
1.get requests.get() 传入参数:
1.url
2.headers
3.timeout
4.data
5.json
6.parmas
7.cookies
8.verify
9.proxies
proxies = {
"http": "http://117.80.203.24:8118",
}
requests.get("http://httpbin.org/ip", proxies = proxies,timeout=3)
10.allow_redirects
2.response 无论发送什么请求都会返回一个response对象
response.text 响应文本
返回的字符串数据,文本数据,json数据,包括密文数据。
根据HTTP 头部对响应的编码推测的文本编码
response.encoding="utf-8" 修改编码
respones.content 响应二进制数据或bytes数据
返回视频数据,图片数据,音乐数据等二进制数据
print(response.content.decode("utf-8"))
print(response.content.decode())
print(response.text)
content.decode("utf-8")解码
response.status_code http响应状态码
response.headers 响应header
response.cookies 响应的cookie
1.print(requests.utils.dict_from_cookiejar(response.cookies)) 把cookies转化为字典
2.print(response.cookies.get_dict()) 同上面作用一样
response.encoding 响应网站字符集编码 赋值是设置 不赋值是打印当前
response.json() 如果返回json可以直接用这个方法转成字典
response.url 返回响应的最终 URL 重定向的时候有用
response.raise_for_status() 如果状态码不是200会抛异常 主动结束程序运行
response.request.headers 返回请求header
response.request.body 返回请求body
response.request.url 返回请求url
session 请求
// 创建一个会话对象
session = requests.session()
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36',
}
response = session.get('https://www.baidu.com',headers=headers)
print(response.cookies)
response = session.get('https://www.baidu.com', params={'key': 'value'})
可以在会话对象中设置全局参数,如超时时间
session.timeout = 10
print(response.request.headers)
4.杂项
1.报错
1.请求https站点报错
ssl.CertificateError开头的报错
添加verify=False 让请求不验证服务器ssl证书
response = requests.get(url,verify=False)
2.代理
1.常见的代理网站(仅用于学习)
66免费代理网 http://www.66ip.cn/
89免费代理 http://www.89ip.cn/
站大爷 https://www.zdaye.com/free/
无忧代理 http://www.data5u.com/
云代理 http://www.ip3366.net/
快代理 https://www.kuaidaili.com/free/
2.代理分类
透明代理(Transparent Proxy):不对请求做任何修改,客户端和服务器都知道对方的存在。
匿名代理(Anonymous Proxy):隐藏客户端的真实 IP 地址,但服务器知道请求来自代理。
高匿代理(Elite Proxy):隐藏客户端的真实 IP 地址,服务器无法知道请求来自代理
3.传输协议分类
HTTP代理:只能代理HTTP流量。
HTTPS代理:可以代理HTTPS流量,支持SSL加密传输。
SOCKS代理:支持多种协议的代理,如HTTP、HTTPS、FTP等
3.retry
from retrying import retry
@retry(stop_max_attempt_number=3) // 尝试次数
def parse_url():
# 超市就会报错并且重试
print("开始请求...")
response = requests.post("https://www.baidu.com", timeout=3)
assert response.status_code == 200, '状态码不正确'
return response
4.curl 复制后 可以在 splidertools.cn 转 python
2.json
1.dumps
1.正常把 字典 转为 字符串
import json
dict1 = {
"name": "小明",
"age": 18
}
j1 = json.dumps(dict1)
print(type(j1)) #<class 'str'>
print(type(dict1)) #<class 'dict'>
print(dict1) # {'name': '小明', 'age': 18} 单引号 就算定义的时候是双引号
print(j1) # {"name": "\u5c0f\u660e", "age": 18}
2.参数
1.dumps配置参数
indent 美化输出指定缩进的空格数,用于美化输出的JSON字符串。例如,indent=4表示使用4个空格缩进,默认值为None,表示不缩进。
ensure_ascii 不适用非ascii字符转义,也就是保持中文,别把中文转成Unicode, 默认不加他会自动转成Unicode编码
sort_keys 指定是否按照键的字母顺序对JSON对象进行排序。默认值为False,表示不排序。如果设置为True,则会按照键的字母顺序进行排序。
separators 指定分隔符的字符,用于控制JSON字符串中各个元素之间的分隔方式。
默认separators=(",",":")
2.代码举例
import json
data = {"name": "yg", "age": 18, "techang?": "长"}
d = json.dumps(data,indent=4,ensure_ascii=False,sort_keys=True,separators=(",",":"))
print(d)
2.loads
1.从字符串loads后转为字典
import json
data = '{"name": "yg", "age": 18, "techang?": "chang"}'
json_data = json.loads(data)
print(json_data) #{'name': 'yg', 'age': 18, 'techang?': 'chang'}
print(type(json_data)) #<class 'dict'>
2.从文件读取JSON数据 load 注意不是 loads
import json
with open("1.txt", "r") as f:
python_obj = json.load(f)
print(python_obj) # {'name': 'yg', 'age': 18, 'techang': 'chang'}
print(type(python_obj)) # <class 'dict'>
3.将字典以 json 格式 写入 文件
import json
data = {"name": "yg", "age": 18, "techang": "chang"}
with open("2.txt", "w") as f:
json.dump(data,f)
3.pyexecjs 模块 py运行js的pyexecjs模块
1.代码1 compile 编译后 call 调用
import execjs
// 创建一个运行时环境
ctx = execjs.compile(
这里是三个引号
function add(x, y) {
return x + y;
}
这里是三个引号
)
// 调用JavaScript函数
result = ctx.call("add", 1, 2)
print(result) # 输出3
2.代码2 Node 环境
import execjs
# 获取Node.js运行时环境
ctx = execjs.get("Node")
print(ctx)
# 编写和执行JavaScript代码
result = ctx.eval("1 + 2")
print(result) # 输出3
3.代码3 runtime
import execjs
# 获取一个可用的 JavaScript 运行时
runtime = execjs.get()
# 定义一个简单的 JavaScript 代码
js_code = """
function add(x, y) {
return x + y;
}
return add(3, 4);
"""
# 使用 JavaScript 运行时执行 JavaScript 代码
result = runtime.exec_(js_code)
print(result) # 7
4.代码4 runtime
import execjs
runtime = execjs.get()
result = runtime.eval("1 + 2")
print(result) # 3
runtime = execjs.get()
result = runtime.eval("new Date().getTime()")
print(result) #1713191124607
5.代码5 编译 并调用外部的 js
import subprocess
# 这个类需要重写一下 目的就是改变一下编码 encoding="utf-8" 否则下面的调用会报错 默认 encoding=None
class MySub(subprocess.Popen):
def __init__(self,*args,**kwargs):
super().__init__(encoding="utf-8",*args,**kwargs)
subprocess.Popen = MySub
import execjs
node = execjs.get()
# 创建运行时环境
with open("S:\project 2021\other\ChromeHelper\chrome tomorrow\逆战宇\\try\\111.js",encoding="utf-8") as f:
js_code = f.read()
ctx = node.compile(js_code,cwd="S:\project 2021\other\ChromeHelper\chrome tomorrow\逆战宇\\try\\node_modules")
# 调用外部 JavaScript 文件中的函数
data = 'aaaaaaaa'
result = ctx.call("callByPython",data) # 调用 111.js 里面的 函数 并传入参数 data js里面的 console.log() 不会执行
print(result) # 正常输出 UVjxz7/6x...
4.re 正则表达式模块
1.match 匹配不到返回 None
import re
data = "a测试数据:123456,hello222222,world"
res = re.match('^a.*:(\d+),.*o(\d+),.*', data)
print(res) # <re.Match object; span=(0, 30), match='a测试数据:123456,hello222222,world'>
print(res.group(0)) # a测试数据:123456,hello222222,world
print(res.group(1)) # 123456
print(res.group(2)) # 222222
print(f"{res.span()},{res.start()},{res.end()}") #(0, 30),0,30
2.关于分组
1.匹配分组
1.| 匹配符号左右任意一个表达式
2.(ab) 小括号中的字符作为一个分组
3.\n 引用之前的分组匹配中的规则匹配到的结果当作规则匹配
import re
text = "hello hello"
pattern = r"(\w+)\s\1" #\1 引用前面的子匹配
matches = re.match(pattern, text)
print(matches.group(0)) # hello hello
print(matches.group(1)) # hello
4.(?P) 是正则表达式中用于给捕获组命名
import re
text = "2024-03-24"
pattern = r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})"
matches = re.match(pattern, text)
if matches:
print("Year:", matches.group('year')) # Year: 2024
print("Month:", matches.group('month')) # Month: 03
print("Day:", matches.group('day')) # Day: 24
else:
print("No match found.")
5.(?P=name) 引用之前命名的捕获组
3.关于第三个参数 正则表达式修饰符
1.re.I 忽略大小写
2.re.M 匹配多行
3.re.S 。可以匹配所有 包括换行
5.time 模块
1.代码
import time
ts = time.time()
print(ts) # 1713201793.921693
print(type(ts)) #<class 'float'>
print(int(ts)) #1713201793 10位
print(int(ts*1000)) #1713201793921 13位
ts = time.localtime()
print(ts) #time.struct_time(tm_year=2024, tm_mon=4, tm_mday=16, tm_hour=1, tm_min=22, tm_sec=24, tm_wday=1, tm_yday=107, tm_isdst=0)
print(f"{ts.tm_year},{ts.tm_mon},{ts.tm_mday}") #2024,4,16
print(time.mktime(ts)) #1713201793.0
print(time.strftime("%Y-%m-%d %H:%M:%S")) #2024-04-16 01:27:36
print(time.strptime('2018-05-10',"%Y-%m-%d")) # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=10, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=130, tm_isdst=-1)
print(time.strptime("2018-01-24 11:31:16","%Y-%m-%d %H:%M:%S")) #time.struct_time(tm_year=2018, tm_mon=1, tm_mday=24, tm_hour=11, tm_min=31, tm_sec=16, tm_wday=2, tm_yday=24, tm_isdst=-1)
time.sleep(0.5)
6.lxml 模块 xpath
from lxml import etree
html = etree.HTML(text)
# print(html) # <Element html at 0x2004fc8>
# print(etree.tostring(html).decode("utf-8")) # 打印出网站代码
res = html.xpath('//*') # [<Element html at 0x1f24d68>, <Element head at 0x2101528>]
res = html.xpath('//tr/td')# [<Element td at 0x1721768>, <Element td at 0x17216c8>]
#获取指定节点用text()方法取值
print(res[0].xpath("./text()")) # ['\n 111.225.152.47\n ']
#获取子节点
res = html.xpath("//tr[1]/td[1]/text()") # ['\n 111.225.152.47\n ']
#获取父节点
res = html.xpath("//tr[1]/td[1]/../td") # 等价于 html.xpath("//tr[1]/td")
#属性匹配
res = html.xpath("//tr[1]/td[1]/parent::*/td[@class='ip']/text()") # parent::* 回到了 tr
#属性获取
res = html.xpath("//a/text()") #['去百度', '去百度1']
res1 = html.xpath("//a/@href") # ['http://www.baidu.com', 'http://www.baidu1.com']
#属性多值匹配 contains 和 and or 搭配
res = html.xpath("//a[@class=a]") # 如果有两个 class a a1 写一个匹配不到
# res = html.xpath("//a[@class=‘a a1’]") # 这么写两个直接报错
print("-------------------")
res = html.xpath("//a[contains(@class,'a a1')]/text()") #['去百度'] 一个属性值还是多个属性值都可以用
res = html.xpath("//a[contains(@class,'a')]/text()") #['去百度'] 一个属性值还是多个属性值都可以用
res = html.xpath("//a[contains(@name,'a2') and contains(@class,'a')]/text()") #contains 类似 寻找文本
res = html.xpath("//a[contains(@name,'a2') and contains(@name,'a3')]/text()") # and
res = html.xpath("//a[contains(@name,'a2') or @names='qbd']/text()") # or
res = html.xpath("//a[not(text()='去百度')]/text()") # not 取反
res = html.xpath("//a[last()]/text()") # 最后一个
res = html.xpath("//a[last()-1]/text()") #倒数第二个
res = html.xpath("//a[position()>1]/text()") # position() 位置 > < = 某个位置
res = html.xpath("//a[position()>1 and position()<4]/text()") # 精确选择 选第2和3节点
#条件取值 通过 [text()=] 和 [@xxx=] [@xxx!=]都可以
res = html.xpath("//tr/td[3][text()='河北省张家口市']/text()")
res = html.xpath("//a[@href='http://www.baidu.com']/@href")
res = html.xpath("//a[@href!='http://www.baidu.com']/@href")
7.selenium自动化工具
1.简介
1.Selenium是一个用于自动化Web应用程序测试的工具。它提供了一组API(应用程序编程接口),允许开发人员以多种编程语言(如Python、Java、C#等)编写测试脚本,用于模拟用户在浏览器中的操作。这些操作可以包括点击链接、填写表单、提交数据等,从而可以对Web应用程序进行功能测试、回归测试等。
2.Selenium支持多种浏览器,包括Chrome、Firefox、Edge等主流浏览器,可以在不同的浏览器中运行测试脚本。它还支持不同的操作系统,如Windows、Linux、macOS等。
3.除了自动化测试外,Selenium还可以用于网页数据抓取、网页内容提取等应用场景。由于其灵活性和强大的功能,Selenium被广泛应用于软件开发和测试领域。
2.安装
以谷歌浏览器为例:
新版本安装:https://chromedriver.com/
老版本安装:https://chromedriver.storage.googleapis.com/index.html
3.打开 python 在执行完毕代码后 chrome 浏览器会自动关闭 如果想让chrome不关闭 想办法让 py 代码一只执行
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
CHROMEDRIVER_PATH = r"G:\Python3.9.13\chromedriver.exe"
svc = Service(executable_path=CHROMEDRIVER_PATH)
browser = webdriver.Chrome(service=svc)
browser.get("https://www.baidu.com")
4.基础语法
1.声明浏览器对象
from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.PhantomJS()
browser = webdriver.Safari()
2.访问网页
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
browser.get("https://spidertools.cn/#/curl2Request")
browser.get("https://extfans.com/search/?q=listen")
3.查找element对网页进行操作
1.基本用法
from selenium.webdriver.common.by import By
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
# find_element是查询一个 send_keys 在标签内输入
browser.find_element(By.NAME,'wd').send_keys("python")
# .click() 点击当前标签
browser.find_element(By.ID,"su").click()
2.这里还可以不用By.xx因为这只是一个字符串的对应关系
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
browser.find_element("name",'wd').send_keys("python")
3.元素定位
1.找到元素后 不能用 /text() 取文本 要用自己的方法
res = browser.find_element(By.XPATH,"//tr/td[1]")
print(res.get_attribute("class")) # 取类名
res1 = res.get_attribute("innerHTML") # 取元素代码
res1 = res.get_attribute("innerText") # 取元素文本
4.截屏
1.browser.get_screenshot_as_file('bd.png')) 全屏幕截图
2.form1.screenshot("form1.png")#给这个元素截图
5.关闭浏览器
browser.quit() # 退出
browser.close()# 关闭
6.cookie操作
1.获取cookie
1.browser.get_cookies()
1.区别get_cookies()直接调用 会返回一个cookis的json 列表套字典
[{'domain': 'www.baidu.com', 'httpOnly': False, 'name': '666', 'path': '/', 'sameSite': 'Lax', 'secure': True, 'value': '999'}, {...]
cookies = browser.get_cookies()
cookies_dict = {cookie['name']:cookie["value"] for cookie in cookies}
2.browser.get_cookie()
1.zfy = browser.get_cookie("ZFY")
2.删除cookie
browser.delete_all_cookies()
browser.delete_cookie("ZFY")
3.设置cookie
add_cookie() 传入一个字典 传name和value
{"name":"xx","value":"xx"} 如果name
7.获取网页源代码
browser.page_source
browser.page_source.encode('utf-8')
8.执行js代码
js_code1 = "var a = navigator.webdriver;alert(a);"
browser.execute_script(js_code1)
time.sleep(5)
9.切换标签页
1.代码
browser.switch_to.window(browser.window_handles[1])
browser.switch_to.window(browser.window_handles[2])
2.可以通过判断是否还有标签页 让 py 代码处于执行状态 关闭所有tab页后 就为 0 了
while len(browser.window_handles) > 0:
pass
3.不同页面切换 和 在切换到的tab下面 打开新的网址
browser.get('https://www.baidu.com')
time.sleep(1)
browser.execute_script('window.open("https://www.taobao.com")')
time.sleep(2)
browser.switch_to.window(browser.window_handles[0])
browser.get('https://www.jd.com')
time.sleep(1)
browser.switch_to.window(browser.window_handles[1])
browser.get('https://www.baidu.com')
time.sleep(10)
10.前进后退
borwser.forward() # 前进
borwser.back() #后退
11.滑动
1.常见代码
window.scrollBy(x,y)
window.scrollBy(0,300) # 运行一次就滑动一次
window.scrollTo(0,300) # 一步到位,多次运行也是一样结果
driver.execute_script('window.scrollBy(0, 1000);')
2.滑动到底部
# 向下滑动到页面底部
browser.execute_script('window.scrollTo(0, document.body.scrollHeight);') # 最大body距离 document.body.scrollHeight
# 滑动到顶部
browser.execute_script('window.scrollTo(0,0);')
# 当前y轴位置
y = browser.execute_script("return window.scrollY")
print(y)
3.慢慢滚
for i in range(10):
time.sleep(0.5)
browser.execute_script(f'window.scrollTo(0,{i * 300})')
5.经验用法
1.配置项 使用配置对象
1.不让浏览器提示 有自动化程序控制 的提示
option = webdriver.ChromeOptions()
# 解决谷歌浏览器提示“Chrome正在受到自动化测试软件的控制”
option.add_experimental_option("useAutomationExtension", False)
option.add_experimental_option("excludeSwitches", ["enable-automation"])
# option.add_argument(‘–headless’) # 给chrome_options添加headless参数
browser = webdriver.Chrome(options=option)
2.综合配置项
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
# 解决谷歌浏览器提示“Chrome正在受到自动化测试软件的控制”
options.add_experimental_option("useAutomationExtension", False)
options.add_experimental_option("excludeSwitches", ["enable-automation"])
# 无头模式 在后台运行 装逼用的
# options.add_argument("-headless")
# 设置代理
# options.add_argument("--proxy-server=http://123.33.251.23:8080")
# 设置浏览器大小
options.add_argument("--window-size=1920,1080")
# 禁用浏览器通知
options.add_argument("--disable-notifications")
# 通过设置user-agent
ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537111111.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36'
options.add_argument(f'user-agent={ua}')
# 禁用扩展程序
options.add_argument("--disable-extensions")
# 设置浏览器语言
options.add_argument("--lang=zh-CN")
# 启用开发者模式 打开的时候自动开启f12
options.add_argument("--auto-open-devtools-for-tabs")
# 禁止自动化提示
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
# 禁用自动化控制接口实现防止被检测
options.add_argument('--disable-blink-features=AutomationControlled')
# 禁止图片
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
# 安装插件
extension_path = r'S:\project 2021\other\ChromeHelper\chrome tomorrow\commonPlugs\xpath\xpath.crx'
options.add_extension(extension_path)
# 初始化配置
browser = webdriver.Chrome(options=options)
# 将浏览器最大化显示
# browser.maximize_window()
browser.get("https://www.baidu.com")
# 设置宽高
# browser.set_window_size(480, 800)
# 通过js新打开一个窗口
# browser.execute_script('window.open("http://httpbin.org/ip");')
2.稍微综合用法
browser.get("https://www.baidu.com/")
browser.find_element(By.NAME,'wd').send_keys("python")
browser.find_element(By.ID,"su").click()
print(browser.page_source.encode('utf-8')) #获取网页源码
print(browser.get_cookies()) # 获取cookies
print(browser.get_screenshot_as_file('123.png')) # 保存图片
print(browser.current_url) #获取当前路径
time.sleep(10)
3.等待 某个/全部 元素加载完毕
1.基本代码
# 等待某个标签加载,如果没加载就抛出异常
wait.until(EC.presence_of_element_located((By.ID,"key")))
# 等待符合条件的标签全部加载完成
wait.until(EC.presence_of_all_elements_located((By.ID,"key")))
2.用法举例
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
option = webdriver.ChromeOptions()
# 解决谷歌浏览器提示“Chrome正在受到自动化测试软件的控制”
option.add_experimental_option("useAutomationExtension", False)
option.add_experimental_option("excludeSwitches", ["enable-automation"])
# option.add_argument(‘–headless’) # 给chrome_options添加headless参数
browser = webdriver.Chrome(options=option)
wait = WebDriverWait(browser,10)
browser.get("https://www.baidu.com")
# 等待某个标签加载,如果没加载就抛出异常
wait.until(EC.presence_of_element_located((By.NAME,"key")))
# 等待符合条件的标签全部加载完成
wait.until(EC.presence_of_all_elements_located((By.ID,"key")))
3.用法举例2
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.remote.webelement import WebElement
from time import sleep
import traceback
chrome_options = Options()
chrome_options.add_argument('--headless')
# chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options=chrome_options)
# driver.maximize_window()
# driver.get("https://www.baidu.com")
driver.get("https://www.baidu.com")
print(driver.title)
# 繁体字
html = driver.execute_script("return document.documentElement.outerHTML")
try:
element = WebDriverWait(driver, 360).until(EC.presence_of_element_located((By.CLASS_NAME, "s-top-left-new")))
# driver.find_element_by_id("").
eles = driver.find_elements(By.XPATH, "//ul[@id='hotsearch-content-wrapper']/li")
print(eles)
eles = [ele.text for ele in eles]
for ele in eles:
print(f"news:{ele}")
except (Exception, e):
traceback.print_exc()
html = driver.execute_script("return document.documentElement.outerHTML")
sleep(3)
8.csv 模块
import csv
with open('data.csv', 'r+', encoding='utf-8',newline="") as f:
# 第一种 写法
# data = ["id","name","age"]
# writer = csv.writer(f)
# writer.writerow(data)
# writer.writerow(["1","zs",50])
# writer.writerow(["2","zs1",51])
# writer.writerows([["3","zs2",52],["4","zs3",53]])
# 第二种 写法
# writer = csv.DictWriter(f,fieldnames=["id","name","age"])
# writer.writeheader()
# writer.writerow({"id":"1","name":"zs","age":50})
# writer.writerow({"id":"2","name":"zs2","age":51})
# writer.writerow({"id":"3","name":"zs3","age":52})
#第一种 读法
# reader = csv.reader(f)
# for row in reader:
# print(row) # ['id', 'name', 'age']
#第二种 读法
reader = csv.DictReader(f)
for row in reader:
print(row) # {'id': '3', 'name': 'zs3', 'age': '52'}
杂项相关
1.路径相关
1.路径一般情况下不用转义 但是 遇到 \try 这种就需要写成 \\try \111.js \\111.js 数字也需要转义
2.字符串相关
1.字符串前面有r a = r"a\tb" r表示的是这个字符串是原始字符串 所有的\不具备转义 功能
import re
text1 = "app le"
matches1 = re.match('app\\sle', text1)
print(matches1) # <re.Match object; span=(0, 6), match='app le'>
matches1 = re.match(r'app\\sle', text1)
print(matches1) # None
2.b"123" == "123".encode("utf-8") # True 结果 都是字节集
3.关于混淆
1.常见的代码混淆手段
1.压缩代码
2.字符串加密(AES Base64)
3.代码分拆和重组(将原始代码分拆为很多片段 以不同的顺序重组)
4.变化语法来增加代码复杂性
5.无意义的代码插入
6.控制流混淆 (JavaScript Obfuscator 和 Closure Compiler)
7.代码加密 (WASM)
2.混淆的弊端
1.增大代码的体积 浪费流量
3.混淆的网址
1.https://www.jsjiami.com/jsfuck.html
4.关于各种编码
1.encode 结果是返回的字节集
a = "123"
print(a.encode("utf-8"))
5.异常处理
1.代码
try:
a = 1/0
#except Exception as e: 这种写法任意错误都可以 当然错误分很多种
except ZeroDivisionError as e:
print(e) #division by zero 零不能作除数 所以报错
else:
print("No exception") # 如果不发生异常 走这里
finally:
print("Finally") # Finally 无论怎样都走这里
print("over")
6.装饰器
1.装饰器代码
#定义装饰器 被装饰的函数 当作参数 传入到 return 的函数 中去
def outer(func):
def wrapper(*args, **kwargs):
print('begin')
func(*args, **kwargs)
print('end')
return wrapper
@outer
def login(*args,**kwargs):
print("login.....")
#输出结果
#begin
#login.....
#end
if __name__ == '__main__':
login(user='admin',pwd='123')
7.类
1.类的三个属性
1.__doc__ 参数说明
2.__name__ print(__name__) # 如果是执行文件 __main__ 如果是类的话 __main__ 是包名
class Animal(object):
def __init__(self):
self.name = __name__
def __str__(self):
return "Anmial Info"
animal = Animal()
print(animal.name) # __main__ 如果在类文件里面调用
from test import Animal
animal = Animal()
print(animal.name) # test 如果 在引用类的文件里面调用 会输出 两条 test 也就是说 上面的 __main__ 也会变
1.所以有 if __name__ = "__main__" 来判断 说明在类内部运行
3.__str__
class Animal(object):
def __init__(self):
self.name = __name__
def __str__(self):
return "Anmial Info"
if __name__ == "__main__":
animal = Animal()
print(animal.name) # __main__
print(Animal()) # "Anmial Info"
python 简单的类结构
class Car:
def __init__(self, make, model, year):
self.__make = make # 私有变量
self.__model = model # 私有变量
self.__year = year # 私有变量
def get_make(self):
return self.__make # 通过公共方法访问私有变量
def set_make(self, make):
self.__make = make # 通过公共方法修改私有变量
car = Car("Toyota", "Camry", 2022)
print(car.get_make()) # 输出: Toyota
car.set_make("Honda")
print(car.get_make()) # 输出: Honda
# 尝试直接访问私有变量
print(car.__make) # 报错: AttributeError: 'Car' object has no attribute '__make'
简单的 继承 Animal Dog
class Animal:
def __init__(self, name, age):
self.name = name
self.__age = age
def speak(self):
print("I am an animal")
def say_name(self):
print(f"My name is {self.name},age is {self.__age}")
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age)
self.breed = breed
def speak(self):
print("I am a dog")
dog = Dog("FuGui", 3, "Labrador")
dog.speak() # I am a dog
dog.say_name() # My name is FuGui,age is 3
print(dog.name) # FuGui
print(dog.__age) # AttributeError: 'Dog' object has no attribute '__age' 私有 属性外部不可以访问
复杂的 Animal Dog 继承
class Animal:
def __init__(self, name="animal", age=99):
Person("Animal Constructor")
self.name = name
self.__age = age
def speak(self):
print("I am an animal")
def say_name(self):
print(f"My name is {self.name},age is {self.__age}")
def stand(self):
print("Animal is standing")
def aniaml_id(self):
print("Animal id is 123")
class Person:
def __init__(self, name, age):
print("Person Constructor")
self.name = name
self.__age = age
def stand(self):
print("Person is standing")
class Dog(Person,Animal): # 多继承 谁在前面 谁的方法 优先 比如 stand 可以理解为 作用域链 找到就不再继续找了
def __init__(self, name, age, breed):
super().__init__(name, age) # 这里的 super() 是父类 Person 谁在前面执行 谁的构造方法
#整个过程 Animal super() 的 构造函数没有执行 也就是说 构造方法没有执行
# 想调用 Animal 的构造函数
self.breed = breed
def speak(self):
print("I am a dog")
def eat():
print("Dog can eat")
dog = Dog("FuGui", 3, "Labrador")
dog.stand()
dog.speak() # I am a dog
dog.aniaml_id() # Animal id is 123 虽然 Animal 的 构造函数 __init__ 没有执行 但是方法依然是继承了
# dog.say_name() # My name is FuGui,age is 3 如果 Dog 多继承时候 Animal 放后面 由于 constructor 没有执行 所以这个方法报错
print(dog.name) # FuGui
# print(dog.__age) # AttributeError: 'Dog' object has no attribute '__age' 私有 属性外部不可以访问
Dog.eat() # Dog can eat 不需要 私有属性装饰器 @staticmethod 好像也没问题
8.模块的封装
1.单文件 Animal.py
1.代码
class Animal(object):
def __init__(self,name,brand,age):
self.name = name
self.age = age
self.brand = brand
def speak(self):
print("I am a {} and I am {} years old".format(self.name,self.age))
def add(a,b):
print(a+b)
import Animal
animal = Animal.Animal("Dog", "Brown", 4)
animal.speak() # I am a Dog and I am 4 years old
Animal.add(1,2) # 3
animal.add(2,3) # ttributeError: 'Animal' object has no attribute 'add'
from Animal import Animal
1.如果用这种模式调用 Animal.add(1,2) # 这个也会报错 因为只是调用了文件Animal 里面的 类
2.多文件
1.其实就是一个文件夹下面有很多个 py 文件
2.需要文件夹下有一个 __init__.py 的空文件 即可
3.代码
#add.py
def add(a,b):
return a + b
#Animal.py
class Animal(object):
def __init__(self,name,brand,age):
self.name = name
self.age = age
self.brand = brand
def speak(self):
print("I am a {} and I am {} years old".format(self.name,self.age))
#MulDiv.py
def mult(a,b):
return a*b
def div(a,b):
return a/b
#调用文件
from myMath.Animal import Animal
from myMath.add import add
from myMath.MulDiv import mult,div
animal = Animal("dog","wangwang",3)
animal.speak()
print(add(1,2)) # 3
print(mult(3,2)) #
print(div(3,2)) # 1.5
9.数据库
1.mysql
1.代码
import pymysql
import time
db = pymysql.connect(host='localhost',user='root',password='abc',db='abc')
cursor = db.cursor() # 需要 cursor 去执行 语句 但是 提交 commit 和 close 需要 db
#查询
res = cursor.execute("select * from de_data limit 205,50") # 返回查询到的条数
data = cursor.fetchall() # 获取到查询的所有结果
for i in data:
print(list(i)) # tuple 结果 每条
pass
#插入
sql = "insert into de_data (email,other_pwd) values (%s,%s)" # 返回查询到的条数
values = ('python001@gmail.com','abcdefg') # 数据单独写进values
res = cursor.execute(sql,values) # 执行sql并替换 values 执行后的结果返回一个整数 表示影响的行数
res = db.commit() # 然后 db 提交 不返回任何东西 None
db.close() # 关闭 Db
2.mongodb
1.代码
import pymongo
client = pymongo.MongoClient(host="localhost", port=27017) # MongoClient(host=['localhost:27017']...)
db = client["tt"] # 选择数据库 Database(MongoClient(host=['localhost:27017'],... 'tt')
table = db["abc_1"] # 选择表 Collection(Database(MongoClient(host=['localhost:27017'], ... 'tt', 'abc_1')
# 插入数据
data = {"name": "zhangsan", "age": 18, "sex": "男"} # 数据的列表可以没有 没有就自动添加一行
res = table.insert_one(data) # InsertOneResult(ObjectId('662793daf302de51214b7247'), acknowledged=True)
data2 = [{"name": "lisi", "age": 20, "sex": "女"}, {"name": "wangwu", "age": 22, "sex": "男"}]
res = table.insert_many(data2)
print(res) #InsertManyResult([ObjectId('6627943d0f8ccbc8eb75f552'), ObjectId('6627943d0f8ccbc8eb75f553')])
res = table.find()
for i in res:
print(i) # {'_id': ObjectId('662797f32f994fd3350c0615'), 'name': 'zhangsan', 'age': 18, 'sex': '男'}
课件相关
https://docs.qq.com/sheet/DREJyckVrcEV6WVlU?tab=000001
教学案例(随用随更):【腾讯文档】爬虫百例-宇哥实战 :群文件自取
测试练习题 :【腾讯文档】测试练习题 (都是实战)
https://docs.qq.com/doc/DRGR0cENDWk9xd21R
课件资料:群文件自取
ps:没有基础或基础不好不要跳着看
Python课件更新中:https://docs.qq.com/doc/DREFKSHFSc2ZQTll4