news 2026/9/26 5:34:15

爬虫数据清洗通用工具包:日期、金额、单位与空值处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
爬虫数据清洗通用工具包:日期、金额、单位与空值处理

做爬虫这些年,我越来越确认一件事:爬虫最耗时的环节,从来不是写请求和解析选择器,而是拿到数据后的清洗。你费劲把网页上的信息抓下来,结果日期一会儿是"2024年12月2日",一会儿是"12/02/2024",金额带着货币符号和千分位,空值更是形态各异。这篇文章分享的就是我沉淀下来的一套通用清洗工具包,专门对付日期、金额、单位、空值这四类高频脏数据,代码可复用、可扩展,零基础也能直接用。核心思路很简单:把"变化多端的字符串"变成"格式统一的结构化数据",后续入库、分析和可视化才算真正开始。

1. 爬虫数据为什么总是一团乱麻

1.1 脏数据的真实来源:抓回来只是第一步

爬虫从网页上拿到的数据,本质上只是"网页源码的切片"。网页本身是给人看的,不是给程序用的,所以格式混乱是常态。我从实际项目中归纳了三类最常见的问题来源。

第一类是HTML结构嵌套带来的串位。很多网站用表格或div嵌套展示数据,解析时如果selector写得不够精确,很容易把相邻字段混进来。比如某电商平台的价格字段,页面源码里可能同时存在"促销价"和"划线价",一不小心就把"划线价"当成真实价格抓下来了,这种数据其实是"假脏数据",它格式正常,但语义错了,清洗阶段要格外小心。

第二类是页面渲染导致的缺失。现在越来越多的网站是前后端分离架构,数据由JavaScript动态加载,直接用requests抓到的HTML里根本没有这些字段。即便你用Selenium或者Playwright渲染之后再抓,由于网络延迟、懒加载策略,也会出现某些字段抓不到的情况。这种缺失在数据里就直接表现为空值、None、"null"字符串,甚至是一个孤零零的"--"。

第三类是编码和字符问题。中文网页常见GBK/GB2312编码,英文网页常用UTF-8,偶尔还有BOM头、乱码字符混进来。金额符号可能是全角也可能是半角,日期里的分隔符可能是"/"、"-"、"年月日",空格和换行也可能混在其中。这些看似琐碎的问题,如果不在清洗阶段统一处理,到了分析和建模阶段会逐一爆炸。

1.2 清洗在爬虫链路中的位置:咽喉要道

一个完整的爬虫项目链路,大致是:采集、解析、清洗、存储、分析。很多人把精力狂热地投入到前两步,觉得"抓到页面、提取字段"就完事了,结果数据一入库就发现问题:日期字段有的是字符串,有的是datetime,有的是时间戳;金额字段有的带"万"字,有的带千分位;空值满天飞,写SQL都难受。

清洗环节恰恰是这条链路的咽喉。它做的是把"从网页提取出来的、格式各异的原始字符串",转换成"结构明确、类型统一、语义清晰的数据",下游不管是存进MySQL、SQLite,还是交给pandas做分析,都能省一大堆事。

特别提一句,清洗和解析要分开。解析是"把字段从HTML里抠出来",清洗是"把抠出来的字段变成靠谱的数据"。两个环节分开写,代码清晰,测试也方便。我见过不少新手把正则和replace乱掺在一起,字段也抠了、格式也改了,但代码完全没法复用,换一个网站就重写一遍,非常痛苦。这也是我想把清洗工具独立出来的初衷。

2. 工具包设计思路:一个类解决一类问题

2.1 为什么不做成散装函数

写清洗工具很多人第一反应是"写几个函数不就行了"。确实,clean_date()、clean_amount()几个函数摆在那里,看起来也能用。但真进了实战项目你会发现,散装函数有几个很难受的问题。

第一是参数无处收敛。清洗规则是需要配置的,比方说空值用什么策略处理、日期解析失败返回什么兜底值、金额单位如何换算,这些参数如果散落在各个函数里,每个调用处都要传一遍,传着传着就有人漏传,导致同一个字段在不同地方清洗行为不一致。

