1. 项目概述Python爬取课程信息实战最近在整理在线教育平台的课程资源时手动复制粘贴效率实在太低。作为Python开发者自然想到用爬虫技术自动化这个流程。这个项目核心是通过Python实现课程信息的结构化采集适用于各类在线学习平台的数据抓取需求。课程信息通常包含课程名称、讲师、评分、价格、学习人数等关键字段这些数据对于竞品分析、市场调研或个性化推荐都很有价值。不同于简单的网页抓取课程信息往往涉及动态加载、登录验证等复杂场景这正是本项目的技术挑战所在。2. 技术选型与工具准备2.1 核心库的选择Requests和BeautifulSoup是基础组合但现代网站越来越多地采用动态加载# 基础爬虫三件套 import requests from bs4 import BeautifulSoup import re对于动态内容Selenium或Playwright更合适# 动态渲染方案 from selenium import webdriver from selenium.webdriver.common.by import By2.2 开发环境配置推荐使用虚拟环境隔离依赖python -m venv course_spider source course_spider/bin/activate # Linux/Mac course_spider\Scripts\activate # Windows pip install requests beautifulsoup4 selenium注意Chromedriver版本需与本地Chrome浏览器匹配否则Selenium会报错3. 网页结构分析与爬取策略3.1 静态页面抓取流程基础爬虫四步法发送HTTP请求获取页面解析HTML提取目标元素数据清洗与格式化持久化存储示例代码框架def scrape_course_info(url): headers {User-Agent: Mozilla/5.0} response requests.get(url, headersheaders) soup BeautifulSoup(response.text, html.parser) courses [] for item in soup.select(.course-card): title item.select_one(.title).text.strip() instructor item.select_one(.instructor).text courses.append({title: title, instructor: instructor}) return courses3.2 动态内容处理技巧当遇到滚动加载时Selenium的自动滚动方案driver webdriver.Chrome() driver.get(url) last_height driver.execute_script(return document.body.scrollHeight) while True: driver.execute_script(window.scrollTo(0, document.body.scrollHeight);) time.sleep(2) new_height driver.execute_script(return document.body.scrollHeight) if new_height last_height: break last_height new_height4. 反爬机制应对方案4.1 常见反爬措施User-Agent检测请求频率限制验证码拦截IP封禁4.2 应对策略实现随机请求头配置示例user_agents [ Mozilla/5.0 (Windows NT 10.0; Win64; x64), Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ] headers { User-Agent: random.choice(user_agents), Accept-Language: en-US,en;q0.9, Referer: https://www.google.com/ }代理IP轮询方案proxies { http: http://proxy1.example.com:8080, https: http://proxy2.example.com:8080 } response requests.get(url, headersheaders, proxiesproxies)5. 数据存储与结构化处理5.1 存储格式选择CSV适合基础需求import csv with open(courses.csv, w, newline, encodingutf-8) as f: writer csv.DictWriter(f, fieldnames[title, instructor, price]) writer.writeheader() writer.writerows(course_data)MongoDB适合非结构化数据from pymongo import MongoClient client MongoClient(mongodb://localhost:27017/) db client[course_db] collection db[courses] collection.insert_many(course_data)5.2 数据清洗技巧处理价格信息的正则表达式def clean_price(price_str): # 匹配 ¥199.00 或 $199 等形式 match re.search(r[\¥\$]?(\d\.?\d*), price_str) return float(match.group(1)) if match else 0.06. 项目优化与扩展6.1 性能优化方案异步爬虫实现aiohttp示例import aiohttp import asyncio async def fetch(session, url): async with session.get(url) as response: return await response.text() async def main(urls): async with aiohttp.ClientSession() as session: tasks [fetch(session, url) for url in urls] return await asyncio.gather(*tasks)6.2 扩展应用场景定时爬取实现import schedule import time def job(): print(开始执行定时爬取...) # 爬取逻辑 schedule.every().day.at(10:30).do(job) while True: schedule.run_pending() time.sleep(60)7. 常见问题排查指南7.1 典型错误处理SSL证书错误解决方案import ssl ssl._create_default_https_context ssl._create_unverified_context元素定位失败处理try: element driver.find_element(By.CSS_SELECTOR, .price) except NoSuchElementException: element None7.2 调试技巧启用Selenium日志from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options chrome_options Options() chrome_options.add_argument(--headless) chrome_options.add_argument(--log-levelDEBUG) service Service(log_pathchromedriver.log)8. 法律与道德注意事项8.1 robots.txt检查自动解析robots.txtfrom urllib.robotparser import RobotFileParser rp RobotFileParser() rp.set_url(https://example.com/robots.txt) rp.read() can_fetch rp.can_fetch(*, /courses)8.2 合规爬取建议控制请求频率建议≥3秒/次仅爬取公开数据设置合理的爬取时间窗口避免对服务器造成负担我在实际项目中发现早上8-10点爬取教育类网站成功率最高这个时段服务器负载较低且内容已更新完毕。对于需要登录的课程平台建议使用官方API替代爬虫很多平台其实提供了开发者接口。