使用Python实现一个简单的Web爬虫(含完整代码)
随着互联网的发展,网络数据变得越来越丰富。对于数据分析师、研究人员以及开发者来说,从网页中提取有用信息成为一项重要技能。Web爬虫(Web Crawler)技术正是用于自动抓取网页内容的工具。本文将介绍如何使用 Python 编写一个简单的 Web 爬虫,涵盖基本原理、常用库的使用方法,并提供完整的可运行代码示例。
我们将使用以下主要技术:
requests:用于发送 HTTP 请求获取网页内容。BeautifulSoup:用于解析 HTML 文档并提取所需数据。re(正则表达式):辅助提取特定格式的数据。本项目的目标是爬取一个示例网站中的文章标题和链接,并将其保存为本地 CSV 文件。
环境准备
在开始之前,请确保你的系统已安装以下 Python 库:
pip install requests beautifulsoup4 lxml
我们选择 lxml
作为 BeautifulSoup 的解析器,因为它速度快且兼容性好。
爬虫的基本流程
发送请求:向目标网址发送 HTTP 请求,获取响应内容。解析 HTML:使用 BeautifulSoup 解析返回的 HTML 内容。提取数据:定位到包含目标数据的 HTML 标签,提取所需信息。存储数据:将提取的数据保存至文件或数据库中。设置延迟与异常处理:避免对服务器造成过大压力,增强程序健壮性。项目实战:爬取博客文章标题和链接
3.1 目标网站分析
为了演示,我们以一个测试用的静态博客网站为例。假设我们要爬取该网站的所有文章标题和链接。
目标网站结构如下(模拟页面):
<div class="post-list"> <div class="post-item"> <h3><a href="/post/1">这是第一篇文章</a></h3> </div> <div class="post-item"> <h3><a href="/post/2">这是第二篇文章</a></h3> </div> ...</div>
我们的任务是从每个 .post-item
中提取 <a>
标签的文本和 href
属性。
3.2 完整代码实现
import requestsfrom bs4 import BeautifulSoupimport csvimport timeimport os# 设置目标URL(请替换为实际要爬取的网站)BASE_URL = "https://example.com/blog"HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36"}def fetch_page(url): """发送HTTP请求并返回响应内容""" try: response = requests.get(url, headers=HEADERS, timeout=10) response.raise_for_status() # 如果状态码不是200,抛出异常 return response.text except requests.RequestException as e: print(f"请求失败: {e}") return Nonedef parse_html(html): """解析HTML内容,提取文章标题和链接""" soup = BeautifulSoup(html, 'lxml') posts = [] # 查找所有文章条目 post_items = soup.select(".post-list .post-item") for item in post_items: title_tag = item.find("h3").find("a") if item.find("h3") else None if title_tag: title = title_tag.get_text(strip=True) link = title_tag["href"] full_link = BASE_URL + link if not link.startswith("http") else link posts.append({"title": title, "link": full_link}) return postsdef save_to_csv(data, filename="posts.csv"): """将数据保存为CSV文件""" file_exists = os.path.isfile(filename) with open(filename, mode='a', newline='', encoding='utf-8') as f: writer = csv.DictWriter(f, fieldnames=["title", "link"]) if not file_exists: writer.writeheader() writer.writerows(data)def crawl_blog(): """主函数:执行爬虫流程""" print("开始爬取文章列表...") html = fetch_page(BASE_URL) if html: posts = parse_html(html) if posts: save_to_csv(posts) print(f"成功爬取 {len(posts)} 篇文章,并保存至 posts.csv") else: print("未找到任何文章。") else: print("无法获取网页内容。")if __name__ == "__main__": crawl_blog()
代码说明与优化建议
4.1 关键部分解释
fetch_page(url)
:封装了请求逻辑,增加了 User-Agent 和超时控制。parse_html(html)
:使用 CSS 选择器定位文章元素,提取标题和链接,并补全相对路径。save_to_csv()
:使用 csv.DictWriter
将数据写入 CSV 文件,支持追加写入。crawl_blog()
:整个流程的控制函数。4.2 增强功能建议
多页爬取:如果目标网站有分页,可以循环爬取多个页面。代理/IP轮换:防止被封 IP。日志记录:使用logging
模块记录错误信息。并发处理:使用 concurrent.futures
或 asyncio
提升效率。Robots协议检查:遵守目标网站的爬虫策略。反爬虫机制与应对策略(简述)
一些网站会采取以下手段防止爬虫:
IP封锁验证码验证JavaScript渲染页面(如 SPA)用户行为检测应对方案包括:
使用代理IP池添加随机延迟使用 Selenium 或 Playwright 模拟浏览器操作登录后携带 Cookie 请求本文通过一个完整的 Python Web 爬虫实例,展示了从请求、解析到保存数据的全过程。虽然这是一个基础示例,但已经具备了一个爬虫的核心功能。掌握这些知识后,你可以根据具体需求扩展功能,如爬取图片、评论、商品价格等。
爬虫是一把双刃剑,使用时请务必遵守法律法规和网站的使用条款,尊重数据隐私和服务器资源。
附录:常见问题解答
Q1:为什么使用 BeautifulSoup 而不是 XPath?
A:两者都可以完成任务。BeautifulSoup 更适合快速开发和非严格的 HTML 解析,XPath 则更强大、灵活,尤其适用于 XML 或结构化较强的 HTML。
Q2:能否爬取 JavaScript 渲染的内容?
A:不能直接使用 requests 获取 JS 动态加载的内容。可以考虑使用 Selenium 或 Puppeteer 等无头浏览器工具。
Q3:爬虫会被封吗?
A:频繁访问可能会触发风控机制。建议添加 time.sleep(random.uniform(1, 3))
来模拟人类行为。
如果你希望我为你定制某个网站的爬虫,也可以告诉我目标网址和你想抓取的数据字段,我可以帮你生成对应的代码。