第二是没有状态和复用能力。项目里经常需要针对同一个网站的多个页面、甚至多个网站的数据统一清洗,如果清洗逻辑是散装的,你得在每一个爬虫脚本里复制粘贴一份,后续规则一改,全项目都要跟着改。

第三是测试困难。散装函数没有统一的入口,想写单元测试就得分别import各个函数,测试代码比业务代码还长。

所以我把清洗逻辑封装成一个UniversalCleaner类。类的优势在于:构造时统一配置,方法按职责划分,调用链清晰,还能挂载日志、统计、异常处理这些辅助能力。它像一个"数据清洗加工厂",你往里扔原始字符串,它吐出来干净的Python对象。

2.2 关键设计决策:兜底值、空值策略与调用链

我这个工具包有三个关键设计决策,直接影响复用体验。

第一个是兜底值机制。清洗类方法统一带default参数,任何解析失败、空值、类型不符的情况,都不抛异常,而是返回兜底值。为什么?因为爬虫面对的是非受控数据源,一个字段格式不对就中断整个爬虫,代价太高。兜底值可以让你在数据量大的场景下"先跑通再修正",配合日志记录,后续再去分析哪些字段触发了兜底。

第二个是空值策略统一配置。null_strategy参数在初始化时定好,fill表示填充,drop表示删除,mark表示标记保留。这个不单单是某个字段的处理,而是针对整批数据的统一策略。比如写数据库之前你想填充默认值,分析前你想删除全空行,改一个参数就行,不用动业务代码。

第三个是方法返回类型确定。清洗器的每个方法都返回确定类型的结果:日期返回datetime,金额返回float,空值判断返回bool,这就让清洗可以像流水线一样串联。先判断空值,再清洗日期,再清洗金额,每一步的输出都是下一步的输入,逻辑非常顺畅。

3. 四大清洗模块详解与实现

3.1 日期清洗:把"花式日期"统一成datetime

日期是爬虫数据里脏得最离谱的字段。同一个"2024年12月2日",在不同网站里可能是下面这些形态:

原始字符串说明
2024-12-02最标准的ISO格式
2024/12/02斜杠分隔
2024年12月2日中文格式
12月02日缺少年份
02/12/2024日/月/年(欧美习惯)
昨天相对时间
3小时前相对时间(评论区常见)
Dec 2, 2024英文缩写月

如果还有时间部分,比如"2024-12-02 14:30:00",处理逻辑又要多一截。我的clean_date方法分三步处理:

第一步,识别空值和非法输入,直接返回兜底值; 第二步,处理相对时间关键词,比如"刚刚""x分钟前""x小时前""昨天""x天前",这类数据在评论区、公告、订单记录里特别常见; 第三步,依次尝试多种日期格式模板解析,匹配成功就转成datetime,全部失败就返回兜底值。

代码实现如下(基于常见实践封装,可直接复用):

import re from datetime import datetime, timedelta def clean_date(raw, default=None, now=None): """把花式日期字符串统一成 datetime,解析失败返回 default""" if now is None: now = datetime.now() if raw is None: return default text = str(raw).strip() # 1. 空值判断 lower = text.lower() if not text or lower in ('null', 'none', 'nan', 'n/a', 'na'): return default # 2. 相对时间 if text in ('刚刚', '现在', 'just now'): return now match = re.match(r'(\d+)\s*(分钟|小时|天)前', text) if match: num, unit = int(match.group(1)), match.group(2) if unit == '分钟': return now - timedelta(minutes=num) if unit == '小时': return now - timedelta(hours=num) if unit == '天': return now - timedelta(days=num) if text == '昨天': return now - timedelta(days=1) if text == '前天': return now - timedelta(days=2) # 3. 完整日期格式,按优先级依次尝试 formats = [ ('%Y-%m-%d %H:%M:%S', r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'), ('%Y/%m/%d %H:%M:%S', r'\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}'), ('%Y-%m-%d', r'\d{4}-\d{2}-\d{2}'), ('%Y/%m/%d', r'\d{4}/\d{2}/\d{2}'), ('%Y年%m月%d日', r'\d{4}年\d{1,2}月\d{1,2}日'), ('%Y.%m.%d', r'\d{4}\.\d{2}\.\d{2}'), ('%m月%d日', r'\d{1,2}月\d{1,2}日'), ] for fmt, pattern in formats: if re.fullmatch(pattern, text): try: parsed = datetime.strptime(text, fmt) # 缺少年份时补当前年份 if fmt == '%m月%d日': parsed = parsed.replace(year=now.year) return parsed except ValueError: continue # 英文月份:Dec 2, 2024 match = re.fullmatch(r'([A-Za-z]{3})\.?\s+(\d{1,2}),?\s+(\d{4})', text) if match: month_map = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12} mon = month_map.get(match.group(1).capitalize()) if mon: try: return datetime(int(match.group(3)), mon, int(match.group(2))) except ValueError: pass return default

