当前位置: 首页 > news >正文

Python多线程实战:爬取乌鲁木齐某菜市场价格数据

一、项目前言

日常做农贸数据分析、生鲜行情调研时,菜市场实时报价是核心数据源。本文以乌鲁木齐某菜市场网页价格数据为爬取目标,采用 requests 做网络请求、 lxml 解析网页、 ThreadPoolExecutor 线程池实现并发提速,把全品类菜价结构化存入CSV文件,完整实现从网页抓取→数据清洗→本地存储全流程。

技术栈:Python3 + requests + lxml + 内置线程池 + CSV存储

二、页面分析

1. 爬取目标

该菜市场分页菜价列表,页面规律:URL通过页码参数翻页,每页为表格布局,表格每行 <tr> 对应一种菜品, <td> 单元格包含:品类、品名、规格、均价、产地、报价日期等字段。

2. 页面难点

表格单元格内部分文字嵌套 <em> 标签,直接 td.text 会丢失em标签内内容;解决方案:XPath语法 string(.) 提取单个 <td> 下所有嵌套标签合并后的完整文本,是本项目关键数据清洗技巧。

3. 并发选型

数据页数多达数百页,单线程循环爬取效率极低,使用 ThreadPoolExecutor 线程池,设置固定并发数批量提交任务,成倍缩短采集耗时。

三、爬虫源码

import requests from lxml import etree from concurrent.futures import ThreadPoolExecutor HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } def download(url): resp = requests.get(url, headers=HEADERS, timeout=10) resp.encoding = "utf-8" tree = etree.HTML(resp.text) trs = tree.xpath("//div[@class='bjbiao']/table/tr[position()>1]") lines = [] for tr in trs: # 关键修复:用 string(.) 取整个td的文本,合并 <em> 里的内容 tds = tr.xpath("./td") row = [] for td in tds: text = td.xpath("string(.)").strip() # 把 <td> 里所有文本合并成一个 row.append(text) lines.append(",".join(row)) with open("北园春蔬菜价格1.csv", "a", encoding="utf-8-sig") as f: f.write("\n".join(lines) + "\n") print("完成:", url) if __name__ == "__main__": # 表头初始化 with open("北园春蔬菜价格.csv", "w", encoding="utf-8-sig") as f: f.write("品种,最高价,最低价,中间价,分类,产地,市场,报价日期\n") base = "http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page={}" with ThreadPoolExecutor(max_workers=15) as exe: for page in range(1, 3974): url = base.format(page) exe.submit(download, url)

运行结果:

完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=4 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=5 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=1 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=11 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=6 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=12 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=2 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=3 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=9 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=7 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=13 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=10 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=15 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=16 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=8 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=14 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=17 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=19 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=18 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=20 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=21 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=24 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=27 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=29 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=23 ... 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=3973 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=3972 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=3969 完成: http://www.beiyuanchun.com/jiagexingqing/?&chandi=%E4%B9%8C%E9%B2%81%E6%9C%A8%E9%BD%90&pz=&rqstart=&rqend=&fl=%E8%94%AC%E8%8F%9C&sc=&page=3971

四、代码逐模块讲解

1. 依赖与请求头配置

requests :负责HTTP网络请求,模拟浏览器访问页面;
lxml.etree :高性能HTML/XML解析器,配合XPath精准定位页面元素;
ThreadPoolExecutor :Python内置线程池,不用手动创建销毁线程,自动管理并发队列;
HEADERS :UA伪装,解决服务器拦截Python默认爬虫标识的问题。

2. download()核心爬取函数

1. 请求页面:设置超时10秒,防止页面卡死阻塞爬虫;指定 utf-8 编码,解决中文乱码;
2. XPath定位表格: //div[@class="bjbiao"]/table/tr[position()>1] , position()>1 跳过表格表头行,只取数据行;
3. 关键数据提取:string(.)
常规 td.text 只能获取标签直接文本,若 <td>大白菜<em>精品</em></td> , .text 只会拿到 大白菜 ;
td.xpath("string(.)") 会递归提取td下所有子节点文本,结果为 大白菜精品 ,完美适配页面嵌套标签场景;
4. 异常捕获:单页爬取报错不中断整体程序,打印失败链接方便后续补爬。

3. 主线程:表头初始化和线程池调度

1. CSV预处理:使用 utf-8-sig 编码,Excel打开CSV不会出现中文乱码;程序启动先写入字段表头;
2. 线程池批量提交任务:循环拼接每一页URL, exe.submit(download, url) 异步分发爬取任务, max_workers=15 控制并发数,防止并发过高被网站封IP;
3. 收尾落地数据:所有页面爬取完成后,一次性把全部数据写入CSV,减少频繁IO操作、提升文件写入效率。

五、爬虫运行效果

