尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python爬虫实战:博物馆展览数据抓取与处理
1. 项目概述最近在帮朋友做一个博物馆展览信息聚合的小工具需要从各大博物馆官网抓取展览预告和正在热展栏目的数据。这个需求看似简单但实际开发中遇到了不少坑特别是不同博物馆网站结构差异大、反爬机制各异的问题。下面分享我的完整实现方案包含从页面分析到数据存储的全流程。2. 技术选型与准备工作2.1 基础工具链选择Python作为开发语言主要依赖以下库requests/urllib3基础网络请求BeautifulSoup4HTML解析selenium应对动态渲染页面pandas数据清洗与CSV导出fake-useragent伪装浏览器头import requests from bs4 import BeautifulSoup from selenium import webdriver import pandas as pd from fake_useragent import UserAgent2.2 目标网站分析以中国国家博物馆为例其展览页面有如下特点主展信息通过API异步加载展期格式不统一2024.3.1-2024.6.30 vs 2024年3月1日至6月30日票务信息分散在多个div中有基础的频率限制同一IP短时间内多次访问会被暂时屏蔽3. 核心爬取逻辑实现3.1 页面请求与反反爬策略针对不同博物馆采用不同的请求策略def get_page(url): headers { User-Agent: UserAgent().random, Accept-Language: zh-CN,zh;q0.9 } try: # 静态页面直接请求 if static in url: resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() return resp.text # 动态页面使用selenium else: options webdriver.ChromeOptions() options.add_argument(fuser-agent{UserAgent().random}) driver webdriver.Chrome(optionsoptions) driver.get(url) WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, exhibition-item)) ) html driver.page_source driver.quit() return html except Exception as e: print(f请求失败: {str(e)}) return None3.2 数据解析关键技巧展览信息的解析需要处理多种特殊情况def parse_exhibition(html): soup BeautifulSoup(html, html.parser) exhibitions [] for item in soup.select(.exhibition-item): try: # 处理展期格式 period item.select_one(.period).text start_date, end_date normalize_date(period) # 提取展厅位置可能多层嵌套 location item.select_one(.location) if not location: location item.find(stringre.compile(展厅|展馆)) exhibitions.append({ name: item.select_one(.title).text.strip(), start_date: start_date, end_date: end_date, location: location.text.strip() if location else 待确认, ticket: parse_ticket_info(item), source_url: item.select_one(a)[href] }) except Exception as e: print(f解析异常: {str(e)}) continue return exhibitions def normalize_date(date_str): 统一处理各种日期格式 # 实现细节省略... return start_date, end_date4. 数据存储与导出4.1 CSV导出最佳实践使用pandas进行数据清洗和导出避免常见的编码和格式问题def save_to_csv(data, filename): df pd.DataFrame(data) # 处理可能的NaN值 df.fillna(, inplaceTrue) # 确保日期列格式统一 date_cols [start_date, end_date] for col in date_cols: if col in df.columns: df[col] pd.to_datetime(df[col], errorscoerce).dt.strftime(%Y-%m-%d) # 写入CSV注意编码和换行符处理 df.to_csv(filename, indexFalse, encodingutf-8-sig, line_terminator\n) print(f成功导出{len(df)}条数据到{filename})4.2 增量更新策略为避免重复爬取实现增量更新逻辑def update_existing_data(new_data, csv_path): try: # 读取已有数据 existing pd.read_csv(csv_path, encodingutf-8-sig) # 合并新旧数据基于展览名称和日期去重 combined pd.concat([existing, new_data]) combined.drop_duplicates( subset[name, start_date], keeplast, inplaceTrue ) return combined except FileNotFoundError: return new_data5. 实战经验与避坑指南5.1 高频问题解决方案反爬突破随机化请求间隔0.5-3秒使用代理IP池建议免费IP付费IP混合使用模拟鼠标移动等用户行为针对行为检测数据解析难点使用try-except包裹每个字段提取逻辑准备多种XPath/CSS选择器备用方案对日期等关键字段实现多种格式解析器性能优化对静态页面启用缓存requests-cache使用连接池requests.Session异步请求aiohttpasyncio5.2 法律与道德注意事项严格遵守robots.txt规则控制请求频率单目标1请求/秒不在商业用途中使用爬取数据设置明显的User-Agent标识6. 完整示例代码import re import time import random import pandas as pd from datetime import datetime from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class MuseumSpider: def __init__(self): self.session requests.Session() self.session.headers.update({ User-Agent: MuseumResearchBot/1.0 (https://example.com/bot-info) }) def crawl_museum(self, museum_url): 主爬取流程 print(f开始爬取 {museum_url}) # 1. 获取页面 html self.get_page(museum_url) if not html: return [] # 2. 解析数据 exhibitions self.parse_exhibitions(html) # 3. 清洗数据 cleaned self.clean_data(exhibitions) return cleaned # 其他方法实现... if __name__ __main__: spider MuseumSpider() data spider.crawl_museum(https://www.chnmuseum.cn/zpzl/) save_to_csv(data, museum_exhibitions.csv)这个项目虽然不算复杂但涉及到的技术点很全面。在实际开发中最大的挑战不是技术实现而是如何平衡爬取效率和目标网站的正常运行。建议大家在开发类似项目时一定要做好频率控制并尽量在非高峰时段运行爬虫。
RELATED