这段代码看起来不短,但逻辑是线性的:先判空,再处理相对时间,再按格式模板匹配。日常爬虫数据九成以上都能覆盖。真正要注意的是优先级,带时间的完整格式要放在不带时间的前面,否则"2024-12-02 14:30:00"会被%Y-%m-%d匹配到只剩日期,时间部分丢了。

我在实际项目里还踩过一个坑:有些网站日期里混进全角字符,比如"2024-12-02",看起来一模一样,但strptime不认。遇到这种情况有两种处理思路:要么先做全角转半角,要么用正则把数字部分提取出来再拼标准格式。我建议在清洗器里面加一个全角转半角的小工具函数,一劳永逸。

3.2 金额清洗:符号、千分位、单位一网打尽

金额字段的脏,主要体现在三个方面:货币符号(¥、¥、$)、千分位逗号、单位词(万、亿、元)。此外还有全角数字、空格、多余文字混入的情况。我的思路是:只提取数值主干,再根据单位词做数量级换算,最终统一输出float类型。

def clean_amount(raw, default=0.0): """金额字符串转 float,支持万/亿/千等中文数量级""" if raw is None: return default text = str(raw).replace(',', '').replace(',', '').replace(' ', '').strip() if not text or text.lower() in ('null', 'none', 'n/a', 'nan', '--', '-'): return default # 提取数字部分,支持负号和小数 match = re.search(r'-?\d+(?:\.\d+)?', text) if not match: return default num = float(match.group()) if '亿' in text: num *= 100000000 elif '万' in text: num *= 10000 elif '千' in text or re.search(r'\d\s*k\b', text, re.IGNORECASE): num *= 1000 return round(num, 4)

这个版本把"¥1,234.56"转成1234.56,把"1.2万"转成12000.0,把"-3,500元"转成-3500.0,覆盖了绝大多数中文站点的金额形态。需要注意的几个边界:

一是负数的处理。有些爬虫抓到的价格可能带负号(比如优惠券抵扣后的金额),正则里要保留负号,否则-3,500会被提取成3500,正负语义就错了。

二是"元"要不要累乘。如果单位是"元",本身就是基础单位,无需换算;但有些网站写"万元",比如某房产网站挂牌价"350万元",这里的"万"已经是数量级,需要乘10000,而"元"只是本位词,不能重复乘。所以单位换算只看数量级词(万、亿、千),不要看本位词(元、块、RMB)。

三是精度问题。金额涉及"万"换算时可能出现浮点误差,比如0.1万算出1000.0000000000001,所以我在返回前统一round到4位小数。如果项目对精度要求极高(比如金融数据),建议后面用Decimal,或者直接把数量级换算保留成整数运算。

我不建议在这种通用工具里做太复杂的货币汇率转换,爬虫抓到的金额通常已经是目标网页展示的最终面值,直接归一化即可。如果确实需要处理多币种,那就得额外加币种识别和汇率参数,这属于业务级功能,不应该放进通用工具包。

3.3 单位清洗:不只是"万"和"亿"

