news 2026/10/18 15:16:57

Scrapy实战:Boss直聘AI岗位数据抓取与多维度分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Scrapy实战:Boss直聘AI岗位数据抓取与多维度分析

简介:这份实战包面向数据分析初学者、求职调研者与课程设计学生,聚焦Boss直聘上大数据、数据分析、机器学习、人工智能等热门方向的岗位采集与统计。资源以Scrapy框架为核心,通过纯HTTP请求高效抓取全国热门城市岗位信息,输出结构化CSV文件,字段涵盖公司名称、职位名称、薪资范围、学历要求、工作经验、工作地点、行业类别与技能关键词,并已做基础去重与格式归一化,可直接导入Excel或pandas、matplotlib、seaborn进行区域分布热力图、薪资中位数对比、学历需求饼图与高频技能词云等可视化分析。压缩包共34个文件,约235KB,以13个py脚本承载爬虫工程与解析逻辑,12个js与html、css支撑辅助页面,另含1个csv数据文件、1个cfg配置及png、txt等说明素材,spiders、pipelines、middlewares、settings等模块齐备,runspider.py可一键启动。目前已有73人学习,适合快速上手岗位数据采集与多维统计的完整练手场景。

1. 招聘数据里的AI岗位真相:为什么值得自己爬一遍

招聘平台上的 AI 岗位数据,是当下技术就业市场最直接的体温计。但大多数人看招聘网站,只是搜几个关键词、翻两页就关了,得到的印象非常粗糙。真正有价值的问题——比如「AI 类岗位里算法和工程的比例到底是多少」「哪些城市在抢人」「薪资区间是怎么分布的」「经验要求集中在几年」——靠手翻是翻不出来的。这个实战包要解决的就是这件事:用 Scrapy 把 Boss 直聘上 AI 类岗位的公开列表数据抓下来,落成 CSV,再做多维度统计和可视化。它适合有 Python 基础、想练一个完整数据管道的开发者,也适合想用真实数据判断求职方向的从业者。整条链路不长,但每一环都有坑,下面按「先立住原理、再动手复现」的顺序拆开讲。

2. 抓取目标拆解与 Scrapy 项目骨架搭建

动手写爬虫之前,最容易被跳过、也最不该跳过的一步,是把「抓什么」定义清楚。很多人一上来就写start_requests,结果爬到一半发现字段对不上、翻页逻辑错乱,只能推倒重来。这一章先把数据模型和项目结构定下来,再进入编码。

2.1 先定字段再写代码:AI 岗位的数据模型

招聘列表页能拿到的信息,通常比详情页少,但胜在量大、翻页快。对「多维度统计」这个目标来说,列表页字段已经够用。我一般会先列一张字段表,明确每个字段的来源和类型,再决定解析逻辑。

字段名含义类型来源
job_title岗位名称str列表卡片标题
salary_raw薪资原始文本str列表卡片,如「20-40K·14薪」
city城市str列表卡片位置信息
experience经验要求str列表卡片标签
education学历要求str列表卡片标签
company公司名str列表卡片
tags技能标签list列表卡片标签区
crawl_time抓取时间str程序生成

这里有个关键决策:薪资不要在原字段上直接清洗。原始文本「20-40K·14薪」里同时包含月薪区间和年终奖信息,一旦在爬取阶段就拆成数字,后面想按「年薪」维度统计时就没有后悔药了。正确做法是原样存salary_raw,清洗放到分析阶段,用单独的解析函数处理。同理,tags存成列表,落 CSV 时用分隔符拼接,分析时再拆开。

字段定完,还要明确抓取范围。AI 类岗位的关键词不能只用一个「AI」,那样会漏掉大量岗位。常见做法是用一组关键词:算法工程师、机器学习、深度学习、NLP、计算机视觉、数据挖掘、大模型、推荐算法。每个关键词单独跑一轮,最后合并去重。去重键用「岗位名 + 公司 + 城市」,因为同一个岗位在不同关键词下可能重复出现。

2.2 创建 Scrapy 项目与目录结构

环境上,Python 3.8 以上即可,Scrapy 用当前稳定版。先建虚拟环境,再装依赖,避免污染全局。

# 创建并激活虚拟环境 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装核心依赖 pip install scrapy pandas matplotlib # 创建 Scrapy 项目 scrapy startproject job_spider cd job_spider scrapy genspider ai_jobs example.com

生成后的目录结构大致是这样,我习惯在spiders同级加一个utils放清洗和解析工具:

