python学习
Python学习
input输入
==python对缩进有着严格的要求,这里的print和input都是顶格写==
1 | #input()内的作用和print()一样,都是打印,但是如果这样操作,输入不会换行 |
1 | What is your name ?123 #他会让你输入一些数据,123是我输入的数据 |
算术运算符
1 | print("1+1=",1+1) |
1 | 1+1= 2 |
精确度和字符串拼接
1 | name="YYSSH" |
1 | My name is YYSSH My number is 1 |
while循环\for循环
1 | num = 1 |
1 | 5050 |
1 | name="itheima is a brand of itcast" |
1 | 4 |
函数
==def定义带有名称的函数==
1 | def 函数名: |
==lambda定义匿名函数==
只能被调用一次(因为没有名字),但可以多次写
1 | lambda x,y:x+y #只能有一行函数体,冒号后面的即是return返回值也是函数体 |
传参
1 | def user_info(name,age,gender): |
1 | def user_info(name,age,gender="男"): #只能在后面设置默认值,也就是默认值后面不允许不是默认值的 |
1 | def user_info(*args): #规定叫args,不用也可以*a,*b |
序列(列表、元组、字符串)
列表
增删改查
1 | ##增加 |
1 | [1, 'y', 2, 3, 4, 5] |
1 | ##删除 |
1 | [1, 2, 4, 56, 6, 7] |
1 | ##修改 |
1 | [1, 2, 3, 4, 56, 999999, 8, 1] |
1 | ##查询 |
1 | 4 |
1 | ##统计 |
1 | 2 |
1 | ##清空 |
1 | [] |
1 | ##求列表大小 |
1 | 7 |
字符串
字符串转大小写
1 | name='pyThOn' |
1 | my_str=("YYSSH") |
1 | Y,H |
元组
1 | ###########定义元组 :元组不可以被修改 tuple |
1 | (1, 1, 1, 1, 1, 1, 23, 577, 'jianjian') |
==序列 连续、有序、支持下标索引 e.g.(列表、元组、字符串)==
1 | my_list=[1,2,3,4,5,6,7] |
1 | [1, 2, 3, 4, 5, 6, 7] |
1 | #练习案例:序列的切片实践 |
1 | <class 'str'> |
集合
1 | ############### 集合 无序、所以不支持下标索引和while循环遍历 去重、集合里面不允许有重复的数据存在 |
1 | set() |
字典
1 | # 定义字典 |
容器的不同
==都支持len\max\min\sorted(序列,[reverse=True])==
==使用sorted函数之后容器会变成列表==
==字典转序列除了字符串,其他都会丢失值==
字符串的比较
1 | 通过ascii码表一位一位比较,只要前面有一位比后面大,整体就大 |
文件读取
1 | open(name,mode,encoding) |
循环读取文件数据
1 | for line in open("python.txt","r"): |
文件写入
1 | f=open(python.md,'w',encoding=UTF-8) |
异常
1 | try: |
异常可以传递
Python模块
1 | []:表示可选 |
pip国内网站源安装包
1 | pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 安装包名 |
python中json格式
可以使用python中的内置模块,将字典或者包含字典的列表转换为json格式
json.dump(data)
:将字典或者包含字典的列表转换为json格式json.load(data)
:将json转换为字典或者列表
python服务请求
bs4库一些常用函数说明
BeautifulSoup
(简称bs4
)是一个用于解析HTML和XML文档的Python库。它创建了一个解析树,从中可以提取和操纵数据。对于Python新手来说,BeautifulSoup
提供了一个非常直观和易于使用的接口来处理网页数据。以下是一些BeautifulSoup
中常用的函数和方法,以及它们的说明和作用:
BeautifulSoup
构造函数
1 | from bs4 import BeautifulSoup |
解析器解释
1 | 解析器的作用是将HTML文档(通常是一个字符串或字节序列)转换成一个树形结构,这个结构中的每个节点都对应着HTML文档中的一个元素(如标签、文本节点等)。BeautifulSoup提供了对这个树形结构的操作接口,允许你查找、修改和删除元素,以及提取文档中的数据。 |
find()
和 find_all()
1 | tag = soup.find('tagname') |
find_parents()
和 find_parent()
1 | parents = tag.find_parents('tagname') |
find_next_siblings()
和 find_next_sibling()
1 | siblings = tag.find_next_siblings('tagname') |
get_text()
1 | text = tag.get_text() |
attrs
和string
1 | attributes = tag.attrs |
navigable_string
和 set_navigable_string()
1 | new_string = BeautifulSoup("<new_string>", 'html.parser').navigable_string |
decode()
和 encode()
1 | decoded_string = soup.decode() |
requests.post/requests.get
1 | requests.post(url, data=None, json=None, headers=None, cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, proxies=None, stream=None, verify=None, cert=None, hooks=None) |
python脚本速写小技巧
format{}占位符
1 | soure_number='$(({}))' |
善用f_string格式化
在新版本的 Python 中(从 Python 3.6 开始),引入了 f-string(格式化字符串字面量),即通过在字符串前加上字母 f
来实现字符串插值,它比传统的 .format()
方法和 %
格式化更加简洁和高效。
基本语法
1 | f"Hello, {variable}!" |
f
表示这是一个格式化字符串。{variable}
是一个占位符,Python 会把variable
的值插入到字符串中。
1 | name = "Alice" |
输出:
1 | Hello, my name is Alice and I am 25 years old. |
在 f-string
中,任何在花括号 {}
内的表达式都会被计算并且结果会插入到字符串中。
支持的表达式
在 f-string
中,你不仅可以插入简单的变量,也可以使用复杂的表达式、函数调用、甚至条件判断。
- 变量插值
1 | name = "Bob" |
- 数学表达式
1 | x = 10 |
调用函数
1 | def greet(name): |
- 条件表达式
1 | age = 20 |
格式化选项
你还可以在花括号内使用格式规范来对插入的值进行格式化。格式化规范通常写在 :
后面。
常见格式化选项:
d
:十进制整数x
:十六进制整数(小写字母)X
:十六进制整数(大写字母)o
:八进制整数b
:二进制整数f
:浮点数,默认是小数形式e
:浮点数,使用科学记数法g
:浮点数,自动选择最合适的表示方式
- 数字格式化
浮动数值:
1
2
3pi = 3.141592653589793
message = f"Pi is approximately {pi:.2f}."
print(message) # 输出 'Pi is approximately 3.14.':.2f
表示保留两位小数。整数格式化:
1
2
3num = 123456789
message = f"Formatted number: {num:,}"
print(message) # 输出 'Formatted number: 123,456,789':,
会使用逗号作为千位分隔符。
- 对齐和宽度
你可以设置文本的对齐方式、宽度等。
右对齐(默认):
1
2
3name = "Alice"
message = f"{name:>10}" # 右对齐,宽度为10
print(message) # 输出 ' Alice'左对齐:
1
2
3name = "Alice"
message = f"{name:<10}" # 左对齐,宽度为10
print(message) # 输出 'Alice '居中对齐:
1
2
3name = "Alice"
message = f"{name:^10}" # 居中对齐,宽度为10
print(message) # 输出 ' Alice '
- 填充字符
可以设置对齐时使用的填充字符。
1 | name = "Alice" |
日期和时间格式化
对于日期和时间类型,可以使用 strftime
格式来进行格式化。
1 | from datetime import datetime |
%Y-%m-%d %H:%M:%S
是标准的日期时间格式,表示年-月-日 时:分:秒。
嵌套 f-string
如果你需要在一个 f-string
中嵌套另一个 f-string
,可以直接这样做:
1 | name = "Bob" |
直接判断一个字符在不在字符串 not in
1 | text = "hello world" |
re模块(正则表达式)的学习
re
模块提供了一些用于处理字符串匹配、替换和分割的工具,基于正则表达式的语法。正则表达式是一种强大的模式匹配工具,可以用来查找、验证或替换字符串中的内容。
常见用法:
re.compile()
函数
re.compile()
函数用于将正则表达式编译成一个正则表达式对象,可以多次使用该对象进行匹配操作。这种方法在你需要进行多次匹配时非常有用,因为编译后的正则表达式对象会提高性能。
1 | import re |
在这个例子中,使用 re.compile()
编译正则表达式 r'(\d+)-(\d+)-(\d+)'
,然后我们就可以多次调用 match()
或 search()
方法,避免每次都重新解析正则表达式,从而提高效率。
re.match()
和 re.search()
re.match()
: 从字符串的开始位置开始尝试匹配模式。如果模式在字符串开始处匹配成功,它会返回一个匹配对象;否则返回None
。1
2pythonresult = re.match(r'\d+', '123abc')
print(result.group()) # 输出: 123match()
只会在字符串的起始位置进行匹配,因此只有在匹配发生在字符串的最前面时才会成功。re.search()
: 在整个字符串中搜索模式。如果在字符串中找到匹配的部分,它会返回一个匹配对象;否则返回None
。1
2pythonresult = re.search(r'\d+', 'abc123xyz')
print(result.group()) # 输出: 123search()
会在整个字符串中查找匹配项,而不仅仅是从起始位置开始,因此比match()
更灵活。
re.findall()
和 re.finditer()
re.findall()
: 返回一个包含所有匹配项的列表。每个元素是字符串中的一个匹配项。1
2pythonresult = re.findall(r'\d+', 'abc123def456gh789')
print(result) # 输出: ['123', '456', '789']re.finditer()
: 返回一个迭代器,其中每个元素都是一个匹配对象。你可以使用group()
来提取每个匹配的子串。1
2
3pythonresult = re.finditer(r'\d+', 'abc123def456gh789')
for match in result:
print(match.group()) # 输出: 123 456 789
re.sub()
和 re.subn()
re.sub()
: 用于替换字符串中的匹配内容。它接受三个参数:正则表达式、替换字符串、原始字符串。1
2pythonresult = re.sub(r'\d+', 'number', 'abc123def456')
print(result) # 输出: abcnumberdefnumberre.subn()
: 和re.sub()
类似,但它还会返回替换操作发生的次数。1
2
3pythonresult, count = re.subn(r'\d+', 'number', 'abc123def456')
print(result) # 输出: abcnumberdefnumber
print(count) # 输出: 2
re.split()
re.split()
用于根据正则表达式分割字符串,返回一个列表。它与字符串的 split()
方法类似,但 re.split()
可以使用正则表达式作为分隔符。
1 | pythonresult = re.split(r'\d+', 'abc123def456ghi789') |
在这个例子中,正则表达式 \d+
匹配一个或多个数字,所以字符串会在这些数字处被分割。
group
方法
在使用正则表达式进行匹配时,re.match()
、re.search()
或 re.findall()
等函数会返回一个匹配对象。如果匹配成功,这些对象允许你调用 .group()
方法来提取匹配的字符串。
group()
方法:返回匹配结果中捕获的子串。可以使用数字或名称来提取捕获的组。
1 | import re |
使用
group()
获取多个匹配组:group(0)
:返回完整的匹配内容。group(1)
、group(2)
、…:返回对应的捕获组内容。
提取所有捕获组: 如果你想一次性获取所有捕获组,可以使用
groups()
方法,它返回一个元组,包含所有匹配的子组:1
2
3pythonmatch = re.match(pattern, text)
if match:
print(match.groups()) # 输出: ('2025', '03', '25')使用命名组:如果你在正则表达式中使用了命名捕获组,可以通过组名来获取匹配内容。
1
2
3
4
5
6
7pattern = r'(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+)'
text = "2025-03-25"
match = re.match(pattern, text)
if match:
print(match.group('year')) # 输出: 2025
print(match.group('month')) # 输出: 03
print(match.group('day')) # 输出: 25
常见正则表达式模式:
- **
.
**:匹配任何单个字符(除了换行符)。 - **
\d
**:匹配数字字符,等价于[0-9]
。 - **
\D
**:匹配非数字字符,等价于[^0-9]
。 - **
\w
**:匹配字母数字字符(包括下划线),等价于[a-zA-Z0-9_]
。 - **
\W
**:匹配非字母数字字符,等价于[^a-zA-Z0-9_]
。 - **
\s
**:匹配任何空白字符(空格、制表符、换行符等)。 - **
\S
**:匹配任何非空白字符。 - **
+
**:匹配前一个表达式一次或多次。 - **
\*
**:匹配前一个表达式零次或多次。 - **
?
**:匹配前一个表达式零次或一次。 - **
{n}
**:匹配前一个表达式恰好 n 次。 - **
[]
**:匹配括号内的任何一个字符。 - **
()
**:分组匹配,用来捕获子匹配。
collections 模块的学习
collections
模块提供了许多有用的集合类,增强了 Python 内建数据结构的功能。
Counter
是一个字典的子类,用来计数某个元素出现的次数。它的键是元素,值是该元素出现的次数。
**创建
Counter
**:1
2
3
4
5
6from collections import Counter
# 通过传入一个可迭代对象创建 Counter
counter = Counter('abracadabra')
print(counter)
# 输出: Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})**从字典创建
Counter
**:1
2
3counter = Counter({'a': 3, 'b': 1, 'c': 2})
print(counter)常见方法:
most_common()
: 返回出现频率最高的元素。1
print(counter.most_common(2)) # 输出: [('a', 3), ('c', 2)]
elements()
: 返回按出现次数排序后的所有元素,可以重复返回。1
print(list(counter.elements())) # 输出: ['a', 'a', 'a', 'c', 'c', 'b']
subtract()
: 从当前Counter
中减去另一个Counter
或可迭代对象。1
2counter.subtract({'a': 1, 'b': 1})
print(counter) # 输出: Counter({'a': 2, 'c': 2, 'b': 0})
pyshark模块的学习
主要功能
pyshark
提供了一些强大的功能,主要包括:
读取 pcap 文件:分析现有的
.pcap
文件。实时捕获数据包:实时捕获和分析网络流量。
过滤和解析数据包:应用过滤器以获取感兴趣的网络流量,支持解析各种协议(如 IP、TCP、UDP、HTTP 等)。
从 pcap 文件读取数据包
最基本的用法是加载 .pcap
文件并分析其中的数据包。
1 | import pyshark |
每个 packet
对象表示一个捕获的数据包,可以访问该数据包的不同字段,例如:
packet.ip
:表示 IP 层的信息。packet.tcp
:表示 TCP 层的信息。packet.udp
:表示 UDP 层的信息。
- 实时捕获数据包
你可以使用 pyshark.LiveCapture
来实时捕获网络数据包,并分析它们。你可以指定接口(如 eth0
、wlan0
等)来捕获指定接口的流量,或者捕获所有接口的流量。
1 | import pyshark |
在上述代码中,我们指定了网络接口 eth0
,并捕获了 5 个数据包。sniff_continuously()
方法会持续捕获数据包,直到达到指定的数量。
- 应用过滤器
你可以使用 Wireshark 的显示过滤器来只捕获感兴趣的数据包。pyshark
允许你在读取数据包时应用这些过滤器,从而提高性能,减少不相关的数据包。
1 | import pyshark |
在上面的例子中,display_filter='http'
使得我们只捕获 HTTP 协议的数据包。这对于实时分析特定协议的流量非常有用。
- 访问数据包字段
每个数据包在捕获后都被解析成一个包含各层协议字段的对象。你可以访问这些字段来获取详细的信息。
获取 IP 层信息:
1 | import pyshark |
获取 TCP 层信息:
1 | import pyshark |
获取 HTTP 层信息:
1 | import pyshark |
- 捕获特定的包或协议
pyshark
支持通过协议过滤器和其他条件来捕获特定类型的数据包。例如,你可以只捕获 TCP 数据包、特定端口的流量或 HTTP 请求。
1 | import pyshark |
bpf_filter
(Berkley Packet Filter)用于指定捕获的数据包条件。它可以帮助你减少捕获的数据量,只捕获你需要的数据。
- 读取和分析各种协议
pyshark
支持解析各种常见的网络协议,包括:
- IP:IPv4 和 IPv6。
- TCP / UDP:传输层协议。
- HTTP:用于 Web 通信的协议。
- DNS:域名系统。
- ARP:地址解析协议。
- SSL/TLS:安全套接层协议。
例如,如果你想检查某个数据包中的 DNS 查询,可以这样做:
1 | import pyshark |
- 数据包统计
你可以使用 pyshark
来对捕获的数据包进行统计。例如,计算不同协议的数据包数量:
1 | import pyshark |
- 错误处理
在使用 pyshark
时,可能会遇到一些错误(例如文件损坏或网络接口无权限访问)。你可以通过捕获异常来处理这些错误。
1 | import pyshark |
实际案例(2025红明谷异常行为溯源)
1 | from pyshark import FileCapture |
1 | for packet in FileCapture(input_file="network_traffic.pcap", keep_packets=False): |
FileCapture(input_file="network_traffic.pcap", keep_packets=False)
:FileCapture
用于加载一个.pcap
文件。input_file
参数指定了文件路径,keep_packets=False
参数告诉pyshark
在处理完每个数据包后不保留它们的内存副本,这样可以减少内存使用,尤其是在处理大文件时。- 这个
for
循环会逐个遍历.pcap
文件中的每个数据包。
解析 TCP 数据包
1 | tcp = packet.tcp |
packet.tcp
提取数据包中的 TCP 协议层。pyshark
会自动解析数据包并根据其协议层次进行分类。在这里,假设数据包包含 TCP 协议,因此你可以通过packet.tcp
获取到与 TCP 协议相关的信息。
处理 TCP 数据包中的负载(Payload)
1 | data = bytes.fromhex(tcp.payload.replace(":", "")).decode() |
tcp.payload
: 每个 TCP 数据包都有一个payload
字段,它包含数据包的实际负载。通常这部分数据是应用层传输的内容,可能是 HTTP 请求、DNS 响应、文件传输数据等。tcp.payload.replace(":", "")
: TCP 的payload
字段通常是以十六进制表示的,并且每两个字符之间由冒号分隔(例如00:1f:2a:3b
)。这里使用replace(":", "")
去除所有冒号,得到一个纯粹的十六进制字符串。bytes.fromhex(...)
: 这行代码将十六进制字符串转换为字节对象。例如,"00:1f:2a"
会被转换为b'\x00\x1f\x2a'
。.decode()
: 将字节对象解码为字符串。假设payload
中的内容是 UTF-8 编码的文本数据,所以我们可以直接将字节对象解码为文本。
解码 Base64 数据
1 | data = b64decode(data).decode() |
b64decode(data)
: 上一步解码得到的data
是经过 Base64 编码的字符串,这里通过b64decode
对其进行解码,恢复出原始的数据。Base64 是一种常见的编码方式,用于将二进制数据(如图像、文件或消息)转换为 ASCII 字符串,以便在网络中传输。.decode()
: 解码得到的 Base64 数据依然是字节流,通过.decode()
将其转换为字符串。
解析 JSON 数据
1 | data = loads(data) |
loads(data)
: 假设解码后的数据是 JSON 格式的字符串(例如,包含键值对的消息),loads
方法会将其解析为一个 Python 字典。在解析之后,你可以通过字典的键来访问具体的信息。
提取消息和类型
1 | msg = data["msg"] |
data["msg"]
: 在解析的 JSON 数据中,提取"msg"
字段,这可能是一个消息内容,通常是数据传输的核心信息。data["type"]
: 同样提取"type"
字段,这可能代表消息的类型或某种标识。
进一步解码消息
1 | msg = b64decode(msg).decode().strip() |
b64decode(msg)
: 假设msg
也是 Base64 编码的字符串,这一步将它解码回原始数据。.decode()
: 将解码后的字节对象转换为字符串。.strip()
: 去除字符串两端的空白字符(例如空格、换行符等)。