Python 使用 Requests 模块进行爬虫

目录

  • 一、请求数据
  • 二、获取并解析数据
  • 四、保存数据
    • 1. 保存为 CSV 文件
    • 2. 保存为 Excel 文件
      • 打开网页图片并将其插入到 Excel 文件中
  • 五、加密参数逆向分析
    • 1. 定位加密位置
    • 2. 断点调试分析
    • 3. 复制相关 js 加密代码,在本地进行调试(难)
    • 4. 获取 sign 加密参数
  • 六、其他示例
    • 1. 单页数据处理与保存
    • 2. 翻页数据采集 — MD5 加密
      • 1)分析请求链接 / 参数的变化
      • 2)sign 加密参数逆向分析
      • 3)Python 代码实现


学习视频;【Python爬虫实战:采集常用软件数据(得物、闲鱼、小红书、微信小程序、验证码识别)】
参考文档:【Requests: 让 HTTP 服务人类】

一、请求数据

Requests 模块通过模拟浏览器对 url 地址发送请求。

  • 打开需要采集数据的网站,通过浏览器的开发者工具分析对应的数据位置。
    • 右键选择 “检查” → “网络” ,打开开发者工具;
    • 刷新网页;
    • 通过关键字搜索找到对应的数据位置。

  • 请求标头:通过使用请求标头中的参数内容模拟浏览器,该参数需要使用字典 dict={'键':'值',} 接收。

PyCharm 批量添加引号和逗号的方法:

  • 选中要替换的内容,输入 Ctrl + R 打开替换栏;
  • 勾选 .* ,使用正则命令匹配数据进行替换;
  • 第一栏输入 (.*?):(.*) ,第二栏输入 '$1':'$2', ,再选中要替换的内容点击 “全部替换” 。

  • 请求网址:复制抓包分析找到的链接地址。

  • 请求方法

    • POST 请求 → 需要向服务器提交表单数据 / 请求载荷;
    • GET 请求 → 向服务器获取数据。

  • 请求参数:可以在 “载荷” 中进行查看
    • POST 请求 → 隐性;
    • GET 请求 → 显性(查询的参数直接在请求网址的链接中就可以看出)。

参考文章:【HTTP 方法:GET 对比 POST | 菜鸟教程】

  • 发送请求:使用 requests 模块。
    • 如果没有安装该模块,则 Win + R 输入 cmd ,输入 pip install requests 命令并运行即可。
    • 在 PyCharm 中输入 import requests 导入数据请求模块。

Python 代码:

import requests# 请求标头
request_header = {'accept': '*/*','accept-encoding': 'gzip, deflate, br, zstd','accept-language': 'zh-CN,zh;q=0.9','connection': 'keep-alive','content-length': '124','content-type': 'application/json','cookie': '...','host': 'app.dewu.com','ltk': '...','origin': 'https://www.dewu.com','referer': 'https://www.dewu.com/','sec-ch-ua': '"Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"','sec-fetch-dest': 'empty','sec-fetch-mode': 'cors','sec-fetch-site': 'same-site','sessionid': '...','shumeiid': '...','sk': '','traceparent': '...','user-agent': '...'
}# 请求网址
request_url = r'https://app.dewu.com/api/v1/h5/commodity-pick-interfaces/pc/pick-rule-result/feeds/info'# 请求载荷
request_parameters = {'filterUnbid': True,'pageNum': 1,  # 页数'pageSize': 24,'pickRuleId': 644443,'showCspu': True,'sign': "0e5d10fb111f2afef6ac0a1776187e23"  # 签名(加密参数)
}# 请求数据
response = requests.post(url=request_url, json=request_parameters, headers=request_header)

二、获取并解析数据

  • 获取服务器返回的响应数据。

    • response.text → 获取响应的文本数据(字符串)
    • response.json() → 获取响应的 json 数据(字典 / 列表)
    • response.content → 获取响应的二进制数据(二进制数据)
  • 对键值对进行取值,提取出所需信息。