标题里说的"单位"其实涵盖两类:一是数值自带的单位词(万、亿、千),二是字段本身的度量单位(重量kg、长度米、面积平米等)。第一类我在金额清洗里已经顺手处理了,这一节重点说第二类,因为它在爬虫数据里同样高频出现,比如商品详情页的"2.5kg"、"500g",房产页的"120㎡"、"85平米"。

单位归一化的核心思路是:先定义一张单位换算表,把各种写法映射到基准单位,再用统一公式换算。我习惯用"每类基准单位一张表"的方式组织:

UNIT_WEIGHT = { 'kg': 1.0, '千克': 1.0, '公斤': 1.0, 'g': 0.001, '克': 0.001, '斤': 0.5, '两': 0.05, 't': 1000.0, '吨': 1000.0, 'lbs': 0.45359237, '磅': 0.45359237, } UNIT_LENGTH = { 'm': 1.0, '米': 1.0, 'cm': 0.01, '厘米': 0.01, 'mm': 0.001, '毫米': 0.001, 'km': 1000.0, '公里': 1000.0, '英尺': 0.3048, 'ft': 0.3048, '英寸': 0.0254, 'in': 0.0254, } def clean_unit(value_text, unit_map=None, default=None): """把带单位的字符串拆成数值,统一换算到基准单位""" if unit_map is None: unit_map = UNIT_WEIGHT if value_text is None: return default text = str(value_text).strip().lower() match = re.search(r'(-?\d+(?:\.\d+)?)\s*([a-z\u4e00-\u9fa5]+)', text) if not match: return default num = float(match.group(1)) raw_unit = match.group(2) if raw_unit in unit_map: return round(num * unit_map[raw_unit], 4) return default

实际使用时,你可以根据字段语义选择不同的单位表。比如商品重量抓到的原始字段"2.5公斤",调用clean_unit('2.5公斤', UNIT_WEIGHT)直接得到2.5(基准kg)。如果和你下游要求的单位一致,就不用再二次处理了。

单位清洗的坑主要在中文和英文单位的混合写法,以及单位词和数字之间有没有空格。比如"2.5 kg"和"2.5kg"都能匹配,但"2.5KG"如果不先lower()就会漏掉。再比如"1000克"和"1千克",结果都是1kg,但如果不做换算,下游就乱了。

多说一句,单位清洗不建议在爬虫解析阶段做,因为你可能同时抓多个列表页和详情页,字段的单位表可能不同,统一在清洗阶段处理更安全。

3.4 空值清洗:识别、填充、删除、标记

空值是爬虫数据里最隐蔽的坑。为什么说隐蔽?因为"空值"不只是None和空字符串,它有一大堆形态:

原始值常见来源
None / null / NULLJSON、数据库
NaN / nanpandas、numpy
"" / " "HTML空标签
"null" / "none" / "N/A" / "n/a" / "NA"网页模板占位
"--" / "-" / "—"前端占位符
"\N" / " " / "(null)"数据导入导出
"待定" / "暂无" / "未知"业务占位语义

我的is_null方法会把上面所有这些形态统一识别成"空",然后根据策略统一处理。字段级判断代码:

import numpy as np def is_null(value): """识别各种形态的空值""" if value is None: return True if isinstance(value, float) and np.isnan(value): return True if isinstance(value, str): text = value.strip() return text in ('', 'null', 'None', 'NULL', 'none', 'nan', 'NaN', 'N/A', 'n/a', 'NA', '--', '-', '—', '\\N', '<null>', '(null)', '待定', '暂无', '未知', '无') return False def apply_null_strategy(value, strategy='fill', fill_value=None): """按策略处理空值,返回清洗后的值""" if not is_null(value): return value if strategy == 'fill': return fill_value elif strategy == 'drop': return np.nan # 标记为需要删除的行 return '__MISSING__' # mark 策略:保留标记让后续业务判断

这里有三件事要特别提醒。