相关推荐

200元搭一套农田监测:ESP32土壤温湿度采集、WiFi上云与报警完整指南

200元搭一套农田监测:ESP32土壤温湿度采集、WiFi上云与报警完整指南

200元搭一套农田监测:ESP32土壤温湿度采集、WiFi上云与报警完整指南 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 凌晨五点,番茄大棚里还是黑灯瞎…

📅 2026/9/12 8:57:57
Biotin-SS-TCO在ADC技术中的革新应用与操作指南

Biotin-SS-TCO在ADC技术中的革新应用与操作指南

1. 项目概述:Biotin-SS-TCO在ADC技术中的革新应用Biotin-SS-TCO(生物素-SS-(4E)-反式环辛烯)是一种具有独特分子结构的双功能连接子,在抗体-药物偶联物(ADC)领域展现出突破性的应用价值。这个看似复杂的化学…

📅 2026/9/12 8:57:57
Envoy Reverse Tunnel 握手段错误修复:HTTP/1 dispatch 期间禁止关闭连接的工程实践

Envoy Reverse Tunnel 握手段错误修复:HTTP/1 dispatch 期间禁止关闭连接的工程实践

Envoy Reverse Tunnel 握手段错误修复:HTTP/1 dispatch 期间禁止关闭连接的工程实践 【免费下载链接】envoy Cloud-native high-performance edge/middle/service proxy 项目地址: https://gitcode.com/GitHub_Trending/en/envoy 本篇技术指南聚焦 Envoy 反向…

📅 2026/9/12 8:57:57
MORE NEWS

更多资讯

📰

GB/T 15532-2008 软件测试规范解读:从测试过程到文档落地的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Python编程入门:从Hello World到绘制动态心形代码

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

2026 年国产大模型怎么选?调用量、定价、上下文三条线对照

大模型选型是指在给定的任务类型、预算约束与部署条件下,从多个候选模型中确定主用模型、备用模型与降级路由的过程。墨衍 MoGrow 是面向开发者与企业的一站式 AI 数字营销平台,提供 AI 选题创作、多平台一键分发与 SEO & GEO 双端优化,其…

📰

Lucide 图标描边宽度定制指南:Astro 中 strokeWidth 与 nonScalingStroke 实战解析

Lucide 图标描边宽度定制指南:Astro 中 strokeWidth 与 nonScalingStroke 实战解析 【免费下载链接】lucide Beautiful & consistent icon toolkit made by the community. Open-source project and a fork of Feather Icons. 项目地址: https://gitcode.com/…

📰

KC901S便携式矢量网络分析仪深度解析

1. 这台KC901S到底是什么,能干啥,谁该认真看看它矢量网络分析仪、KC901S、矢量网络分析仪的使用——这三个词最近在射频工程师、天线调试员、微波实验室学生和业余无线电爱好者圈子里反复刷屏。不是因为某家大厂出了旗舰新品,而是因为KC901S这…

📰

密码学与编码技术:从基础概念到安全实践

1. 密码与编码基础概念解析密码学和编码技术是现代信息安全的两大基石。作为从业十余年的安全工程师,我经常被问到这两者的区别与联系。简单来说,编码(Encoding)是将信息从一种形式转换为另一种形式的过程,目的是确保数…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