Python 代码:

# from pprint import pprint# 获取数据
data_json = response.json()
# print(data_json)# 解析数据
info_list = data_json['data']['list']
for index in info_list:# pprint(index)# print('-' * 50)info_dict = {'标题': index['title'],'价格': index['price'],'图片网址': index['logoUrl']}for key, value in info_dict.items():print(f'{key} : {value}')print('-' * 50)

注:如果出现 “requests.exceptions.InvalidHeader: xxx” 的报错,说明你的 request_header 字典中的值存在多余的空格,仔细检查后删除即可。

四、保存数据

1. 保存为 CSV 文件

Python 代码:

import requests
import csvrequest_header = {...}
request_url = r'https://app.dewu.com/api/v1/h5/commodity-pick-interfaces/pc/pick-rule-result/feeds/info'
request_parameters = {'filterUnbid': True,'pageNum': 1,  # 页数'pageSize': 24,'pickRuleId': 644443,'showCspu': True,'sign': "0e5d10fb111f2afef6ac0a1776187e23"  # 签名(加密参数)
}# 创建文件对象
f = open('dewu.csv', mode='w', encoding='utf-8-sig', newline='')
# 字典写入方法
cd = csv.DictWriter(f, fieldnames=['标题', '价格', '图片网址'])
# 写入表头
cd.writeheader()# 请求数据
response = requests.post(url=request_url, json=request_parameters, headers=request_header)
# 获取数据
data_json = response.json()
# 解析数据
info_list = data_json['data']['list']
for index in info_list:info_dict = {'标题': index['title'],'价格': index['price'] / 100,'图片网址': index['logoUrl']}# 写入数据cd.writerow(info_dict)f.close()

2. 保存为 Excel 文件

Python 代码:

import requests
import pandas as pdrequest_header = {...}
request_url = r'https://app.dewu.com/api/v1/h5/commodity-pick-interfaces/pc/pick-rule-result/feeds/info'
request_parameters = {'filterUnbid': True,'pageNum': 1,  # 页数'pageSize': 24,'pickRuleId': 644443,'showCspu': True,'sign': "0e5d10fb111f2afef6ac0a1776187e23"  # 签名(加密参数)
}# 请求数据
response = requests.post(url=request_url, json=request_parameters, headers=request_header)
# 获取数据
data_json = response.json()
# 创建一个空列表
dewu_info = []# 解析数据
info_list = data_json['data']['list']
for index in info_list:info_dict = {'标题': index['title'],'价格': index['price'] / 100,'图片网址': index['logoUrl']}# 写入数据dewu_info.append(info_dict)# 转换数据
df = pd.DataFrame(dewu_info)
# 导出保存为 Excel 表格
df.to_excel('dewu.xlsx', index=False)

打开网页图片并将其插入到 Excel 文件中

Python 代码:

import openpyxl
from openpyxl.drawing.image import Image as xlImage
from openpyxl.utils import get_column_letter
from PIL import Image
from io import BytesIOdef download_image(url):rg_url = requests.get(url)# 检查响应状态码if rg_url.status_code == 200:# 创建图像对象image = Image.open(BytesIO(rg_url.content))# 统一图像类型if image.mode != 'RGB':image = image.convert('RGB')# 调整图像大小return image.resize((150, 96))else:raise Exception(f"无法下载图片,状态码: {rg_url.status_code}")# 加载 Excel 文件
wb = openpyxl.load_workbook(r'dewu.xlsx')
# 默认为第一个 sheet
sheet = wb.active
# 调整行高和列宽
for row in range(2, sheet.max_row + 1):sheet.row_dimensions[row].height = 75
sheet.column_dimensions['C'].width = 20# 读取链接并下载图片插入到对应位置
for row in range(2, sheet.max_row + 1):# 假设图片链接在第 2 行开始,第 C 列是链接(对应 column = 3),获取链接单元格的值link = sheet.cell(row=row, column=3).value# 清空内容sheet.cell(row=row, column=3).value = None# 如果链接不为空if link:# 发送 HTTP 请求下载图片try:# 尝试下载图像resized_image = download_image(link)except OSError:print(f"下载图片 {link} 失败")continueelse:# 将调整后的图像插入到工作表中img_bytes = BytesIO()resized_image.save(img_bytes, format='PNG')  # 将图片保存到内存中img = xlImage(img_bytes)sheet.add_image(img, f'{get_column_letter(3)}{row}')  # 插入图片到指定位置wb.save(r'dewu_result.xlsx')  # 必要
wb.close()  # 必要

