11-27周三练习
写入数据,打开文件的语法
with open (r‘路径’,‘读写模式’,encoding=‘编码规则’)as 名称 :
名称.方法名()
调用方法即可读.read()或者写.write()数据
r ‘路径’表示原生raw,\不表示转义字符。
想表示路径(路径里常用 \ 做分隔符),那可能需要使用原始字符串(在 Python 里以 r 开头定义字符串),像 r"C:\path\to\something",或者使用正斜杠 / 来替代(在很多情况下正斜杠也可以用于路径表示,尤其是在跨平台兼容时更合适,Windows、Unix、Linux都认),例如 "/path/to/something" 等。
.json()方法替代.text属性读取数据
当你从网络 API 获取数据时,很多时候数据是以 JSON 格式返回的。使用.json()方法将其转换为 Python 数据结构(如字典、列表等)后,你可以方便地对这些数据进行处理和分析。
请求requests关闭后仍可调用数据
当你关闭请求连接(例如在 Python 的requests
库中使用resp.close()
)后,之前已经获取到的响应内容仍然是可以使用的。
原因如下:
- 数据已经被接收
- 当你发出请求并收到响应时,响应的数据已经被传输到你的程序中。例如,在执行
resp = requests.get(url)
后,整个响应内容(包括状态码、头部信息、正文内容等)都已经存储在resp
对象中。关闭连接只是终止了与服务器的网络连接,并不会影响已经获取到的数据。
- 当你发出请求并收到响应时,响应的数据已经被传输到你的程序中。例如,在执行
- 响应对象的特性
- 在
requests
库中,Response
对象在获取到响应后就已经包含了所有相关的数据。像resp.text
、resp.json()
、resp.content
等属性都是从已获取的数据中提取的,而不是在每次调用时重新从网络获取。所以即使关闭了连接,你仍然可以通过这些属性访问和处理响应内容。
- 在
总之,关闭请求连接只是断开了与服务器的通信链路,并不会清除已经在本地获取和存储的响应数据。
文件名路径
绝对路径:
总结:
6:00到10:10,4h,复习了get、post请求方式,能够独立写出get请求,学习了文件写入方法,post暂不熟悉。
11-28周四-爬虫正则
group方法了解
在 Python 中,如果你是在处理正则表达式相关内容(通过re模块),group()是re.MatchObject的一个方法。
- 基本功能
- 当你使用re.search()、re.match()或re.finditer()等函数进行正则表达式匹配时,这些函数如果匹配成功,会返回一个MatchObject。
- group()方法用于获取匹配到的字符串。
- 如果正则表达式中没有分组(即没有用括号()括起来的子表达式),group()返回整个匹配的字符串。
- 例如:
收起
python
复制
import re
pattern = re.compile(r"(\d{3})-(\d{3}-\d{4})")
s = "My phone number is 123-456-7890"
match_obj = re.search(pattern, s)
if match_obj:
print(match_obj.group()) # 输出: 123-456-7890
- 分组功能
- 如果正则表达式中有分组,group()可以获取特定分组匹配到的字符串。
- group(0)等同于group(),即返回整个匹配的字符串。
- group(1)返回第一个分组匹配到的字符串,group(2)返回第二个分组匹配到的字符串,依此类推。
- 注意:1是第一个,0是整个
- 例如:
python
复制
import re
pattern = re.compile(r"(\d{3})-(\d{3}-\d{4})")
s = "My phone number is 123-456-7890"
match_obj = re.search(pattern, s)
if match_obj:
print(match_obj.group(1)) # 输出: 123
print(match_obj.group(2)) # 输出: 456-7890
re模块数据分析-豆瓣电影排名
先requests获取text,含有所需内容的页面源码
然后对text进行正则解析,提取想要数据
写入文件,或者用print输出后粘贴到文件中。
11-29周五-爬贴吧邮箱
from itertools import chain
from urllib.request import urlopen
import re
# 获取网页源代码的函数
def getPageContent(url):
"""
获取网页源代码
:param url: 指定url内容
:return: 返回页面的内容(str格式)
"""
# 使用with语句打开指定的url,确保操作完成后正确关闭相关资源
with urlopen(url) as html:
# 读取网页内容,由于读取到的是字节流形式,所以需要解码为字符串格式
return html.read().decode('utf-8')
# 根据网页内容获取贴吧总页数的函数
def parser_page(content):
"""
根据内容获取所有的贴吧总页数
:param content: 网页内容
:return: 贴吧总页数
"""
# 定义正则表达式模式,用于匹配网页内容中<span class="red">标签内的数字,即贴吧总页数
pattern = r'<span class="red">(\d+)</span>'
# 使用re.findall函数按照定义的模式在网页内容中查找匹配项,返回所有匹配结果的列表
data = re.findall(pattern, content)
# 返回匹配结果列表中的第一个元素,假设其为贴吧总页数
return data[0]
# 根据贴吧总页数构造不同url地址并找出所有邮箱的函数
def parser_all_page(pageCount):
"""
根据贴吧页数,构造不同的url地址,并找出所有的邮箱
:param pageCount:
:return:
"""
emails = []
# 遍历贴吧的每一页,page从0到pageCount - 1
for page in range(int(pageCount)):
# 构造每一页的url地址,格式为原帖子地址加上分页参数pn
url = 'http://tieba.baidu.com/p/2314539885?pn=%d' % (page + 1)
# 打印正在爬取的url地址,方便查看爬取进度
print('正在爬取:%s' % (url))
# 获取当前分页的网页内容
content = getPageContent(url)
# 定义用于匹配邮箱地址的正则表达式模式
pattern = r'[a-zA-Z0-9][-\w.+]*@[A-Za-z0-9][-A-Za-z0-9]+\.+[A-Za-z]{2,14}'
# 使用re.findall函数按照定义的模式在当前网页内容中查找邮箱地址,返回匹配结果列表
findEmail = re.findall(pattern, content)
# 打印当前分页找到的邮箱地址列表,方便查看提取情况
print(findEmail)
# 将当前分页找到的邮箱地址列表添加到emails列表中,这里会形成一个列表的列表结构
emails.append(findEmail)
return emails
# 主函数,协调调用其他函数完成整个任务
def main():
# 定义要爬取的百度贴吧帖子的url地址
url = 'http://tieba.baidu.com/p/2314539885'
# 获取该帖子首页的网页内容
content = getPageContent(url)
# 根据首页网页内容获取贴吧总页数
pageCount = parser_page(content)
# 根据贴吧总页数爬取各分页并提取邮箱地址
emails = parser_all_page(pageCount)
# 打印提取到的邮箱地址列表(此时是列表的列表结构),方便查看提取结果
print(emails)
# 使用with语句以写入模式打开名为tiebaEmail.txt的文件,确保操作完成后正确关闭文件
with open('tiebaEmail.txt', 'w') as f:
# 使用chain函数将emails列表的列表结构展平为一个单一的可迭代对象
for tieba in chain(*emails):
# 将每个邮箱地址写入文件中,每个地址占一行
f.write(tieba + '\n')
# 调用主函数启动整个程序的执行
main()
1、from itertools import chain
chain
函数的主要作用是将多个可迭代对象(如列表、元组、字符串、生成器等)连接成一个单一的可迭代对象。它允许你把不同的可迭代对象看作是一个连续的序列进行处理,就好像它们被拼接在一起了一样。
chain(*iterables)
,这里使用了可变参数语法(*
),意味着你可以传入任意数量的可迭代对象作为参数。
2、列表连接用append和extend的区别
append
方法的情况分析
- 功能及行为:
append
方法用于在列表末尾添加一个元素。在这段代码里,findEmail
是通过re.findall
函数得到的结果,它本身是一个列表(包含了在当前网页内容中匹配到的所有邮箱地址的列表)。当执行emails.append(findEmail)
时,它会把整个findEmail
列表作为一个单一元素添加到emails
列表的末尾。- 例如,如果
findEmail
的值是['abc@example.com', 'def@mail.com']
,执行emails.append(findEmail)
后,emails
列表就变成了类似[ [...
之前已有的元素
...], ['abc@example.com', 'def@mail.com'] ]
这样的结构,也就是说最终emails
是一个列表的列表,每个子列表对应着每一次分页查找得到的邮箱地址列表。
- 可能的合理性:
- 从代码后续处理来看,如果后续还有对每个分页的邮箱结果单独处理的需求,或者这种嵌套列表结构方便进行其他逻辑判断、数据统计等相关操作时,保持这种通过
append
添加的列表嵌套结构是有一定意义的。比如可能后续想要知道每个分页分别找到了多少个邮箱地址等情况,直接通过索引访问每个子列表就可以进行相应统计分析。
- 从代码后续处理来看,如果后续还有对每个分页的邮箱结果单独处理的需求,或者这种嵌套列表结构方便进行其他逻辑判断、数据统计等相关操作时,保持这种通过
extend
方法的情况分析
- 功能及行为:
extend
方法用于在列表末尾一次性追加另一个列表中的所有元素。如果把代码中的emails.append(findEmail)
换成emails.extend(findEmail)
,那么findEmail
列表中的每个元素(也就是每个具体的邮箱地址)会被逐个添加到emails
列表的末尾。- 例如,同样
findEmail
的值是['abc@example.com', 'def@mail.com']
,执行emails.extend(findEmail)
后,emails
列表会变成[...
之前已有的元素
..., 'abc@example.com', 'def@mail.com']
,这样emails
就变成了一个扁平化的列表,其中直接包含了所有分页中找到的所有邮箱地址,没有了嵌套结构。
- 优势:
- 从最终目的来看,如果只是想简单地收集所有的邮箱地址,形成一个单一的、扁平化的邮箱地址集合,便于后续统一处理(比如去重、写入文件等操作),使用
extend
方法会更加合适。在原代码后续通过chain(*emails)
来展平列表的操作其实就是为了把这种嵌套结构变回扁平化结构,以便能逐个将邮箱地址写入文件中,如果一开始就使用extend
方法,就可以省略chain(*emails)
这一步骤,代码逻辑上会更加简洁直接。
- 从最终目的来看,如果只是想简单地收集所有的邮箱地址,形成一个单一的、扁平化的邮箱地址集合,便于后续统一处理(比如去重、写入文件等操作),使用
11-30周六-复习上机+反反爬学习
1、什么是Cookie
基本信息
- 定义与构成:Cookie 通常是由网站服务器发送给用户浏览器,并由浏览器保存在用户计算机硬盘上的一个或多个小文件。它以键值对的形式存储信息,每个 Cookie 都有一个名称和对应的值,例如 “username=JohnDoe”,其中 “username” 是键,“JohnDoe” 是值 。此外,Cookie 还可能包含其他属性,如有效期、域名、路径等,用于控制 Cookie 的使用范围和有效时间。
- 工作原理:当用户访问一个使用了 Cookie 技术的网站时,网站服务器会通过 HTTP 响应头信息向用户浏览器发送 Cookie 数据。浏览器接收到 Cookie 后,会根据其设置的规则将 Cookie 保存起来。在后续访问该网站或相关网站时,浏览器会在每次向服务器发送的 HTTP 请求头信息中自动附上相应的 Cookie,服务器通过读取这些 Cookie 来获取用户的相关信息,从而实现各种功能,如识别用户身份、记住用户的登录状态、个性化设置等。
主要用途
- 会话管理:用于跟踪用户在网站上的会话状态,比如用户登录后,网站通过 Cookie 来识别用户是否已经登录以及登录的身份信息,使用户在浏览不同页面时无需重复登录。
- 个性化设置:网站可以根据用户的浏览历史、偏好设置等信息,通过 Cookie 来为用户提供个性化的内容和服务。例如,电商网站根据用户之前的浏览和购买记录,推荐相关的商品信息。
- 用户行为跟踪:通过 Cookie 可以记录用户在网站上的各种行为,如浏览的页面、点击的链接、停留的时间等,网站运营者可以借此分析用户的行为模式和偏好,以优化网站的设计和内容布局,或者进行精准的广告投放。
分类
- 会话 Cookie(Session Cookie):也称为临时 Cookie,它的有效期通常较短,一般在用户关闭浏览器时就会被自动删除。这类 Cookie 主要用于维护用户在一次浏览会话中的状态信息,例如在购物网站的一次购物流程中,用于记录当前购物车中的商品信息等。
- 持久 Cookie(Persistent Cookie):其有效期较长,可以在用户关闭浏览器后仍然保留在计算机上,直到达到预设的过期时间为止。网站常利用持久 Cookie 来记住用户的长期登录状态或其他需要长期保存的偏好设置等信息。
Cookie 的安全性与隐私问题
- 安全风险:虽然 Cookie 本身一般不包含敏感信息,但如果被恶意攻击者获取,可能会被用于一些恶意目的,如伪装成合法用户进行登录、获取用户的浏览历史等。因此,网站在设置 Cookie 时应注意不要在其中存储敏感信息,如密码等。同时,浏览器也提供了一些安全机制来保护 Cookie 的安全,如对 Cookie 进行加密存储、限制 Cookie 的访问范围等。
- 隐私问题:由于 Cookie 可以跟踪用户的浏览行为,一些用户可能会担心自己的隐私被侵犯。为了保护用户隐私,许多国家和地区都制定了相关的法律法规,要求网站在使用 Cookie 时必须获得用户的明确同意,并告知用户 Cookie 的用途和使用方式。同时,浏览器也允许用户自行设置是否接受 Cookie 以及清除已有的 Cookie 等。
2、类型判断
x = 18
if type(x) == int:
print('True!')
type(x) 返回的是 <class 'int'> 这样一个类型对象,而不是字符串 "int"。因此使用if type(x) == int: 而非if type(x) == ‘int’:
类型不需要加上双引号!
另外,推荐使用if type(x) is int: ,更符合python规范。
x = 18
if type(x) is int:
print('True!')
3、python中有整除运算符,\\表整除
4、reversed()逆序函数,返回的是reverse可迭代对象,和map对象一样,返回的是迭代器。不能直接输出,想要访问就遍历输出!
5、python字符串,当在系统中其只有一对引号时,输出该字符串,会自动去除外面的引号;当在系统中有两对引号时,输出才会带上一对引号。
6、format()方法运用
基本用法
format()
方法可以接受多个参数,并将这些参数按照指定的格式插入到字符串中的占位符位置 。占位符通常用大括号{}
表示。- 示例:
python
复制
name
=
"Alice"
age
=
25
print("My name is {} and I am {} years old.".format(name
, age
))
输出:My name is Alice and I am 25 years old.
格式化参数的顺序和重复使用
- 可以通过在占位符中指定参数的索引来控制参数的使用顺序,索引从 0 开始计数。也可以多次使用同一个参数。
- 示例:
python
复制
print("I am {1} years old. My name is {0}. {0} is a nice name.".format("Alice",
25))
输出:I am 25 years old. My name is Alice. Alice is a nice name.
格式化字符串的格式限定
- 在占位符中,可以使用冒号
:
来添加格式限定符,以指定数据的显示格式,如宽度、精度、对齐方式等。 - 示例:
python
复制
pi
=
3.1415926
print("The value of pi is approximately {:.2f}".format(pi
))
这里的:.2f
表示将浮点数格式化为保留两位小数的形式,输出:The value of pi is approximately 3.14
其他格式化类型
除了上述常见的用法外,还可以用于格式化整数、字符串等其他数据类型,并且可以进行进制转换等操作。
- 示例:
python
复制
num
=
42
print("The decimal number {0} is {0:x} in hexadecimal and {0:b} in binary.".format(num
))
输出:The decimal number 42 is 2a in hexadecimal and 101010 in binary.
7、f-string来格式化输出
f-string 是 Python 3.6 及以后版本引入的一种简洁高效的字符串格式化方法,它提供了一种直观且方便的方式来将变量或表达式嵌入到字符串中,以下是对它的详细介绍:
基本语法
- f-strings 以字母
f
或F
开头,后面紧跟字符串,字符串中使用花括号{}
包含要替换的变量或表达式。当 Python 解释器遇到 f-string 时,会自动将花括号内的内容替换为相应的值,并将整个字符串进行求值,得到最终的格式化后的字符串。 - 示例:
python
复制
name
=
"Alice"
age
=
25
print(f"My name is {name} and I am {age} years old.")
输出:My name is Alice and I am 25 years old.
表达式求值
- 在花括号内不仅可以直接放置变量,还可以放置任意合法的 Python 表达式,解释器会对表达式进行求值并将结果替换到字符串中。
- 示例:
python
复制
a
=
10
b
=
20
print(f"The sum of {a} and {b} is {a + b}.")
输出:The sum of 10 and 20 is 30.
函数调用
- 也可以在花括号内调用函数,函数的返回值会被插入到字符串中相应的位置。
- 示例:
python
复制
def
get_greeting(name
):
return
f"Hello, {name}!"
print(f"{get_greeting('Alice')} How are you today?")
输出:Hello, Alice! How are you today?
格式化控制
- 与
format()
方法类似,f-strings 也支持在花括号内使用冒号:
来进行格式化控制,如指定宽度、精度、对齐方式等。 - 示例:
python
复制
pi
=
3.1415926
print(f"The value of pi is approximately {pi:.2f}")
输出:The value of pi is approximately 3.14
引号使用
- 在 f-string 中,如果字符串本身需要使用引号,可以像普通字符串一样,使用不同类型的引号来避免冲突。
- 示例:
python
复制
name
=
"Alice's"
print(f"My name is {name}")
输出:My name is Alice's
性能优势
- f-strings 在性能上优于传统的
%
格式化和format()
方法,因为它在编译时就会解析字符串,而不是在运行时进行格式化操作,这使得它在处理大量字符串格式化操作时更加高效。
12.1周日-正则练习
1、
2、电影天堂的例子,因为网站反爬做的太强,把我IP封了,不能实现for遍历嵌套自动实现爬取,后续反反爬实现后再重新来实现以下。
1、csv模块常用功能
Python 中的 csv
模块提供了用于读写 CSV(逗号分隔值)文件的功能,以下是详细介绍:
读取 CSV 文件
- 基本读取
csv.reader()
函数用于创建一个读取 CSV 文件的对象,它可以从文件对象中读取数据,并以列表的形式返回每一行的数据。- 例如:
复制
import csv
with
open('example.csv',
'r')
as
file:
reader
= csv
.reader
(file)
for row
in reader
:
print(row
)
- 上述代码打开名为
example.csv
的文件,使用csv.reader()
创建读取对象,然后逐行读取并打印文件内容,每一行数据以列表形式呈现,其中每个元素对应 CSV 文件中以逗号分隔的一个值。 - 指定分隔符和引号字符
- 可以通过参数指定分隔符和引号字符等,以适应不同格式的 CSV 文件。例如,如果 CSV 文件使用制表符
\t
作为分隔符,可以这样读取:
- 可以通过参数指定分隔符和引号字符等,以适应不同格式的 CSV 文件。例如,如果 CSV 文件使用制表符
复制
import csv
with
open('example.tsv',
'r')
as
file:
reader
= csv
.reader
(file, delimiter
='\t')
for row
in reader
:
print(row
)
写入 CSV 文件
- 基本写入
csv.writer()
函数用于创建一个写入 CSV 文件的对象,通过该对象可以将数据写入文件,每一行数据以列表形式传入writerow()
方法来实现写入。- 例如:
python
复制
import csv
data
=
[
['Name',
'Age',
'City'],
['Alice',
25,
'New York'],
['Bob',
30,
'San Francisco']
]
with
open('output.csv',
'w', newline
='')
as
file:
writer
= csv
.writer
(file)
for row
in data
:
writer
.writerow
(row
)
- 上述代码创建了一个包含姓名、年龄和城市信息的二维列表
data
,然后打开output.csv
文件,使用csv.writer()
创建写入对象,通过循环调用writerow()
方法将每一行数据写入文件。 - 写入字典形式的数据
csv.DictWriter()
类用于以字典形式写入数据到 CSV 文件。它需要先定义好字段名,然后通过writerow()
方法传入字典,字典的键需要与字段名对应。- 例如:
python
复制
import csv
data
=
[
{'Name':
'Alice',
'Age':
25,
'City':
'New York'},
{'Name':
'Bob',
'Age':
30,
'City':
'San Francisco'}
]
fieldnames
=
['Name',
'Age',
'City']
with
open('output_dict.csv',
'w', newline
='')
as
file:
writer
= csv
.DictWriter
(file, fieldnames
=fieldnames
)
writer
.writeheader
()
for row
in data
:
writer
.writerow
(row
)
- 此代码中,先定义了包含字典的列表
data
和字段名列表fieldnames
,打开文件后使用csv.DictWriter()
创建写入对象,先调用writeheader()
写入字段名作为文件的表头,再循环写入每一行数据。
其他功能
- 自动检测换行符:如前文所述,在读取和写入 CSV 文件时,建议设置
newline=''
,这样可以让csv
模块自动检测文件中的换行符,避免因换行符不一致导致的问题。 - 数据格式处理:
csv
模块在读取和写入数据时,会尽量保留数据的原始格式,不会对数据进行额外的类型转换等操作,除非你在代码中显式地进行处理。这使得它在处理各种类型的数据时都能保持较好的兼容性和稳定性。
2、csv中writerow与writerows区别
在 Python 的 csv
模块中,writerow
和 writerows
是 csv.writer
对象的两个重要方法,用于向 CSV 文件写入数据,它们的主要区别如下:
writerow
方法
- 功能:用于向 CSV 文件写入一行数据。
- 参数要求:它接受一个可迭代对象作为参数,通常是一个列表或元组,其中的每个元素代表 CSV 文件中某一列的值。
import csv
# 准备数据
data_row
=
['John',
25,
'New York']
# 打开文件并写入数据
with
open('example.csv',
'w', newline
='')
as
file:
writer
= csv
.writer
(file)
writer
.wrow
(data_row
)
- 在上述示例中,
writerow
方法将列表['John', 25, 'New York']
作为一行数据写入到example.csv
文件中 。如果文件不存在,则会创建新文件;如果文件已存在,则会先清空文件再写入新数据。
writerows
方法
- 功能:用于一次性向 CSV 文件写入多行数据。
- 参数要求:它接受一个二维可迭代对象作为参数,通常是一个列表的列表,其中每个内层列表代表 CSV 文件中的一行数据。
import csv
# 准备数据
data_rows
=
[
['Alice',
22,
'London'],
['Bob',
28,
'Paris'],
['Charlie',
30,
'Tokyo']
]
# 打开文件并写入数据
with
open('example.csv',
'w', newline
='')
as
file:
writer
= csv
.writer
(file)
writer
.writerows
(data_rows
)
- 在这个示例中,
writerows
方法将列表的列表data_rows
中的每一个内层列表作为一行数据,一次性写入到example.csv
文件中,实现了多行数据的快速写入。
3、with open文件操作
1)、encoding指定编码格式为utf_8_sig,若用utf-8编码,用excel打开该csv文件中文会乱码,用utf_8_sig告诉excel用utf-8格式打开文件。
2)、csv模块写入,需要先用csv.writer创建writer对象,随后对象名.writerow或者对象名.writerows来实现写入数据。
4、寻找网页所爬取数据对应的源代码
鼠标右键【查看页面源码】,看页面数据是否在源码中。
1)服务器渲染
若在,则直接爬取该页面搜索框里面的url即可,打开【检查】,找第一个文件,看是post方式还是get方式,若有反爬则制定相应的反反爬策略。
2)客户端渲染
若数据不在源码中,则打开检查,CTRL + R刷新,点击XHR文件进行筛选,点击【预览】看所需的数据是否在。若找到对应数据,则记住【预览】里面不是页面源码,【响应】里面才是页面源码!!!
5、从页面源码中提取所需数据
requests发送请求后,先.text输出源码内容,看看其是否和浏览器中页面源码有相同的空白符,如换行、空格等。
若.text中自动过滤了空白符,则在编写正则表达式时需根据.text来编写,防止根据浏览器中页面源码编写导致出现多余的空白符而匹配不到所需数据的情况出现
6、python自动爬取客户端渲染网站
客户端渲染的页面,一般其 url 都会有相似的格式。
1)要么是url相同,但【负载】中表单数据不同,此时对于post请求,在requests.post()中加上data=参数dic,dic用来写参数键值对,一般下一页都是某一键比如page从1变化到2、3、4等类似,此时只需要元组生成式构造参数值,随后遍历循环,每次使用不同的参数值即可自动换页面爬取数据。
2)对于get请求,一般是url类似,后缀参数出现明显变化,比如page=1,从1变化为2、3、4等,此时只需要修改url,for循环,每次url +=参数值,每次循环改变该url即可。
亦或者可同1),使用相同的url,将url中查询参数用字典封装,传入request.get()的params=参数中,每次更换属性值即可。
7、post请求中的data与get请求中的params的不同之处
在 Python 的 requests
库中,data
和 params
都可用于向服务器发送数据,但它们有一些区别,主要体现在以下几个方面:
数据传递方式
params
:用于向服务器传递查询字符串参数,这些参数会被附加到 URL 的末尾,形成一个完整的请求 URL。通常用于 GET 请求,以便服务器根据这些参数来筛选或返回特定的数据。data
:用于向服务器发送表单数据或其他需要在请求体中传递的数据,一般用于 POST、PUT、PATCH 等非 GET 请求方法,这些数据不会显示在 URL 中,而是在请求体中发送给服务器。
数据格式和用途
params
- 数据格式通常是简单的键值对,例如
?key1=value1&key2=value2
,其中key1
、key2
是参数名,value1
、value2
是对应的参数值。 - 主要用于向服务器请求特定资源时提供筛选条件或额外信息,帮助服务器更好地理解客户端的需求,进而返回更精准的响应。
- 数据格式通常是简单的键值对,例如
data
- 可以是多种格式的数据,如字典形式的表单数据
{'key1': 'value1', 'key2': 'value2'}
,也可以是字符串、字节流等其他格式,具体取决于所使用的请求方法和服务器的要求。 - 常用于向服务器提交需要处理的数据,如用户注册信息、登录凭据、文件上传等,服务器会根据接收到的数据进行相应的操作,如创建新用户、验证登录、保存文件等。
- 可以是多种格式的数据,如字典形式的表单数据
对请求的可见性
params
:由于params
中的参数会附加到 URL 上,所以在浏览器的地址栏中可以直接看到这些参数,这使得请求的参数信息对用户是可见的。data
:因为data
中的数据是在请求体中发送的,所以在浏览器地址栏中看不到这些数据,相对更加安全和私密,适用于传递一些不希望被用户直接看到的敏感信息,如密码等 。
对缓存的影响
params
:由于params
是 URL 的一部分,而很多缓存机制是基于 URL 进行缓存的,所以使用不同的params
值会导致不同的缓存结果。如果两次请求的 URL(包括params
)相同,可能会命中缓存,直接返回缓存中的数据。data
:一般来说,data
不在缓存考虑的范围内,因为它不在 URL 中,所以不会因data
的变化而直接影响缓存机制。不过,有些特殊的缓存策略可能会综合考虑请求体中的数据,但这种情况相对较少。
8、太长的正则表达式,可用re.compile(r” ”, re.S)封装,对于r” ”字符串,太长的话可考虑换行,会自动在每一行前加上r” ”,以表示二者构成正则表达式的相同整体。
9、re四种方法匹配到数据后读取
match()、search()返回的是Match Object对象型数据,进行读取要用.group( )方法。
finditer()返回的是迭代器对象,每个元素为Match Object对象型数据,只能通过遍历使用group方法得到数据。
group()只能用于返回一个Match Object对象型数据的值,所以finditer型数据不可以整体直接使用group方法,也就不存在group整体输出某一组匹配到的所有字符的情况。
10、group()表示匹配的整体字符串。group()传入参数,则只输出匹配的某组所需的数据。传入参数用的更多!!!
若想只输出想要的数据,可以在正则中加上组名,随后用group方法,带上‘组名’来输出想要内容,亦或者可以简单地使用序号0、1、2、3来获取对应的数据。