第一,is_null必须是"宽识别",因为爬虫拿到的空值形态远比你想象的丰富。我见过有网站用&nbsp;(非换行空格)填充空字段,字符串strip后还有内容,肉眼看着是空的,程序却识别不出来。这种情况建议把\u00a0、\u200b这类特殊空白符也加进替换逻辑。

第二,apply_null_strategy的返回值语义要清晰。填充策略直接返回填充值;删除策略我返回np.nan,意思是"这一行请干掉";标记策略返回一个特定字符串,让下游能感知"这里原本是空的"。三种策略对应三种下游场景,别混着用。

第三,空值清洗要和日期、金额清洗串起来。我的经验是:先做空值判断,再做类型转换。否则一个None丢进clean_amount,虽然方法内部也会判空,但每个方法都判空会导致代码重复,串起来更优雅:

# 串行调用示例 if is_null(raw_date): date_obj = default_date else: date_obj = clean_date(raw_date)

4. 把清洗工具包接入爬虫主流程

4.1 在解析循环中调用清洗方法

工具包写好了,怎么用?这是零基础读者最关心的问题。最理想的方式,是在爬虫的解析环节结束、构造结构化数据字典之前,把每个字段交给对应的清洗方法,这样items列表里装的就是清洗后的干净数据,后续无论转DataFrame还是直接入库,都不用再反复处理。我以一个商品列表爬虫为例,假设解析页面的item字典长这样:

items = [] for item_node in page_soup.select('.item-list .item'): raw = { 'title': item_node.select_one('.title').text.strip(), 'price': item_node.select_one('.price').text, 'publish_time': item_node.select_one('.time').text, 'weight': item_node.select_one('.weight').text, 'sold_count': item_node.select_one('.sold').text, } cleaned = { 'title': apply_null_strategy(raw['title']), 'price': clean_amount(raw['price']), 'publish_time': clean_date(raw['publish_time']), 'weight': clean_unit(raw['weight']), 'sold_count': clean_amount(raw['sold_count']), } items.append(cleaned)

注意几个细节:

title这类文本字段我用了apply_null_strategy而不是简单的strip(),因为空值策略要全局统一,不能某个字段特殊处理。

sold_count字段虽然看起来是整数,但网页里可能显示"1.2万",所以复用了金额清洗方法,因为它本质上也是"数字+数量级词"的组合。

如果某个清洗方法返回兜底值,一定要记录日志,我习惯在方法里挂一个回调或者logger,记录触发兜底的原因和原始值。这样后续可以回溯到底是网站改版了,还是解析规则出了问题。

4.2 批量清洗:当DataFrame遇上清洗器

很多时候爬虫不是一条一条处理数据,而是攒一批一起入库。这种情况下我会先把解析结果转成pandas DataFrame,然后利用Series的map方法,对每一列批量调用清洗器,比for循环快得多,代码也简洁:

import pandas as pd df = pd.DataFrame(items) # 批量处理 df['price'] = df['price'].map(clean_amount) df['publish_time'] = df['publish_time'].map(lambda x: clean_date(x)) df['weight'] = df['weight'].map(lambda x: clean_unit(x, UNIT_WEIGHT)) # 删除空值行 df = df.dropna(subset=['price', 'publish_time']).reset_index(drop=True)

map方法会把列里每个值逐个放进清洗方法,结果以Series返回。需要注意的是,如果你的清洗方法是类方法且带默认参数,直接df['col'].map(cleaner.clean_amount)可能报错,因为map只会传一个位置参数进去。解决办法是包一层lambda,或者用functools.partial固定默认参数。这一点是我实际踩过的坑,报错信息还不直观。

批量场景下,性能也值得关注。如果你有几十万条数据,逐行调Python循环基本等不起。建议优先用pandas的内置方法(如pd.to_datetime、str.replace)做初步清洗,只把清洗器用在真正需要复杂逻辑的列上。两者结合,速度和复用性都能兼顾。

5. 常见问题与排查技巧实录

5.1 日期解析失败的6种典型场景