job_spider/ ├── scrapy.cfg ├── job_spider/ │ ├── __init__.py │ ├── items.py # 字段定义 │ ├── middlewares.py # 中间件 │ ├── pipelines.py # 数据落盘 │ ├── settings.py # 全局配置 │ ├── utils/ │ │ └── parser.py # 薪资、标签解析 │ └── spiders/ │ └── ai_jobs.py # 主爬虫

items.py里把 2.1 的字段表翻译成 Item 定义,这一步别偷懒,字段写全后面 pipeline 才好统一处理。

import scrapy class JobItem(scrapy.Item): job_title = scrapy.Field() salary_raw = scrapy.Field() city = scrapy.Field() experience = scrapy.Field() education = scrapy.Field() company = scrapy.Field() tags = scrapy.Field() keyword = scrapy.Field() # 记录来自哪个搜索词,便于后续分析 crawl_time = scrapy.Field()

keyword这个字段容易被忽略,但它对多维度统计很有用——你可以对比不同关键词下的岗位数量,判断哪个技术方向需求更旺。字段定义完成后,项目骨架就算立住了,接下来才是真正的解析和翻页。

2.3 settings.py 里必须改的四个配置

Scrapy 默认配置是给「礼貌爬取」设计的,直接跑会非常慢,但也不能无脑调快。下面四个参数是我每次都会动的,改之前先理解每个参数在控制什么。

# settings.py 关键配置 # 1. 遵守 robots 协议,公开数据也保持克制 ROBOTSTXT_OBEY = True # 2. 并发请求数,默认 16,招聘站建议降到 4-8 CONCURRENT_REQUESTS = 6 # 3. 下载延迟,默认 0,必须设置,否则容易被限流 DOWNLOAD_DELAY = 1.5 RANDOMIZE_DOWNLOAD_DELAY = True # 在 0.5~1.5 倍之间随机,更像人 # 4. 自动限速,根据服务器响应动态调整 AUTOTHROTTLE_ENABLED = True AUTOTHROTTLE_START_DELAY = 1.0 AUTOTHROTTLE_MAX_DELAY = 10.0 AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0 # 默认请求头,补一个正常的 UA DEFAULT_REQUEST_HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/120.0 Safari/537.36", "Accept-Language": "zh-CN,zh;q=0.9", }

参数说明:CONCURRENT_REQUESTS控制同时发出的请求数,调太高会触发风控,调太低效率差,6 是个稳妥起点。DOWNLOAD_DELAY是每个请求之间的固定间隔,配合RANDOMIZE_DOWNLOAD_DELAY变成随机间隔,能显著降低被识别为脚本的概率。AUTOTHROTTLE是 Scrapy 自带的自动限速,它会根据响应延迟动态调整,TARGET_CONCURRENCY设为 1.0 表示「一次只稳定处理一个请求」,对招聘站这种反爬较严的目标比较合适。这四个参数不是拍脑袋定的,跑之前先用小批量(比如 3 页)试,观察有没有 403 或验证码,再决定是否放宽。

3. 列表页解析与翻页:把岗位数据稳定抓下来

项目骨架搭好后,核心工作就两件:把列表页的每个岗位卡片解析成 Item,以及让翻页逻辑稳定跑完。这两件事看着简单,实际是翻车最集中的地方。

3.1 用 CSS/XPath 定位岗位卡片

招聘列表页的结构通常是「一个容器包多个卡片,每个卡片里再分标题、薪资、标签」。解析的第一步是找到卡片的选择器,而不是直接去抓单个字段——先定位卡片,再在卡片内部取字段,这样字段之间不会串位。

import scrapy from datetime import datetime from job_spider.items import JobItem class AiJobsSpider(scrapy.Spider): name = "ai_jobs" allowed_domains = ["example.com"] # 一组 AI 相关关键词,逐个搜索 keywords = ["算法工程师", "机器学习", "深度学习", "NLP", "计算机视觉"] def start_requests(self): base = "https://example.com/jobs?query={}&page={}" for kw in self.keywords: # 每个关键词从第 1 页开始 yield scrapy.Request( base.format(kw, 1), callback=self.parse, meta={"keyword": kw, "page": 1}, ) def parse(self, response): keyword = response.meta["keyword"] page = response.meta["page"] # 先定位所有岗位卡片 cards = response.css("div.job-card-wrapper") for card in cards: item = JobItem() item["job_title"] = card.css("span.job-name::text").get(default="").strip() item["salary_raw"] = card.css("span.salary::text").get(default="").strip() item["city"] = card.css("span.job-area::text").get(default="").strip() item["experience"] = card.css("span.tag-exp::text").get(default="").strip() item["education"] = card.css("span.tag-edu::text").get(default="").strip() item["company"] = card.css("h3.company-name::text").get(default="").strip() item["tags"] = card.css("div.tag-list span::text").getall() item["keyword"] = keyword item["crawl_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") yield item # 翻页:找到下一页按钮,存在就继续 next_page = response.css("a.next-page::attr(href)").get() if next_page and page < 30: # 硬上限,防止无限翻页 yield scrapy.Request( response.urljoin(next_page), callback=self.parse, meta={"keyword": keyword, "page": page + 1}, )