参考文章:【Python:openpyxl在excel中读取url并下载、插入图片】

五、加密参数逆向分析

1. 定位加密位置

通过开发者工具定位加密位置。

2. 断点调试分析

断点调试分析,分析加密规则。

  • 搜索后返回了三个文件中的四个匹配行,分析可能的加密位置,然后添加断点。

  • 通过对网页进行操作来调试断点,程序停止的位置就是我们要找的断点位置。

  • 通过过滤请求网址,找到对应的请求载荷数据,查看 sign: 后的数据是否与刚刚断点处的 sign: c(e) 值一致。

  • 移除上面的那个不需要的 sign: c(e) 断点。

注意:

c(e) 返回 sign 值,其中 e 是参数,c 是方法。

  • e 是除 sign 以外的 POST 请求载荷。

  • c() 的返回值是 “0e5d10fb111f2afef6ac0a1776187e23”(由 0-9 a-f 组成的 32 位字符)。

  • 由 0-9 a-f 组成的 32 位字符可能是 md5 加密。
    验证是否为标准的 md5 加密,只需要调用加密函数,并传入字符串参数 ‘123456’ ,如果返回值是以 ‘e10adc’ 开头、‘883e’ 结尾,那么就是标准的 md5 加密。

由参数 e 是字典也可以看出,该方法 c() 不是 md5 加密,因为 md5 加密的参数一般是字符串。

3. 复制相关 js 加密代码,在本地进行调试(难)

较难理解的一部分,详细讲解请见:【Python爬虫实战:采集常用软件数据(得物)】的 0:50:25 处。

  • 进入 c() 函数。

  • 新建一个 JavaScript 文件(我的命名:js_file.js),并将上图红框中的代码复制进去。
function c(t) {...}t = {filterUnbid: true,pageNum: 1,pageSize: 24,pickRuleId: 644443,showCspu: true
}  // 请求载荷console.log(c(t))
  • 运行出现错误:ReferenceError: u is not defined ,出现此类报错是正常的,说明存在代码缺失。解决方案就是:缺方法补方法、缺参数补参数、缺环境补环境。

  • 找到相应的加载器,并将代码添加至 JavaScript 文件里。

JavaScript 代码如下:

var a_temp;  // 添加!function a_method(e) {var n = {}function a(r) {...}a_temp = a  // 添加a.e = function (e) {...},a.m = e,a.c = n,a.d = function (e, r, t) {...},a.r = function (e) {...},a.t = function (e, r) {...},a.n = function (e) {...},a.o = function (e, r) {...},a.p = "",a.oe = function (e) {...}
}({});a = (a_temp("cnSC"), a_temp("ODXe"), a_temp("aCH8"))  // 将 r 修改为 a_temp
u = a_temp.n(a);  // 将 r 修改为 a_tempfunction c(t) {...}t = {filterUnbid: true,pageNum: 1,pageSize: 24,pickRuleId: 644443,showCspu: true
}console.log(c(t))
  • 运行上述代码会出现 TypeError: Cannot read properties of undefined (reading 'call') 的错误。如下图所示添加代码:

  • 将运行后输出的缺失代码添加至 JavaScript 文件里。