场景原始值原因处理建议
英文月份缩写Mar 2, 2024格式不在模板列表加英文月份映射
全角数字2024-12-02编码未转换先全角转半角
日期时间混排2024-12-02T14:30:00ISO8601的T分隔符加%Y-%m-%dT%H:%M:%S模板
时间戳1704009600数字字符串被当日期先判断是否为纯数字,按13位毫秒/10位秒分别处理
相对时间2024-12-02 更新于12-05字符串夹杂无关文字用正则提取其中的日期子串
缺失日期无页面本身没展示日期返回兜底值并记录日志

这里补充一个时间戳的坑:有的网站直接给毫秒级时间戳(13位),有的给秒级(10位),千万别统一除以1000,否则日期全错了。我的习惯是先判断字符串长度:13位是毫秒,10位是秒,再分别处理。

5.2 数据库写入时空值覆盖的惨痛教训

这个坑我必须单独拎出来讲。我早期做爬虫时,每天晚上定时把当日数据全量更新到线上数据库,用的SQL是傻瓜式的UPDATE 表 SET 字段=值 WHERE id=某值。看起来没问题,直到某天线上某个字段突然变成空值,排查半天才发现:爬虫当天那个字段没抓到,空值策略是drop,结果写入时字段值变成了空字符串,直接把数据库里原本正确的内容覆盖了。

所以后来我给自己定了一条铁律:爬虫数据入库前,空值字段必须明确处理,绝不允许"空值悄悄覆盖旧值"。具体做法有三层:

第一层,上游拦截。清洗阶段把空值统一处理成填充值或标记值,不让原生的None流向数据库。

第二层,SQL防御。如果用的是UPDATE操作,强烈建议加WHERE条件,确保只有新值非空时才执行更新,避免空值覆盖——这一点和很多后端实践里提到的"UPDATE加WHERE EXISTS条件"是同一个思路。

第三层,对比校验。如果是全量更新,入库前先对比旧数据和新数据的非空字段数量,差异过大说明爬虫可能大面积漏抓,先报警再说。

这个坑在爬虫项目的后期最容易暴雷,因为数据量大了以后,单个字段的空值很难用肉眼发现,等下游分析发现异常时,数据已经被覆盖了好几轮。宁可清洗阶段多花点功夫,也不要省这个保险。

5.3 单位换算带来精度损失

单位清洗在浮点数换算上有一个隐藏问题:它不是精确运算。比如"1斤"换算成"0.5kg",0.5 * 1.0还好,但"3两"换算成3 * 0.05,结果是0.15000000000000002,如果下游做精确比较就会出问题。我的处理办法是:

一切换算结果统一round(…, 4),同时把换算表里的系数尽量写成整数比值(比如斤系数写成1/2而不是0.5),这样在部分场景下能减少浮点误差。如果项目要精确到厘(0.01元)这种级别,建议直接换成decimal.Decimal。

另外一个常见问题是字段语义混淆。有些网页把"价格"和"销量"放在同一个带单位的字符串里,比如"¥99 已售1.2万件",如果你直接扔进clean_amount,正则会把第一个数字99抓出来当价格,后面的1.2万就丢了。这种时候必须先在解析阶段把字段拆开,各走各的清洗方法,不能让清洗器背锅。

6. 工具包的扩展方向与实践建议

6.1 让清洗工具包支持业务自定义规则

通用工具包的价值在于"通用",但真正跑进生产环境,每个业务都有自己的特殊规则。比如某些平台的价格带括号说明"含税",某些日期后面跟着"(补发)"这种状态词。我在设计类的时候预留了一个自定义规则入口,你可以传入一个custom_rules字典或回调函数:

cleaner = UniversalCleaner( null_strategy='fill', null_fill_value='未知', custom_rules={ 'price': lambda x: x.replace('含税', '').strip(), 'publish_time': lambda x: x.split('(')[0].strip(), } )

原则是:通用逻辑写在工具包里,业务差异写在规则里,两者分离。这样清洗器本身只做"格式归一化",不掺入任何业务判断,下一个项目还能继续用。

6.2 实测下来最省心的组合方式

