使用 Python 构建一个简易的 Web 爬虫
在当今互联网时代,数据是企业和开发者的重要资源。获取网络上的公开数据可以帮助我们进行市场分析、趋势预测、学术研究等。Web 爬虫(Web Scraper)是一种自动抓取网页内容的程序,广泛用于从网站中提取结构化数据。
本文将介绍如何使用 Python 编写一个简易但功能完整的 Web 爬虫,涵盖基本的请求发送、HTML 解析、数据提取以及存储流程,并提供完整的代码示例。我们将以爬取豆瓣电影 Top 250 页面为例,演示整个过程。
准备工作
1. 安装依赖库
我们将使用以下 Python 库:
requests
:用于发送 HTTP 请求BeautifulSoup
:用于解析 HTML 内容csv
:用于将爬取的数据保存为 CSV 文件你可以通过 pip 安装这些库:
pip install requests beautifulsoup4
发送请求与获取页面内容
我们首先需要向目标网站发送 HTTP 请求并获取响应内容。这里我们以豆瓣电影 Top 250 页面为例:
URL: https://movie.douban.com/top250
以下是使用 requests
发送 GET 请求的基本代码:
import requestsurl = 'https://movie.douban.com/top250'headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0 Safari/537.36'}response = requests.get(url, headers=headers)if response.status_code == 200: print("成功获取页面") html_content = response.textelse: print(f"请求失败,状态码:{response.status_code}")
注意:很多网站会检测 User-Agent 来判断是否为爬虫,因此设置合理的 User-Agent 是非常必要的。
解析 HTML 并提取数据
接下来,我们需要从 HTML 中提取我们感兴趣的信息。豆瓣电影 Top 250 页面中包含电影名称、评分、年份、导演、简介等信息。
我们可以使用 BeautifulSoup
对 HTML 进行解析,并利用 CSS 选择器来定位元素。
示例:提取电影标题和评分
from bs4 import BeautifulSoupsoup = BeautifulSoup(html_content, 'html.parser')movies = []for item in soup.find_all('div', class_='item'): title = item.find('span', class_='title').get_text() rating = item.find('span', class_='rating_num').get_text() # 获取年份 year_info = item.find('div', class_='bd').find('p').get_text().strip() year = year_info.split('/')[-1].strip() # 提取年份部分 movies.append({ 'title': title, 'rating': rating, 'year': year })print(movies[:3]) # 打印前三个电影作为示例
输出结果类似如下格式:
[ {'title': '肖申克的救赎', 'rating': '9.7', 'year': '1994'}, {'title': '霸王别姬', 'rating': '9.6', 'year': '1993'}, ...]
分页爬取完整数据
豆瓣 Top 250 页面是分页显示的,每页显示 25 部电影,共 10 页。我们需要循环爬取所有页面。
base_url = 'https://movie.douban.com/top250?start='all_movies = []for page in range(0, 250, 25): # 每页25条,共10页 url = base_url + str(page) response = requests.get(url, headers=headers) if response.status_code != 200: print(f"第 {page//25 + 1} 页请求失败") continue soup = BeautifulSoup(response.text, 'html.parser') for item in soup.find_all('div', class_='item'): title = item.find('span', class_='title').get_text() rating = item.find('span', class_='rating_num').get_text() year_info = item.find('div', class_='bd').find('p').get_text().strip() year = year_info.split('/')[-1].strip() all_movies.append({ 'title': title, 'rating': rating, 'year': year })print(f"共爬取到 {len(all_movies)} 部电影")
数据存储:导出为 CSV 文件
为了便于后续分析或导入数据库,我们将爬取的数据保存为 CSV 格式。
import csvwith open('douban_top250.csv', mode='w', encoding='utf-8-sig', newline='') as file: writer = csv.DictWriter(file, fieldnames=['title', 'rating', 'year']) writer.writeheader() writer.writerows(all_movies)print("数据已成功保存至 douban_top250.csv")
使用
utf-8-sig
编码可以避免 Excel 打开 CSV 文件时出现乱码。
完整代码汇总
下面是整合以上各部分的完整代码:
import requestsfrom bs4 import BeautifulSoupimport csvheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0 Safari/537.36'}base_url = 'https://movie.douban.com/top250?start='all_movies = []for page in range(0, 250, 25): url = base_url + str(page) response = requests.get(url, headers=headers) if response.status_code != 200: print(f"第 {page//25 + 1} 页请求失败") continue soup = BeautifulSoup(response.text, 'html.parser') for item in soup.find_all('div', class_='item'): title = item.find('span', class_='title').get_text() rating = item.find('span', class_='rating_num').get_text() year_info = item.find('div', class_='bd').find('p').get_text().strip() year = year_info.split('/')[-1].strip() all_movies.append({ 'title': title, 'rating': rating, 'year': year })# 保存为 CSV 文件with open('douban_top250.csv', mode='w', encoding='utf-8-sig', newline='') as file: writer = csv.DictWriter(file, fieldnames=['title', 'rating', 'year']) writer.writeheader() writer.writerows(all_movies)print(f"共爬取到 {len(all_movies)} 部电影,已保存至 douban_top250.csv")
注意事项与法律风险提示
虽然本文展示的是技术实现,但在实际使用爬虫时,请务必注意以下几点:
遵守网站的 robots 协议:检查目标网站的/robots.txt
文件。设置合理请求频率:避免频繁请求导致服务器压力过大,建议添加 time.sleep()
延迟。尊重版权与隐私:不得爬取受保护的内容或用户隐私信息。考虑使用官方 API:如豆瓣、知乎等平台提供了开放 API,更推荐使用 API 接口获取数据。扩展方向
本项目只是一个简单的静态页面爬虫,如果你希望进一步提升技能,可以尝试以下方向:
使用Selenium
抓取动态加载网页(如 JavaScript 渲染的内容)将数据存入数据库(如 MySQL、MongoDB)添加异常处理机制(超时重试、代理 IP 等)构建图形界面(使用 Tkinter 或 PyQt)本文介绍了如何使用 Python 构建一个基础的 Web 爬虫,并完整实现了从请求、解析到数据存储的全过程。通过这个项目,你不仅可以掌握爬虫的基本原理,还能了解如何处理实际开发中的常见问题。
Web 爬虫是一个强大而灵活的工具,正确使用它可以极大地提高数据获取效率。希望你能以此为基础,继续探索自动化数据采集的世界!
📌 如有疑问或需要帮助调试代码,欢迎留言交流!