JavaScript 代码如下:

var a_temp;  // 添加!function a_method(e) {var n = {}function a(r) {...try {console.log(r)  // 添加e[r].call(t.exports, t, t.exports, a),o = !1} finally {o && delete n[r]}...}a_temp = a  // 添加a.e = function (e) {...},a.m = e,a.c = n,a.d = function (e, r, t) {...},a.r = function (e) {...},a.t = function (e, r) {...},a.n = function (e) {...},a.o = function (e, r) {...},a.p = "",a.oe = function (e) {...}
}({  // 添加cnSC: function (t, e) {...},ODXe: function (e, t, n) {...},BsWD: function (e, t, n) {...},a3WO: function (e, t, n) {...},aCH8: function (t, e, r) {...},ANhw: function (t, e) {...},mmNF: function (t, e) {...},BEtg: function (t, e) {...}
});a = (a_temp("cnSC"), a_temp("ODXe"), a_temp("aCH8"))  // 将 r 修改为 a_temp
u = a_temp.n(a);  // 将 r 修改为 a_tempfunction c(t) {...}t = {filterUnbid: true,pageNum: 1,pageSize: 24,pickRuleId: 644443,showCspu: true
}console.log(c(t))

详细的 js_file.js 文件代码见:【对得物进行爬虫时使用到的 js 模块】

  • 运行结果如下图所示:

4. 获取 sign 加密参数

  • Win + R 输入 cmd 进入命令提示符,输入命令 pip install pyexecjs 安装 execjs 库,安装好后在 PyCharm 中输入 import execjs 就可以使用该模块了。

  • 编译 js 代码并获取 sign 加密参数,并将 sign 值添加至请求载荷中。

Python 代码:

import requests
# 导入编译 js 代码模块
import execjs# 请求标头
request_header = {...}
# 请求网址
request_url = r'https://app.dewu.com/api/v1/h5/commodity-pick-interfaces/pc/pick-rule-result/feeds/info'
# 请求载荷
request_parameters = {'filterUnbid': True,'pageNum': 1,  # 页码'pageSize': 24,'pickRuleId': 644443,  # 类目 ID'showCspu': True
}# 编译 js 代码
js_code = execjs.compile(open('./js_file.js', encoding='utf-8').read())
# 获取 sign 加密参数
sign_data = js_code.call('c', request_parameters)
# 0e5d10fb111f2afef6ac0a1776187e23
# 将 sign 添加至请求载荷中
request_parameters['sign'] = sign_data# 请求数据
response = requests.post(url=request_url, json=request_parameters, headers=request_header)
# 获取数据
data_json = response.json()
# 解析数据
info_list = data_json['data']['list']
for index in info_list:info_dict = {'标题': index['title'],'价格': index['price'] / 100,'图片网址': index['logoUrl']}for key, value in info_dict.items():print(f'{key} : {value}')print('-' * 50)

六、其他示例

1. 单页数据处理与保存

Python 代码:

# 导入数据请求模块
import requests
import csvdef get_data_csv(file_path, head_name):# 模拟浏览器(请求标头)request_header = {'Referer': 'https://www.goofish.com/',# cookie 代表用户信息,常用于检测是否有登陆账户(不论是否登录都有 cookie)'Cookie': '...'# user-agent 代表用户代理,显示浏览器 / 设备的基本身份信息'User-Agent': '...'}# 请求网址request_url = r'https://h5api.m.goofish.com/h5/mtop.taobao.idlemtopsearch.pc.search/1.0/'# 查询参数query_parameters = {'jsv': '2.7.2','appKey': '34839810','t': '1750520204194','sign': '0dba40964b402d00dc448081c8e04127','v': '1.0','type': 'originaljson','accountSite': 'xianyu','dataType': 'json','timeout': '20000','api': 'mtop.taobao.idlemtopsearch.pc.search','sessionOption': 'AutoLoginOnly','spm_cnt': 'a21ybx.search.0.0','spm_pre': 'a21ybx.home.searchSuggest.1.4c053da6IXTxSx','log_id': '4c053da6IXTxSx'}# 表单数据form_data = {"pageNumber": 1,"keyword": "python爬虫书籍","fromFilter": False,"rowsPerPage": 30,"sortValue": "","sortField": "","customDistance": "","gps": "","propValueStr": {},"customGps": "","searchReqFromPage": "pcSearch","extraFilterValue": "{}","userPositionJson": "{}"}print('Data is being requested and processed…')# 发送请求response = requests.post(url=request_url, params=query_parameters, data=form_data, headers=request_header)# 获取响应的 json 数据 → 字典数据类型data_json = response.json()# 键值对取值,提取商品信息所在列表info_list = data_json['data']['resultList']# 创建文件对象f = open(file_path, mode='a', encoding='utf-8-sig', newline='')# 字典写入方法cd = csv.DictWriter(f, fieldnames=head_name)cd.writeheader()# for 循环遍历,提取列表里的元素for index in info_list:# 处理用户名nick_name = '未知'if 'userNickName' in index['data']['item']['main']['exContent']:nick_name = index['data']['item']['main']['exContent']['userNickName']# 处理售价price_list = index['data']['item']['main']['exContent']['price']price = ''for p in price_list:price += p['text']# 处理详情页链接item_id = index['data']['item']['main']['exContent']['itemId']link = f'https://www.goofish.com/item?id={item_id}'temporarily_dict = {'标题': index['data']['item']['main']['exContent']['title'],'地区': index['data']['item']['main']['exContent']['area'],'售价': price,'用户名': nick_name,'详情页链接': link}cd_file.writerow(temporarily_dict)f.close()if __name__ == '__main__':f_path = './fish.csv'h_name = ['标题', '地区', '售价', '用户名', '详情页链接']get_data_csv(f_path, h_name)

2. 翻页数据采集 — MD5 加密

1)分析请求链接 / 参数的变化

如下图所示,其中 t 可以通过 time 模块获取;pageNumber 可以通过 for 循环构建。

2)sign 加密参数逆向分析

  • 通过开发者工具定位加密位置。

  • 断点调试分析。

k = i(d.token + "&" + j + "&" + h + "&" + c.data) ,其中:

d.token = "b92a905a245d2523e9ca49dd382dad12"  // 固定
j = 1750571387066  // 时间戳(变化)
h = "34839810"  // 固定
// 表单数据,其中只有页码 pageNumber 会变化
c.data = ('{"pageNumber": 1, ''"keyword": "python爬虫书籍", ''"fromFilter": false, ''"rowsPerPage": 30, ''"sortValue": "", ''"sortField": "", ''"customDistance": "", ''"gps": "", ''"propValueStr": {}, ''"customGps": "", ''"searchReqFromPage": "pcSearch", ''"extraFilterValue": "{}", ''"userPositionJson": "{}"}')k = "1c32f4de228112a3a59df6972d186b41"  // 返回值 由 0-9 a-f 构成的 32 位字符
  • 判断是否为 md5 加密的方法:调用加密函数 i() ,并传入字符串参数 ‘123456’ ,如果返回值是以 ‘e10adc’ 开头、‘883e’ 结尾,那么就是标准的 md5 加密。

# 导入哈希模块
import hashlibd_token = 'b92a905a245d2523e9ca49dd382dad12'
j = 1750571387066  # <class 'int'>
h = '34839810'
c_data = ('{"pageNumber": 1, ''"keyword": "python爬虫书籍", ''"fromFilter": false, ''"rowsPerPage": 30, ''"sortValue": "", ''"sortField": "", ''"customDistance": "", ''"gps": "", ''"propValueStr": {}, ''"customGps": "", ''"searchReqFromPage": "pcSearch", ''"extraFilterValue": "{}", ''"userPositionJson": "{}"}')
result_str = d_token + "&" + str(j) + "&" + h + "&" + c_data
# 使用 md5 加密
md_str = hashlib.md5()
# 传入加密参数
md_str.update(result_str.encode('utf-8'))
# 进行加密处理
sign = md_str.hexdigest()  # <class 'str'>
print(sign)  # 1c32f4de228112a3a59df6972d186b41

