新闻详情

新闻详情

首页 / 资讯中心 / 详情

爬虫数据清洗与存储——从爬下来到用得上的最后一公里

发布时间:2026/10/24 0:27:25来源:尧图网络
爬虫数据清洗与存储——从爬下来到用得上的最后一公里
爬虫最难的不是把数据爬下来而是把乱七八糟的原始数据洗干净存好。这一篇讲爬虫后处理的完整流程——清洗、去重、存储。一、脏数据的常见问题爬下来的原始数据基本是这样的data[{title: iPhone 15 ,price: ¥6,999 ,stock:100件},{title:华为 Mate 60,price:null,stock:50},{title:,price:5.99,stock:-1},{title:小米 14,price:3999,stock:abc},None,]问题清单空格、换行符、特殊符号混在字符串里价格带货币符号和逗号“¥6,999”空值、None、null 混杂数据类型不对库存是数字但爬下来是字符串脏数据负数库存、空标题重复数据二、pandas 数据清洗三板斧1. 去除空格和特殊字符importpandasaspd dfpd.DataFrame(data)# 去除字符串两端的空格和换行df[title]df[title].str.strip()# 去除所有空格有些用全角空格df[title]df[title].str.replace(r\s,,regexTrue)# 清洗价格字段去符号、去逗号df[price]df[price].str.replace(r[¥$,],,regexTrue)df[price]pd.to_numeric(df[price],errorscoerce)# errorscoerce遇到不能转的变成 NaN# 清洗库存df[stock]pd.to_numeric(df[stock],errorscoerce)print(df.dtypes)# 确认类型已经转成数字2. 处理空值# 查看哪些列有空值print(df.isnull().sum())# 删除空值过多的行dfdf.dropna(subset[title])# 标题为空就删掉# 填充数值列的空值df[price]df[price].fillna(0)df[stock]df[stock].fillna(0)# 或者用均值填充df[price]df[price].fillna(df[price].mean())# 填充字符串列df[brand]df[brand].fillna(未知)3. 去重# 查看重复行数print(df.duplicated().sum())# 删除完全重复的行dfdf.drop_duplicates()# 指定列去重保留第一次出现的dfdf.drop_duplicates(subset[title])# 查看某列重复值print(df[title].value_counts())# 过滤异常数据dfdf[df[price]0]# 价格必须大于0dfdf[df[stock]0]# 库存不能是负数4. 常用数据转换# 类型转换df[price]df[price].astype(float)df[stock]df[stock].astype(int)# 处理时间df[crawl_time]pd.to_datetime(df[crawl_time])# 提取字段中的信息df[city]df[address].str.extract(r(北京|上海|广州|深圳|郑州))# 统一文本格式如品牌名统一小写df[brand]df[brand].str.lower().str.strip()三、存储到 MySQL1. pandas 直接写入最简单fromsqlalchemyimportcreate_engineimportpandasaspd# 连接 MySQLenginecreate_engine(mysqlpymysql://root:123456localhost:3306/spider_db?charsetutf8mb4)# DataFrame 直接写入 MySQL 表# 如果表已存在replace 替换append 追加df.to_sql(nameproducts,# 表名conengine,if_existsappend,# 追加模式indexFalse,# 不保存 DataFrame 的索引chunksize1000,# 分批写入每批1000条)print(数据已写入 MySQL)2. 逐条写入适合自定义处理importpymysql connpymysql.connect(hostlocalhost,port3306,userroot,password123456,databasespider_db,charsetutf8mb4,)cursorconn.cursor()# 批量插入sqlINSERT INTO products (title, price, brand, stock, crawl_time) VALUES (%s, %s, %s, %s, %s)data_list[(iPhone 15,6999,Apple,100,2026-06-26),(华为 Mate 60,5999,华为,50,2026-06-26),]cursor.executemany(sql,data_list)conn.commit()print(f插入了{cursor.rowcount}条数据)cursor.close()conn.close()3. 更新 vs 插入去重逻辑重复爬取时同一件商品可能出现两次。处理方式# 方案一INSERT IGNORE主键或唯一索引冲突时跳过sqlINSERT IGNORE INTO products (id, title, price) VALUES (%s, %s, %s)# 方案二REPLACE INTO冲突时替换sqlREPLACE INTO products (id, title, price) VALUES (%s, %s, %s)# 方案三ON DUPLICATE KEY UPDATE冲突时更新指定字段sqlINSERT INTO products (id, title, price, crawl_time) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE price VALUES(price), crawl_time VALUES(crawl_time)推荐方案三既保留旧数据又更新最新价格和爬取时间。四、存储到 MongoDBMongoDB 适合结构不固定的爬虫数据——不同商品字段可能不一样手机有像素冰箱有容积用 MongoDB 不用提前建表。1. 写入frompymongoimportMongoClient# 连接 MongoDBclientMongoClient(localhost,27017)dbclient[spider_db]collectiondb[products]# 插入一条collection.insert_one({title:iPhone 15,price:6999,brand:Apple,crawl_time:2026-06-26,})# 批量插入直接传 DataFramecollection.insert_many(df.to_dict(records))print(f插入了{len(df)}条)2. 去重更新# 以 title 为唯一标识有则更新无则插入for_,rowindf.iterrows():collection.update_one({title:row[title]},# 查询条件{$set:row.to_dict()},# 更新内容upsertTrue,# 不存在就插入)3. 查询# 价格大于5000的商品forproductincollection.find({price:{$gt:5000}}):print(product[title],product[price])# 按品牌统计数量pipeline[{$group:{_id:$brand,count:{$sum:1}}},{$sort:{count:-1}},]forresultincollection.aggregate(pipeline):print(result[_id],result[count])五、MySQL vs MongoDB 怎么选MySQLMongoDB数据格式需要提前建表字段固定JSON 格式字段灵活爬虫场景同一种商品字段稳定不同来源字段不一致查询适合关联查询、统计适合存和查不适合复杂关联上手需要建表写 SQL直接 insert零门槛实际建议爬电商商品字段固定→MySQL爬多种网站数据格式不统一 →MongoDB小数据量几千条→JSON 文件就够了六、完整流水线示例importpandasaspdfromsqlalchemyimportcreate_engineimportrequestsfrombs4importBeautifulSoupimporttimedefcrawl_products():爬虫 → 清洗 → 存储 一条龙# 1. 爬取all_data[]forpageinrange(1,6):resprequests.get(fhttps://example.com/products?page{page})soupBeautifulSoup(resp.text,html.parser)foriteminsoup.select(.product):all_data.append({title:item.select_one(.title).text,price:item.select_one(.price).text,brand:item.select_one(.brand).text,stock:item.select_one(.stock).text,})time.sleep(1)print(f爬取完成共{len(all_data)}条原始数据)# 2. 清洗dfpd.DataFrame(all_data)df[title]df[title].str.strip()df[price]df[price].str.replace(r[¥$,],,regexTrue)df[price]pd.to_numeric(df[price],errorscoerce)df[stock]pd.to_numeric(df[stock],errorscoerce)dfdf.dropna(subset[title])dfdf.drop_duplicates(subset[title])dfdf[df[price]0]df[crawl_time]pd.Timestamp.now()print(f清洗后剩余{len(df)}条有效数据)# 3. 存储enginecreate_engine(mysqlpymysql://root:123456localhost:3306/spider_db?charsetutf8mb4)df.to_sql(products,conengine,if_existsappend,indexFalse)print(数据已保存到 MySQL)returndfif__name____main__:crawl_products()总结爬虫的核心公式爬下来 → 清洗去空格/去重/类型转换/去异常 → 存储MySQL/MongoDB/文件 ↑ ↑ 最耗时的环节 按场景选很多人把精力都放在爬取上结果数据存进去一堆脏数据后面分析根本没法用。洗数据花的功夫往往比写爬虫还多但这步做好了后面的分析才会顺利。 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/10/23 14:14:50

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/10/23 14:14:34

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/10/23 14:11:44

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/10/24 4:32:58

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/10/23 14:10:55

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/10/23 14:14:34

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