逻辑说明:start_requests为每个关键词生成第一页请求,meta里带上关键词和页码,这样在parse里能知道当前数据属于哪个搜索词、翻到第几页。parse先用response.css("div.job-card-wrapper")拿到所有卡片,再对每张卡片单独取字段,get(default="")保证字段缺失时不会报错。翻页部分用response.urljoin把相对链接转成绝对链接,page < 30是硬上限,避免因为页面结构问题陷入死循环。

参数说明:选择器里的类名(job-card-wrapper、job-name等)是示例,实际要对着目标页面的 DOM 改。改的时候用浏览器开发者工具,右键「检查」,确认类名唯一且稳定。如果类名是随机生成的(比如带哈希后缀),就要改用结构选择器,比如div[class*="job-card"]这种模糊匹配。

3.2 翻页的三种失败模式与兜底

翻页是爬虫最容易断的地方,我踩过的坑基本归为三类。

第一类是下一页按钮选择器失效。招聘站经常改版,今天a.next-page能用,明天可能变成button[aria-label="下一页"]。兜底做法是准备多个候选选择器,依次尝试:

def get_next_url(self, response): candidates = [ "a.next-page::attr(href)", "button[aria-label='下一页']::attr(data-url)", "a[class*='next']::attr(href)", ] for sel in candidates: url = response.css(sel).get() if url: return url return None

第二类是翻到最后一页后仍返回内容。有些站点翻到超出范围时,不返回空页,而是返回第一页或一个通用列表,导致爬虫无限循环。解决办法是记录已抓取的岗位去重键,如果连续两页没有新岗位,就主动停止。

第三类是翻页链接是 JavaScript 动态生成。这种情况href可能是javascript:void(0),真正的翻页靠 AJAX。此时要么分析 XHR 请求直接请求接口,要么用scrapy-splash之类的渲染方案。对招聘列表页来说,多数翻页仍是服务端渲染,先按静态处理,遇到动态再单独处理。

提示:翻页逻辑写完,先用一个关键词跑 3 页,把结果打印出来核对字段,确认无误再放开全部关键词和页数。

3.3 数据落成 CSV:Pipeline 与编码坑

数据抓下来后,用 Pipeline 统一落盘。CSV 是最通用的格式,但中文编码和字段拼接是两个高频坑。

import csv from itemadapter import ItemAdapter class CsvPipeline: def open_spider(self, spider): # utf-8-sig 带 BOM,Excel 打开不乱码 self.file = open("ai_jobs.csv", "w", newline="", encoding="utf-8-sig") self.writer = None def process_item(self, item, spider): adapter = ItemAdapter(item) row = adapter.asdict() # tags 是列表,拼成字符串再写入 row["tags"] = "|".join(row.get("tags", [])) if self.writer is None: self.writer = csv.DictWriter(self.file, fieldnames=row.keys()) self.writer.writeheader() self.writer.writerow(row) return item def close_spider(self, spider): self.file.close()

逻辑说明:open_spider在爬虫启动时打开文件,encoding="utf-8-sig"是关键——普通utf-8写出的 CSV 用 Excel 打开会中文乱码,加 BOM 头能解决。process_item里把tags列表用|拼接,避免 CSV 里出现逗号导致列错位。fieldnames用第一行的 keys 动态生成,前提是字段顺序稳定,所以 Item 定义时字段顺序要固定。

参数说明:分隔符选|而不是逗号,是因为技能标签里可能本身含逗号(比如「Python, Go」)。如果标签里也可能含|,就换成更冷门的分隔符,比如\x1f。落盘路径建议带上日期,比如ai_jobs_20250101.csv,方便多轮抓取对比。

4. 多维度统计:从 CSV 到可解释的结论