3)Python 代码实现

# 导入数据请求模块
import requests
import csv
# 导入哈希模块
import hashlib
import timedef get_sign(page):d_token = '...'  # token 是有时效性的,请自行填入j = int(time.time() * 1000)h = '...'c_data = ('{"pageNumber": %d, ...}') % pageresult_str = d_token + "&" + str(j) + "&" + h + "&" + c_data# 使用 md5 加密md_str = hashlib.md5()# 传入加密参数md_str.update(result_str.encode('utf-8'))# 进行加密处理sign = md_str.hexdigest()return sign, j, c_datadef get_data_csv(file_path, head_name):# 模拟浏览器(请求标头)request_header = {'Referer': 'https://www.goofish.com/',# cookie 代表用户信息,常用于检测是否有登陆账户(不论是否登录都有 cookie)# cookie 是有时效性的,请自行填入'Cookie': '...',# user-agent 代表用户代理,显示浏览器 / 设备的基本身份信息'User-Agent': '...'}# 请求网址request_url = r'https://h5api.m.goofish.com/h5/mtop.taobao.idlemtopsearch.pc.search/1.0/'# 创建文件对象f = open(file_path, mode='a', encoding='utf-8-sig', newline='')# 字典写入方法cd = csv.DictWriter(f, fieldnames=head_name)cd.writeheader()# for 构建循环翻页num = 10for i in range(1, num + 1):print(f'正在采集第 {i} 页数据…')# 获取 sign 加密参数、时间戳和表单数据sign, j_time, c_data = get_sign(i)# 查询参数query_parameters = {'jsv': '2.7.2','appKey': '34839810','t': str(j_time),'sign': sign,'v': '1.0','type': 'originaljson','accountSite': 'xianyu','dataType': 'json','timeout': '20000','api': 'mtop.taobao.idlemtopsearch.pc.search','sessionOption': 'AutoLoginOnly','spm_cnt': 'a21ybx.search.0.0','spm_pre': 'a21ybx.home.searchSuggest.1.4c053da6IXTxSx','log_id': '4c053da6IXTxSx'}# 表单数据form_data = {"data": c_data}# 发送请求response = requests.post(url=request_url, params=query_parameters, data=form_data, headers=request_header)# 获取响应的 json 数据 → 字典数据类型data_json = response.json()# 键值对取值,提取商品信息所在列表info_list = data_json['data']['resultList']# for 循环遍历,提取列表里的元素for index in info_list:# 处理用户名nick_name = '未知'if 'userNickName' in index['data']['item']['main']['exContent']:nick_name = index['data']['item']['main']['exContent']['userNickName']# 处理售价price_list = index['data']['item']['main']['exContent']['price']price = ''for p in price_list:price += p['text']# 处理详情页链接item_id = index['data']['item']['main']['exContent']['itemId']link = f'https://www.goofish.com/item?id={item_id}'temporarily_dict = {'标题': index['data']['item']['main']['exContent']['title'],'地区': index['data']['item']['main']['exContent']['area'],'售价': price,'用户名': nick_name,'详情页链接': link}cd.writerow(temporarily_dict)f.close()if __name__ == '__main__':f_path = './fish_python.csv'h_name = ['标题', '地区', '售价', '用户名', '详情页链接']get_data_csv(f_path, h_name)

运行结果展示:

注意:运行时可能会出现 {'api': 'mtop.taobao.idlemtopsearch.pc.search', 'data': {}, 'ret': ['FAIL_SYS_TOKEN_EXOIRED::令牌过期'], 'v': '1.0'} 的错误,那是因为 d_token 和 cookie 都是具有时效性的,每过一段时间都会改变,因此自行修改成当下的 d_token 值和 cookie 值即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85897.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL行转列、列转行

要达到的效果&#xff1a; MySQL不支持动态行转列 原始数据&#xff1a; 以行的方式存储 CREATE TABLE product_sales (id INT AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(50) NOT NULL,category VARCHAR(50) NOT NULL,sales_volume INT NOT NULL,sales_date DATE N…

云创智称YunCharge充电桩互联互通平台使用说明讲解

云创智称YunCharge充电桩互联互通平台使用说明讲解 一、云创智称YunCharge互联互通平台简介 云创智称YunCharge&#xff08;YunCharge&#xff09;互联互通平台&#xff0c;旨在整合全国充电桩资源&#xff0c;实现多运营商、多平台、多用户的统一接入和管理&#xff0c;打造开…

HTML+JS实现类型excel的纯静态页面表格,同时单元格内容可编辑

<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>在线表格</title><style>table {border…

Gartner金融AI应用机会雷达-学习心得

一、引言 在当今数字化时代,人工智能(AI)技术正以前所未有的速度改变着各个行业,金融领域也不例外。财务团队面临着如何从AI投资中获取最大价值的挑战。许多首席财务官(CFO)和财务领导者期望在未来几年增加对AI的投入并从中获得更多收益。据调查,90%的CFO和财务领导者预…

像素着色器没有绘制的原因

背景 directX调用了 draw&#xff0c;顶点着色器运行&#xff0c;但是像素着色器没有运行。 原因 光栅化阶段被剔除 说明&#xff1a;如果几何图元&#xff08;如三角形&#xff09;在光栅化阶段被剔除&#xff0c;像素着色器就不会被调用。常见剔除原因&#xff1a; 背面…

jenkins对接、jenkins-rest

https://www.bilibili.com/video/BV1RqNRz5Eo6 Jenkins是一款常见的构建管理工具&#xff0c;配置好后操作也很简单&#xff0c;只需去控制台找到对应的项目&#xff0c;再输入分支名即可 如果每次只发个位数的项目到也还好&#xff0c;一个个进去点嘛。但如果一次要发几十个项…

北斗导航深度接入小程序打车:高精度定位如何解决定位漂移难题?

你有没有遇到过这样的尴尬&#xff1a; 在写字楼、地下车库或密集楼群中叫车&#xff0c;系统显示的位置和你实际所在位置差了几十米甚至上百米&#xff1b;司机因为找不到你而绕圈&#xff0c;耽误时间还多花平台费用&#xff1b;有时明明站在A出口&#xff0c;司机却跑到B口…

MySQL 主要集群解决方案

MySQL 主要有以下几种集群解决方案&#xff0c;每种方案针对不同的应用场景和需求设计&#xff1a; 1. MySQL Replication&#xff08;主从复制&#xff09; 类型&#xff1a;异步/半同步复制架构&#xff1a;单主多从特点&#xff1a; 读写分离&#xff0c;主库写&#xff0c…

基于vue3+express的非遗宣传网站

​ 一个课程大作业&#xff0c;需要源码可联系&#xff0c;可以在http://8.138.189.55:3001/浏览效果 前端技术 Vue.js 3&#xff1a;我选择了Vue 3作为核心前端框架&#xff0c;并采用了其最新的Composition API开发模式&#xff0c;这使得代码组织更加灵活&#xff0c;逻辑…

【7】图像变换(上)

本节偏难,不用过于深究 考纲 文章目录 可考题【简答题】补充第三版内容:图像金字塔2023甄题【压轴题】习题7.1【第三版】1 基图像2 与傅里叶相关的变换2.1 离散哈特利变换(DHT)可考题【简答题】2.2 离散余弦变换(DCT)2021甄题【简答题】2.3 离散正弦变换(DST)可考题【简…

WinUI3入门9:自制SplitPanel

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

【面板数据】上市公司投资者保护指数(2010-2023年)

上市公司投资者保护指数是基于上市公司年报中公开披露的多项内容&#xff0c;从信息透明度、公司治理结构、关联交易披露、控股股东行为规范等多个维度&#xff0c;评估企业是否在制度上和实际操作中有效保障投资者&#xff0c;特别是中小投资者的合法权益。本分享数据基于我国…

如何解决USB远距离传输难题?一文了解POE USB延长器及其行业应用

在日常办公、教学、医疗和工业系统中&#xff0c;USB接口设备扮演着越来越关键的角色。无论是视频采集设备、键盘鼠标&#xff0c;还是打印机、条码枪&#xff0c;USB早已成为主流连接标准。然而&#xff0c;USB原生传输距离的限制&#xff08;通常在5米以内&#xff09;常常成…

PostgreSQL(TODO)

(TODO) 功能MySQLPostgreSQLJSON 支持支持&#xff0c;但功能相对弱非常强大&#xff0c;支持 JSONB、索引、函数等并发控制行级锁&#xff08;InnoDB&#xff09;&#xff0c;不支持 MVCC多版本并发控制&#xff08;MVCC&#xff09;&#xff0c;性能更好存储过程/触发器支持&…

LINUX 623 FTP回顾

FTP 权限 /etc/vsftpd/vsftpd.conf anonymous_enableNO local_enableNO 服务器 .20 [rootweb vsftpd]# grep -v ^# vsftpd.conf anonymous_enableNO local_enableYES local_root/data/kefu2 chroot_local_userYES allow_writeable_chrootYES write_enableYES local_umask02…

leetcode:77. 组合

学习要点 学习回溯思想&#xff0c;学习回溯技巧&#xff1b;大家应当先看一下下面这几道题 leetcode&#xff1a;46. 全排列-CSDN博客leetcode&#xff1a;78. 子集-CSDN博客leetcode&#xff1a;90. 子集 II-CSDN博客 题目链接 77. 组合 - 力扣&#xff08;LeetCode&#x…

自定义主题,echarts系列嵌套

自定义主题&#xff0c;echarts系列嵌套&#xff0c;完善map地图系列与lines系列抛物线 自定义主题开发设计&#xff08;如传感器数据可视化&#xff09; 1.使用typetreemap自定义 TreeMap 主题&#xff08;矩形树图系列&#xff09; 2.在矩形树图中画typelines动态连线和typee…

速度与精度的结合:Faster R-CNN模型的性能剖析

目标检测作为计算机视觉领域的核心问题之一&#xff0c;其重要性随着深度学习技术的发展而日益凸显。本文深入探讨了基于深度学习的Faster R-CNN模型&#xff0c;这是一种革命性的目标检测框架&#xff0c;它通过引入区域提议网络&#xff08;Region Proposal Network, RPN&…

计算机网络--期末速通版

以下总结提纲来自于hcgg&#xff0c;伟大无需多言。socket编程没有写进去&#xff0c;Rdt的话我后来感觉可能只考概念&#xff0c;其余我感觉会考的部分都在里面了&#xff0c;如果有错误或者解释不清楚造成的疑问&#xff0c;希望大家及时指正&#xff0c;感谢。 应用层 DNS…

AI浪潮拐点:MCP与A2A协议如何重塑AI智能体协作生态

一、AI技术演进的必然拐点:从单机智能到群体协作 当AI技术从单模型推理迈向复杂系统协作,MCP(模型协作协议)与A2A(智能体间协作协议)的诞生标志着产业变革的关键转折点。这一演进并非偶然,而是技术发展与社会需求双重驱动的必然结果。 从技术脉络看,AI正经历从"…