1. 控制台输出:运行后控制台逐行打印页面URL;
2. 文件产出:项目目录生成 北园春菜市场菜价.csv ,可用Excel/WPS直接打开,字段规整:品类、菜名、单价、产地、日期一一对应;
3. 效率对比:397页数据,单线程需要数分钟,15并发线程池几十秒即可完成全量采集。

六、拓展方案

1. 反爬优化
增加随机请求间隔: import time + random.sleep(random.uniform(0.1,0.5)) ,在请求前随机休眠,降低访问频率;
代理IP:高频爬取触发封禁时,接入代理池轮换IP;
补充Cookie:部分页面需要Cookie鉴权,在HEADERS中追加Cookie字段。
2. 数据存储拓展
存入数据库:把 all_data 数据解析后,使用 pymysql 存入MySQL,方便后续SQL筛选、价格统计;
Pandas处理:爬完后用 pandas.read_csv() 读取CSV,做均价排序、月度价格走势可视化。

fail_urls = [] # 全局存失败链接 # download异常分支:fail_urls.append(url) # 爬完后二次循环重试失败链接

七、合规与提醒

1. 爬虫合规:本项目仅用于个人学习数据分析,禁止商用批量爬取网站数据;爬取前遵守目标网站 robots.txt 协议,控制并发和爬速,避免对目标服务器造成压力;
2. 网站变动兼容:若后续网站改版(class名称、页面结构变更),只需修改XPath表达式和基础URL即可适配。

八、总结

本案例是表格类网页爬虫标准实战模板,吃透3个核心知识点:

1. XPath string(.) 提取含嵌套标签的单元格文本;
2. ThreadPoolExecutor线程池并发爬虫的工程写法;
3. CSV utf-8-sig 编码解决Excel中文乱码。

http://www.jsqmd.com/news/957153/

相关文章:

  • 终极WindowResizer使用指南:如何轻松强制调整任意Windows窗口大小
  • Galactic Geochelone:用陆龟隐喻重构分布式系统韧性设计
  • 5步终极指南:用Gaggiuino微控制器改造你的Gaggia Classic咖啡机
  • 全链路异步解析架构:BilibiliDown高性能视频下载引擎技术突破
  • 用数据说话!2026年好用AI论文工具榜单,免费款也能高效产初稿
  • 择优择校指南:江西师资雄厚民办高职盘点,优质院校实力一览 - 品牌测评鉴赏家
  • 从实验数据到报告:如何用RData文件串联你的完整分析流程?
  • TeXstudio 3.0+ 暗色主题进阶玩法:导入配置文件,一键同步所有编辑器设置
  • RimWorld性能优化终极方案:Performance-Fish深度解析与实战指南
  • 体育为何是机器人能力的终极考场?
  • Proteus自定义元件库开发实战:从零构建TG19264A液晶仿真模型
  • 别再纠结了!5分钟搞懂LDO和DC-DC到底怎么选(附实际电路对比图)
  • 【独家首发】Sora 2比特率-感知质量帕累托前沿图谱(基于LLaVA-Video-QA基准的127组AB测试数据)
  • MATLAB版带时间窗VRP遗传算法求解工具包,含完整函数与实测数据
  • Postman里Body的四种传参方式,到底该怎么选?一次讲清form-data、x-www-form-urlencoded、raw和binary
  • 用Matlab手把手复现MRI并行成像SENSE算法:从k空间欠采样到图像重建全流程
  • 2026 合肥蜀山闲置名包回收权威测评榜|实体店实测:合扬断层夺魁 - 开心测评
  • Unity游戏本地化困境与XUnity.AutoTranslator的智能化解决方案
  • 编写程序根据出差奔波时长,住宿环境,综合评估旅途疲劳值,推荐快速恢复方案。
  • 3大突破:从技术债到性能飞跃的架构重构之旅
  • 文心大模型5.0正式版:从技术参数到服务契约的范式跃迁
  • 3大模块免费打造你的专属Windows系统:Winhance中文版完全指南
  • 2026年电采暖选购指南:河北贺达新能源如何定义采暖新标准 - 企业名录精选推荐
  • pyLDAvis 3.3.1 交互式LDA主题探索工具:含多数据集Notebook与本地部署支持
  • Windows 11优化神器:Win11Debloat让你的电脑速度提升51%的秘诀
  • 抖音视频无水印下载完整指南:免费高效获取高清素材的终极方案
  • 如何用F3D颠覆你的3D可视化工作流:一个极速渲染引擎的终极指南
  • 2026年超声波明渠流量计十大国产品牌排行榜:专业测评与选型全攻略 - 液体流量液位品牌推荐
  • ORBSLAM3 VIO精度评估实战:用KITTI数据集和evo工具,从轨迹对齐到APE/RPE分析全流程
  • 星恒讯工业广域网路由器性能揭秘