
1. 项目背景与目标最近在技术社区看到不少朋友对网络爬虫感兴趣但苦于找不到合适的入门项目。今天我就以麻省理工学院MIT新闻网站为例带大家完成一个完整的初级爬虫实战。这个项目特别适合刚接触Python爬虫的开发者既能学习基础技术又能获取高质量的科技新闻内容。选择MIT新闻作为目标网站有几个优势首先它的页面结构清晰规范适合新手练习其次内容更新频繁且质量高爬取结果有实际价值最重要的是该网站对教育用途的爬取相对友好当然我们还是会严格遵守robots.txt规则。2. 技术准备与环境搭建2.1 基础工具选择对于这个初级项目我们主要使用Python生态中的几个经典库Requests用于发送HTTP请求BeautifulSoup用于解析HTML文档Pandas用于数据存储和处理这些库的安装非常简单pip install requests beautifulsoup4 pandas2.2 目标网站分析在开始编码前我们需要先分析MIT新闻网站的结构。打开浏览器开发者工具F12观察几个关键点页面布局新闻列表通常位于特定CSS选择器下分页机制是传统的页码链接还是无限滚动数据加载是服务端渲染还是客户端动态加载经过分析MIT新闻采用传统的服务端渲染每页显示10篇文章通过明确的页码链接实现分页。3. 核心爬取逻辑实现3.1 基础爬取函数我们先编写一个基础函数来获取单个页面的内容import requests from bs4 import BeautifulSoup def fetch_page(page_num): url fhttps://news.mit.edu/topic/{page_num} headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) } try: response requests.get(url, headersheaders) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: print(fError fetching page {page_num}: {e}) return None3.2 内容解析逻辑获取到HTML后我们需要从中提取关键信息def parse_articles(html): soup BeautifulSoup(html, html.parser) articles [] for item in soup.select(.news-article): title item.select_one(h2 a).text.strip() link item.select_one(h2 a)[href] summary item.select_one(.summary).text.strip() date item.select_one(.date).text.strip() articles.append({ title: title, link: link, summary: summary, date: date }) return articles3.3 分页处理与数据存储为了爬取多页内容我们需要处理分页逻辑import pandas as pd def crawl_mit_news(max_pages5): all_articles [] for page in range(1, max_pages 1): print(fProcessing page {page}...) html fetch_page(page) if html: articles parse_articles(html) all_articles.extend(articles) df pd.DataFrame(all_articles) df.to_csv(mit_news.csv, indexFalse) return df4. 高级功能与优化4.1 请求速率控制为了避免给服务器造成负担我们应该控制请求频率import time def crawl_with_delay(max_pages5, delay2): all_articles [] for page in range(1, max_pages 1): time.sleep(delay) # 添加延迟 html fetch_page(page) if html: articles parse_articles(html) all_articles.extend(articles) return all_articles4.2 异常处理增强健壮的爬虫需要处理各种异常情况def robust_fetch(url, max_retries3): for attempt in range(max_retries): try: response requests.get(url, timeout10) response.raise_for_status() return response.text except Exception as e: print(fAttempt {attempt 1} failed: {e}) if attempt max_retries - 1: return None time.sleep(2 ** attempt) # 指数退避5. 数据存储与分析5.1 多种存储格式除了CSV我们还可以将数据保存为其他格式def save_data(articles, formatcsv): df pd.DataFrame(articles) if format csv: df.to_csv(mit_news.csv, indexFalse) elif format json: df.to_json(mit_news.json, orientrecords) elif format excel: df.to_excel(mit_news.xlsx, indexFalse)5.2 简单数据分析我们可以对爬取的数据进行初步分析def analyze_data(df): # 按日期统计文章数量 df[date] pd.to_datetime(df[date]) daily_counts df.groupby(df[date].dt.date).size() # 标题词频分析 from collections import Counter word_counts Counter( .join(df[title]).lower().split()) return { daily_counts: daily_counts, top_words: word_counts.most_common(10) }6. 反爬虫策略应对6.1 请求头优化设置合理的请求头可以降低被屏蔽的概率headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Accept: text/html,application/xhtmlxml, Accept-Language: en-US,en;q0.5, Referer: https://news.mit.edu/, DNT: 1 }6.2 IP轮换策略对于大规模爬取可以考虑使用代理IPproxies { http: http://your_proxy:port, https: http://your_proxy:port } response requests.get(url, headersheaders, proxiesproxies)7. 项目扩展方向7.1 定时自动爬取使用计划任务实现每日自动更新import schedule import time def daily_job(): crawl_mit_news(max_pages3) schedule.every().day.at(08:00).do(daily_job) while True: schedule.run_pending() time.sleep(60)7.2 构建新闻推荐系统基于爬取的数据构建简单的推荐系统from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity def build_recommender(articles): tfidf TfidfVectorizer(stop_wordsenglish) tfidf_matrix tfidf.fit_transform([a[title] a[summary] for a in articles]) return cosine_similarity(tfidf_matrix)8. 法律与道德注意事项在开发爬虫时必须注意以下几点遵守robots.txt规则控制请求频率避免影响网站正常运行仅用于个人学习目的不爬取敏感或个人隐私信息考虑设置明显的用户代理标识可以通过以下方式检查robots.txtrobots_url https://news.mit.edu/robots.txt print(requests.get(robots_url).text)9. 常见问题解决9.1 页面结构变化应对网站改版是爬虫常见问题解决方法包括使用更宽松的CSS选择器添加多种解析策略建立监控机制及时发现变化9.2 数据清洗技巧爬取的数据往往需要清洗def clean_text(text): text text.replace(\n, ).replace(\r, ) text .join(text.split()) # 去除多余空格 return text.strip()10. 项目总结与进阶建议这个MIT新闻爬虫项目涵盖了从基础到进阶的多个爬虫技术点。在实际操作中我发现以下几点特别重要先人工分析网站结构再编码逐步构建功能不要一次性写太多代码添加充分的日志记录考虑使用Scrapy框架进行更复杂的爬取任务对于想进一步学习的朋友建议尝试爬取动态加载的内容如使用Selenium研究如何绕过更复杂的反爬机制学习将爬虫部署到云服务器探索数据可视化分析结果