数据落到 CSV 只是原料,真正有价值的是统计。这一章用 pandas 做几个核心维度的分析,每个维度都对应一个实际能回答的问题。

4.1 薪资文本清洗:把「20-40K·14薪」变成数字

薪资清洗是整个分析里最需要小心的一步,因为格式太杂。常见格式有「20-40K」「20-40K·14薪」「15-25K·13薪」「300-500元/天」。我一般写一个解析函数,返回月薪下限、上限和年薪估算。

import re import pandas as pd def parse_salary(text): """解析薪资文本,返回 (月薪下限K, 月薪上限K, 年薪估算W)""" if not isinstance(text, str) or not text.strip(): return None, None, None # 匹配 20-40K 或 20-40K·14薪 m = re.search(r"(\d+)-(\d+)K(?:·(\d+)薪)?", text) if m: low, high = int(m.group(1)), int(m.group(2)) months = int(m.group(3)) if m.group(3) else 12 # 年薪 = 月薪中位数 * 月数 / 10,单位万 annual = (low + high) / 2 * months / 10 return low, high, round(annual, 1) # 匹配 300-500元/天,按 22 天折算 m = re.search(r"(\d+)-(\d+)元/天", text) if m: low = int(m.group(1)) * 22 / 1000 high = int(m.group(2)) * 22 / 1000 return round(low, 1), round(high, 1), round((low + high) / 2 * 12 / 10, 1) return None, None, None df = pd.read_csv("ai_jobs.csv") df[["salary_low", "salary_high", "salary_annual"]] = df["salary_raw"].apply( lambda x: pd.Series(parse_salary(x)) ) # 丢掉解析失败的记录,并打印数量 before = len(df) df = df.dropna(subset=["salary_low"]) print(f"薪资解析成功 {len(df)}/{before} 条")

逻辑说明:正则先尝试匹配「K·薪」格式,再匹配「元/天」格式,都不匹配就返回 None。年薪估算用月薪中位数乘以月数,单位统一成「万」,方便后续分箱。dropna之后打印成功率,如果成功率低于 80%,说明页面薪资格式和正则不匹配,需要回去补规则。

参数说明:22是每月工作日估算,/1000是把元转成 K,/10是把 K 转成万。这些系数不是绝对的,按自己的口径调整即可,但要在分析结论里注明口径,否则数字没法解释。

4.2 城市、经验、学历三个维度的分布统计

清洗完薪资,就可以做分组统计。下面三个维度是最能反映市场结构的。

# 城市分布:取前 10 city_dist = df["city"].value_counts().head(10) print("城市分布 Top10:") print(city_dist) # 经验要求分布 exp_dist = df["experience"].value_counts() print("\n经验要求分布:") print(exp_dist) # 学历要求分布 edu_dist = df["education"].value_counts() print("\n学历要求分布:") print(edu_dist) # 各城市的平均年薪 city_salary = df.groupby("city")["salary_annual"].agg(["mean", "count"]) city_salary = city_salary[city_salary["count"] >= 5].sort_values("mean", ascending=False) print("\n各城市平均年薪(样本>=5):") print(city_salary.head(10).round(1))

逻辑说明:value_counts直接给出频次分布,groupby加agg同时算均值和样本量。count >= 5这个过滤很重要——样本太少的城市均值没有统计意义,一个只有 1 条记录的城市可能因为一条高薪岗位就排到第一,那是噪声不是信号。

参数说明:head(10)只取前 10,避免输出太长。round(1)保留一位小数。实际分析时,经验字段可能有「经验不限」「1-3年」「3-5年」「5-10年」等值,直接value_counts就能看出分布,不需要额外处理。

4.3 技能标签词频:AI 岗位到底要什么技术

tags字段里藏着技能要求,把它拆开做词频统计,能直接回答「AI 岗位最常要求哪些技术」。

from collections import Counter # 把所有标签拆开、去空格、过滤空值 all_tags = [] for tags in df["tags"].dropna(): for t in str(tags).split("|"): t = t.strip() if t: all_tags.append(t) tag_freq = Counter(all_tags).most_common(20) print("技能标签 Top20:") for tag, cnt in tag_freq: print(f"{tag}: {cnt}")

逻辑说明:tags在 CSV 里是用|拼接的字符串,先split("|")拆回列表,再逐个累加。Counter直接给出词频,most_common(20)取前 20。这一步能看出「Python」「PyTorch」「TensorFlow」「机器学习」这类词的出现频次,从而判断哪些技能是硬通货。

