使用Python进行网络爬虫开发:从入门到实战
在大数据和人工智能时代,数据成为了最重要的资源之一。而网络爬虫(Web Crawler)作为获取互联网数据的重要手段,广泛应用于数据分析、市场研究、搜索引擎等领域。本文将介绍如何使用 Python 进行基础的网络爬虫开发,并通过一个实际案例演示如何抓取网页中的信息并保存为结构化数据。
我们将使用 requests
和 BeautifulSoup
两个库来完成爬虫任务,并最终将结果保存为 CSV 文件。
环境准备
首先,确保你的系统中安装了 Python 3.x。然后安装以下依赖库:
pip install requests beautifulsoup4 lxml pandas
requests
: 发送 HTTP 请求。beautifulsoup4
: 解析 HTML 文档。lxml
: 高性能的 HTML/XML 解析器。pandas
: 数据处理与分析。第一步:发送请求获取网页内容
我们以豆瓣电影 Top250 页面为例(https://movie.douban.com/top250),这是一个展示高评分电影的页面,非常适合练习爬虫。
示例代码:发送 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/119.0.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 来防止爬虫,因此我们需要设置合适的请求头模拟浏览器访问。
第二步:解析 HTML 内容
接下来我们使用 BeautifulSoup 对 HTML 内容进行解析,提取出每部电影的标题、评分、导演等信息。
示例代码:解析 HTML 并提取信息
from bs4 import BeautifulSoupsoup = BeautifulSoup(html_content, "lxml")movies = soup.find_all("div", class_="item")for movie in movies: rank = movie.find("em").text title = movie.find("span", class_="title").text rating = movie.find("span", class_="rating_num").text link = movie.find("a")["href"] print(f"排名:{rank} | 片名:{title} | 评分:{rating} | 链接:{link}")
上述代码会输出如下格式的信息:
排名:1 | 片名:肖申克的救赎 | 评分:9.5 | 链接:https://movie.douban.com/subject/1292052/...
第三步:分页爬取多个页面
豆瓣电影 Top250 是分页展示的,每页显示 25 条记录,共 10 页。我们需要循环遍历所有页面。
示例代码:分页爬取
base_url = "https://movie.douban.com/top250?start={}&filter="all_movies = []for page in range(0, 10): start = page * 25 url = base_url.format(start) response = requests.get(url, headers=headers) if response.status_code == 200: soup = BeautifulSoup(response.text, "lxml") items = soup.find_all("div", class_="item") for item in items: rank = item.find("em").text title = item.find("span", class_="title").text rating = item.find("span", class_="rating_num").text link = item.find("a")["href"] all_movies.append({ "排名": rank, "片名": title, "评分": rating, "链接": link }) else: print(f"第 {page + 1} 页请求失败,状态码:{response.status_code}")print(f"总共抓取 {len(all_movies)} 部电影信息。")
第四步:保存为 CSV 文件
为了方便后续的数据分析,我们可以将抓取的数据保存为 CSV 格式。
示例代码:使用 pandas 保存为 CSV
import pandas as pddf = pd.DataFrame(all_movies)df.to_csv("douban_top250.csv", index=False, encoding="utf-8-sig")print("数据已保存至 douban_top250.csv")
生成的 CSV 文件内容如下:
排名 | 片名 | 评分 | 链接 |
---|---|---|---|
1 | 肖申克的救赎 | 9.5 | https://movie.douban.com/... |
2 | 霸王别姬 | 9.6 | https://movie.douban.com/... |
第五步:进阶技巧 —— 异常处理与日志记录
在实际爬虫项目中,可能会遇到各种异常情况,如连接超时、IP 被封、页面结构变化等。因此我们需要添加异常处理机制。
示例代码:添加异常处理
import timeimport logginglogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')def fetch_page(url): try: response = requests.get(url, headers=headers, timeout=10) if response.status_code == 200: return response.text else: logging.error(f"请求失败,状态码:{response.status_code}") return None except requests.RequestException as e: logging.error(f"请求异常:{e}") return Nonefor page in range(0, 10): start = page * 25 url = base_url.format(start) logging.info(f"正在抓取第 {page + 1} 页...") html = fetch_page(url) if html: # 解析逻辑 pass time.sleep(2) # 模拟延迟,避免频繁请求被封 IP
总结
本文介绍了使用 Python 编写网络爬虫的基本流程,包括:
使用requests
发送 HTTP 请求;使用 BeautifulSoup
解析 HTML;分页爬取多个页面;将数据保存为 CSV;添加异常处理和日志记录功能。当然,网络爬虫是一个复杂的话题,还有许多高级主题值得深入探讨,比如:
使用Selenium
处理 JavaScript 渲染的页面;使用代理 IP 避免被封;使用 Scrapy
构建更强大的爬虫框架;设置合理的请求间隔,遵守网站的 robots 协议;数据清洗与存储(如数据库)。希望这篇文章能帮助你入门 Python 网络爬虫开发,并激发你对数据采集的兴趣!
完整代码整合版(供参考)
import requestsfrom bs4 import BeautifulSoupimport pandas as pdimport timeimport logginglogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"}base_url = "https://movie.douban.com/top250?start={}&filter="all_movies = []def fetch_page(url): try: response = requests.get(url, headers=headers, timeout=10) if response.status_code == 200: return response.text else: logging.error(f"请求失败,状态码:{response.status_code}") return None except requests.RequestException as e: logging.error(f"请求异常:{e}") return Nonefor page in range(0, 10): start = page * 25 url = base_url.format(start) logging.info(f"正在抓取第 {page + 1} 页...") html = fetch_page(url) if html: soup = BeautifulSoup(html, "lxml") items = soup.find_all("div", class_="item") for item in items: rank = item.find("em").text title = item.find("span", class_="title").text rating = item.find("span", class_="rating_num").text link = item.find("a")["href"] all_movies.append({ "排名": rank, "片名": title, "评分": rating, "链接": link }) time.sleep(2)df = pd.DataFrame(all_movies)df.to_csv("douban_top250.csv", index=False, encoding="utf-8-sig")logging.info("数据已保存至 douban_top250.csv")
作者:AI 助手
日期:2025年4月5日