根据我个人实际操作经验,爬虫数据清洗最省心的组合是:解析阶段拿原始字符串 → 用本工具包做字段级清洗 → 用pandas做列级批量处理 → 入库前再做一次空值总检查。三层防护,基本上能把爬虫数据90%以上的脏问题挡在门外。

这套流程我用了好几年,稳定性明显比早期"抓到什么存什么"要高。尤其是空值总检查这一步,我习惯在入库前跑一行:df.isnull().sum(),看一眼各字段空值数量有没有突变。如果昨晚还是0,今天变成5000,那大概率是目标网站改版了,爬虫解析规则需要调整。这种问题越早发现,损失越小。

最后再分享一个小技巧:清洗工具包里一定要加日志记录,哪怕是简单的print或logging。特别是兜底值触发时,一定要打印原始值和触发原因。我早期没有这个习惯,数据出问题全靠猜,加完日志之后,问题定位速度提升了一个量级。这一点对任何规模的爬虫项目都适用。

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

使用MQTT协议连接华为物联网平台:几个连接参数的生成规则

华为物联网平台&#xff1a;Security Verificationhttps://support.huaweicloud.com/iothub/index.html 在连接前要先创建产品&#xff0c;然后在产品下面创建设备。创建了设备&#xff0c;就可以获得密钥、设备ID、hostname信息&#xff1a; 点击 查看&#xff1a; 可以看到h…

作者头像 李华
网站建设 2026/9/26 5:33:47

IntelliJ IDEA 2024 完整安装教程:从下载、安装,一篇搞定

前言 "工欲善其事&#xff0c;必先利其器。"对于 Java 开发者来说&#xff0c;IntelliJ IDEA 就是那把最称手的利器。但每到开学季、入职季&#xff0c;总有不少同学在第一步就卡住&#xff1a;官网下载太慢、Ultimate 和 Community 到底选哪个、安装选项勾什么、装…

作者头像 李华
网站建设 2026/9/26 5:32:24

链表刷题三件套:移除元素、设计链表与反转链表的通用技巧

刷链表刷到 Day3&#xff0c;整个人已经进入一种“看见 next 就条件反射画箭头”的状态。今天这三道题——203.移除链表元素、707.设计链表、206.反转链表&#xff0c;放在一起刷完你会发现&#xff0c;链表题翻来覆去就考那几件事&#xff1a;怎么安全地改 next 指向、怎么处理…

作者头像 李华
网站建设 2026/9/26 5:32:17

魔兽争霸3冰封王座新系统安装指南:兼容性配置与中文补丁全解析

1. 为什么现在还有人折腾冰封王座先说一个我自己的观察。前阵子帮朋友装老电脑&#xff0c;翻出一张十几年前刻录的《魔兽争霸3&#xff1a;冰封王座》光盘&#xff0c;顺手装了一遍&#xff0c;结果发现现在想把这游戏跑起来&#xff0c;比当年复杂多了。当年一张盘塞进去&…

作者头像 李华
网站建设 2026/9/26 5:31:53

MySQL连接数上限探秘:从默认151到科学调优与故障排查

1. 先搞清楚&#xff1a;MySQL的连接数到底是被什么限制的做后端开发和数据库运维的&#xff0c;几乎都遇到过那个经典的报错&#xff1a;Too many connections。第一次见到它的时候&#xff0c;我还在用默认配置跑一个小网站&#xff0c;流量稍微一起来&#xff0c;数据库直接…

作者头像 李华
网站建设 2026/9/26 5:31:25

Atlas 300V 24G部署YOLO实战:从模型转换到性能调优全记录

我第一次拿到这块Atlas 300V 24G的时候&#xff0c;心态其实挺简单的&#xff1a;这不就是一张“国产显卡”嘛&#xff0c;插上去、装驱动、跑Python&#xff0c;YOLO的推理应该很快就能出来。结果现实给我上了一课——第一次加载OM模型就报了个ACL_ERROR_RT_PARAM_INVALID&…

作者头像 李华