参数说明:如果标签里混入了非技能词(比如「五险一金」「弹性工作」),可以在累加前用一个白名单或黑名单过滤。白名单维护成本高,黑名单更实际,把明显是福利的词列进去排除即可。

5. 可视化与避坑:让图表说话,让爬虫活着

统计数字有了,接下来是可视化。但比画图更重要的是——爬虫得能稳定跑完,数据得能对上。这一章先讲可视化,再集中讲踩坑。

5.1 用 matplotlib 画三张核心图

可视化不需要花哨,三张图足够说明问题:城市分布柱状图、薪资分布直方图、技能词频横向柱状图。

import matplotlib.pyplot as plt # 解决中文显示 plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["axes.unicode_minus"] = False fig, axes = plt.subplots(1, 3, figsize=(18, 5)) # 图1:城市分布 city_dist.plot(kind="bar", ax=axes[0], color="#4C72B0") axes[0].set_title("AI 岗位城市分布 Top10") axes[0].set_ylabel("岗位数") # 图2:薪资分布 df["salary_annual"].hist(bins=20, ax=axes[1], color="#55A868") axes[1].set_title("年薪分布(万)") axes[1].set_xlabel("年薪") # 图3:技能词频 tags, counts = zip(*tag_freq[:15]) axes[2].barh(range(len(tags)), counts, color="#C44E52") axes[2].set_yticks(range(len(tags))) axes[2].set_yticklabels(tags) axes[2].invert_yaxis() axes[2].set_title("技能标签 Top15") plt.tight_layout() plt.savefig("ai_jobs_report.png", dpi=150)

逻辑说明:subplots(1, 3)一行三列,分别放城市、薪资、技能三张图。font.sans-serif设成SimHei解决中文乱码,axes.unicode_minus关掉负号显示问题。barh画横向柱状图,invert_yaxis让词频最高的排在最上面。tight_layout自动调整间距,savefig的dpi=150保证清晰度。

参数说明:bins=20是直方图分箱数,太少看不出分布形状,太多显得毛躁,20 对几百条数据比较合适。颜色代码是 matplotlib 内置色板的十六进制值,换成自己喜欢的即可。

5.2 避坑清单:五条血泪经验

坑一:请求头缺失导致 403。现象是前几个请求正常,之后全部返回 403。原因是默认 UA 被识别为脚本。解决是在settings.py里补全DEFAULT_REQUEST_HEADERS,至少包含User-Agent和Accept-Language,并且开启AUTOTHROTTLE让请求节奏更像人。

坑二:翻页选择器写死,改版即失效。现象是爬到第 2 页就停,日志里没有报错。原因是a.next-page这个类名在新版页面里变了。解决是准备多个候选选择器,用get_next_url依次尝试,同时加「连续两页无新数据就停」的兜底。

坑三:CSV 中文乱码。现象是 Excel 打开 CSV 全是乱码,但用文本编辑器看正常。原因是utf-8不带 BOM,Excel 默认按 GBK 解析。解决是写文件时用encoding="utf-8-sig",多一个 BOM 头,Excel 就认了。

坑四:薪资解析成功率低。现象是dropna之后数据少了一大半。原因是页面薪资格式比预想的多,比如「20-40K」「20K-40K」「20-40K·14薪」「面议」。解决是先把所有解析失败的salary_raw打印出来,人工看一遍,再补正则规则。别指望一次写全。

坑五:标签字段列错位。现象是 CSV 里某些行的列数对不上,pandas 读取时报错。原因是tags列表拼接时用了逗号,而标签本身含逗号。解决是换用|或\x1f这类不常见分隔符,并在DictWriter里确保字段顺序固定。

注意:爬取公开数据也要控制频率,DOWNLOAD_DELAY不要低于 1 秒,单次抓取页数设上限。数据只用于个人分析,不要二次分发。

6. 从能跑到好用:增量抓取与数据校验的两个技巧

爬到数据、画出图,这个实战包的核心链路就通了。但「能跑一次」和「能持续用」之间还有距离。这一章讲两个让方案真正好用的技巧,都是我在反复抓取中磨出来的。

第一个技巧是增量抓取。招聘数据是动态的,今天抓一次、下周再抓一次,才能看出岗位数量的变化趋势。但每次全量重抓既慢又浪费。做法是在 Pipeline 里维护一个已抓取的去重键集合,落盘时先读历史 CSV,把「岗位名 + 公司 + 城市」作为键,已存在的跳过。这样第二次抓取只写入新岗位,CSV 自然变成累积数据集。实现上,open_spider时读一次历史文件,把键存进set,process_item里判断即可。注意去重键不要用薪资,因为薪资会变,用岗位和公司更稳定。

