1. 项目背景与目标
伯克利新闻网站(Berkeley News)是加州大学伯克利分校的官方新闻发布平台,包含大量高质量的学术新闻、研究成果和校园动态。对于新闻传播学研究者、教育从业者或数据分析爱好者而言,定期获取这些内容具有重要价值。
这个爬虫项目的主要目标是:
- 自动化采集伯克利新闻网站的文章数据
- 提取关键信息(标题、发布时间、作者、正文内容等)
- 将数据结构化存储为可分析的格式
- 应对新闻网站常见的反爬机制
提示:新闻类网站通常更新频繁但结构稳定,是理想的爬虫练习对象。但需特别注意遵守robots.txt规则,控制请求频率。
2. 技术选型与准备
2.1 Python爬虫工具链
对于初级爬虫项目,推荐以下Python库组合:
python复制import requests # 网络请求
from bs4 import BeautifulSoup # HTML解析
import pandas as pd # 数据存储
import time # 请求间隔控制
选型理由:
requests比原生urllib更友好,支持会话保持BeautifulSoup的API直观,适合处理新闻类网站的规整HTMLpandas可轻松将数据导出为CSV/Excel- 避免使用Scrapy等框架,保持项目轻量
2.2 目标网站分析
访问伯克利新闻首页(https://news.berkeley.edu),通过浏览器开发者工具(F12)观察:
- 文章列表页URL模式:
/page/[页码]/ - 单篇文章包含的元数据:
- 标题:
<h1 class="entry-title"> - 发布时间:
<time class="entry-date"> - 作者:
<span class="author vcard"> - 正文:
<div class="entry-content">
- 标题:
注意:实际编码前应检查网站的robots.txt文件。伯克利新闻的robots.txt允许爬取新闻页面,但禁止爬取/admin/等后台路径。
3. 爬虫实现详解
3.1 基础爬取流程
python复制def fetch_article(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # 检查HTTP错误
return BeautifulSoup(response.text, 'html.parser')
except requests.exceptions.RequestException as e:
print(f"Error fetching {url}: {e}")
return None
关键点说明:
- 设置User-Agent模拟浏览器访问
- 异常处理避免单次失败导致程序中断
raise_for_status()捕获404/500等状态码
3.2 数据解析实现
python复制def parse_article(soup):
article_data = {
'title': soup.find('h1', class_='entry-title').get_text(strip=True),
'date': soup.find('time', class_='entry-date')['datetime'],
'author': soup.find('span', class_='author').get_text(strip=True),
'content': '\n'.join([p.get_text() for p in
soup.find('div', class_='entry-content').find_all('p')])
}
return article_data
常见问题处理:
- 使用
get_text(strip=True)去除多余空白字符 - 部分文章可能没有作者信息,需添加
if判断 - 正文中的图片可通过查找
<img>标签额外处理
3.3 分页爬取策略
python复制def crawl_berkeley_news(max_pages=5):
base_url = "https://news.berkeley.edu/page/{}/"
all_articles = []
for page in range(1, max_pages + 1):
print(f"Processing page {page}...")
soup = fetch_article(base_url.format(page))
if not soup:
continue
article_links = [a['href'] for a in
soup.select('h3.entry-title a')]
for link in article_links:
article_soup = fetch_article(link)
if article_soup:
all_articles.append(parse_article(article_soup))
time.sleep(2) # 礼貌性延迟
return pd.DataFrame(all_articles)
重要:设置
time.sleep(2)避免触发反爬机制。新闻类网站建议请求间隔≥2秒。
4. 数据存储与增强
4.1 结构化存储
将爬取结果保存为CSV:
python复制df = crawl_berkeley_news()
df.to_csv('berkeley_news.csv', index=False, encoding='utf-8-sig')
进阶存储方案:
- 使用SQLite实现增量爬取(记录已爬URL)
- 添加MD5校验防止重复内容
- 将正文中的关键词自动提取为标签
4.2 处理特殊内容
当遇到正文中的图片文字时:
python复制# 提取所有图片的alt文本
images = soup.find('div', class_='entry-content').find_all('img')
image_texts = [img.get('alt', '') for img in images if img.get('alt')]
对于动态加载的内容:
- 使用Selenium模拟浏览器(会增加复杂度)
- 分析XHR请求接口(推荐方式)
5. 反爬应对策略
5.1 常见反爬现象
- 403 Forbidden错误
- 验证码要求
- 返回假数据
- 请求频率限制
5.2 解决方案实践
方案1:请求头优化
python复制headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Accept-Language': 'en-US,en;q=0.9',
'Referer': 'https://news.berkeley.edu/'
}
方案2:IP轮换(需谨慎)
python复制proxies = {
'http': 'http://user:pass@proxy_ip:port',
'https': 'http://user:pass@proxy_ip:port'
}
response = requests.get(url, headers=headers, proxies=proxies)
法律提示:商业用途的爬虫必须遵守网站服务条款。教育项目建议控制在合理访问频率内。
6. 项目扩展方向
6.1 数据分析应用
- 使用NLTK分析新闻情感倾向
- 统计高频关键词生成词云
- 按作者/时间段分析发文规律
6.2 系统化改进
- 添加日志记录(logging模块)
- 实现断点续爬功能
- 构建自动化邮件报告
我在实际爬取中发现,伯克利新闻网站的移动端页面(m.berkeley.edu)有时返回更简洁的HTML结构,适合作为备用爬取方案。另外,他们的新闻API端点(https://news-api.berkeley.edu)对部分内容提供JSON格式数据,这比解析HTML更可靠——但需要申请访问权限。