第二个技巧是数据校验。抓完一批数据,别急着分析,先跑几个断言:总记录数是否大于预期下限、salary_raw非空比例是否高于 80%、city字段是否有异常值(比如空字符串占比过高)、crawl_time是否都在合理时间范围内。这些检查用 pandas 几行就能写完:

def validate(df): assert len(df) > 100, "记录数过少,可能抓取中断" assert df["salary_raw"].notna().mean() > 0.8, "薪资字段缺失过多" assert df["city"].replace("", pd.NA).notna().mean() > 0.9, "城市字段异常" assert df["job_title"].duplicated().mean() < 0.3, "重复率过高,检查去重逻辑" print("校验通过,可以进入分析")

逻辑说明:四个断言分别检查数据量、薪资完整性、城市完整性和重复率。任何一个不通过,说明抓取环节有问题,先回去修爬虫,别拿脏数据做分析。参数说明:0.8、0.9、0.3这些阈值按实际数据调整,但要有明确口径,不能因为不通过就随手改低。

我自己的习惯是,每次抓完先跑校验,再跑统计,最后画图。顺序不能反,否则图上的异常你根本分不清是市场信号还是抓取 bug。这个实战包看着简单,但把「抓取—清洗—统计—可视化」每一环都做扎实,比堆一堆花哨模型有用得多。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 15:13:54

VisionMaster标定全流程解析:从成像模型到现场避坑

简介&#xff1a;面向机器视觉开发者的VisionMaster标定方法可运行源码&#xff0c;聚焦九点标定与十二点标定两种主流方案&#xff0c;解决成像设备精确校准与空间映射中的参数提取问题。包体仅8KB&#xff0c;但结构精致&#xff0c;共3个文件&#xff1a;inscode脚本承载核心…

作者头像 李华
网站建设 2026/10/18 15:08:45

DH2URDF:将DH参数表转换为URDF的JavaScript工具

简介&#xff1a;DH2URDF 是一份将 Denavit-Hartenberg 参数表转换为统一机器人描述格式&#xff08;URDF&#xff09;的 JavaScript 工具资源&#xff0c;面向机器人建模、运动学仿真与 ROS 学习方向的开发者及学生。它解决的是手工编写 URDF 繁琐、易错的问题&#xff1a;输入…

作者头像 李华
网站建设 2026/10/18 15:08:43

知识蒸馏高级实战:温度调参、特征对齐与多模态落地

先讲个我自己的事。去年有个项目&#xff0c;线上模型是个大体积的初代Transformer变体&#xff0c;精度确实没得说&#xff0c;但推理延迟快赶上用户容忍度的上限了&#xff0c;每次发版都得压着机器硬扛。组里讨论来讨论去&#xff0c;有人提议砍层数&#xff0c;有人建议换轻…

作者头像 李华
网站建设 2026/10/18 15:08:24

泛微ecology流程表单明细行复制:前端脚本实现与避坑指南

1. 流程明细行复制到底在解决什么问题泛微ecology的流程表单里&#xff0c;明细表是个让人又爱又恨的东西。爱的是它能把一张主表拆成多行结构化数据&#xff0c;比如报销单里的多条费用明细、采购申请里的多个物料条目、出差申请里的多段行程安排。恨的是&#xff0c;一旦明细…

作者头像 李华
网站建设 2026/10/18 15:08:14

支付宝账单前端钩子:DOM捕获原理与合规对账实践

简介&#xff1a;本资源是一个面向Android安全与逆向开发者的Hook技术实践项目&#xff0c;聚焦支付宝客户端&#xff08;v10.1.38.2139&#xff09;的账单列表、账单详情及收款二维码三类核心功能的动态钩子实现&#xff0c;适用于具备Java/Smali基础、熟悉Xposed或Frida框架的…

作者头像 李华
网站建设 2026/10/18 15:08:09

核心语法——面向对象基础

一 概述二 类与对象类的定义1 动态添加属性2 定义类时指定实例属性__init__方法是初始化的方法&#xff0c;会在对象创建时自动调用&#xff0c;可以在该方法中为对象设置对应的属性self:是第一个参数&#xff0c;表示当前所创建出来的实例对象同一个类构建的对象&#xff0c;属…

作者头像 李华