使用 Python 实现一个简单的 web 爬虫(建议收藏)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在互联网时代,数据如同空气般无处不在。无论是商业决策、学术研究还是个人兴趣,获取并分析网络上的海量信息都是一项核心能力。使用 Python 实现一个简单的 web 爬虫,可以帮助开发者快速入门这一领域。本文将通过循序渐进的方式,带领读者从零开始构建一个基础但完整的爬虫程序,并深入浅出地解释关键知识点。
知识准备:理解 web 爬虫的基本原理
什么是 web 爬虫?
web 爬虫(Web Crawler)可以看作是互联网上的“数字蜘蛛”。它通过模拟人类浏览网页的行为,自动抓取目标网站的数据,如文本、图片、链接等。想象一下:当用户在浏览器中输入网址时,浏览器会向服务器发送请求,服务器返回网页内容,用户再通过浏览器解析并展示内容。而爬虫正是通过自动化这一过程,将数据直接提取到本地。
爬虫的三大核心步骤
- 发送请求:向目标网站发送 HTTP 请求,获取网页内容。
- 解析响应:将服务器返回的 HTML、JSON 等格式的内容解析为可处理的数据。
- 存储或处理数据:将提取的数据保存到本地文件、数据库,或进行进一步分析。
环境配置与工具选择
Python 的优势
Python 在 web 爬虫领域占据主导地位,主要得益于其简洁的语法和丰富的第三方库。以下是一些常用的工具:
工具名称 | 功能描述 |
---|---|
requests | 发送 HTTP 请求,获取网页内容 |
BeautifulSoup4 | 解析 HTML 和 XML 文档,提取数据 |
Scrapy | 高级框架,适合大规模、复杂的爬虫项目 |
lxml | 高效的 HTML/XML 解析库 |
本文的工具选择
由于目标读者是编程初学者,我们将以 requests
和 BeautifulSoup4
为基础,构建一个轻量级爬虫。这两个库的学习成本较低,且功能足够覆盖基础场景。
pip install requests beautifulsoup4
第一步:发送 HTTP 请求
HTTP 请求的基础概念
当用户访问网页时,浏览器会向服务器发送一个 HTTP 请求(如 GET
请求),服务器则返回对应的网页内容。爬虫的核心任务之一,就是模拟这一过程。
示例:获取网页内容
import requests
url = "https://example.com"
response = requests.get(url)
if response.status_code == 200:
print("请求成功!")
print("响应内容:", response.text[:200]) # 打印前 200 字符
else:
print(f"请求失败,状态码:{response.status_code}")
关键知识点:状态码与异常处理
- 状态码:HTTP 响应的状态码(如
200
表示成功,404
表示页面不存在)是判断请求是否成功的重要依据。 - 异常处理:网络请求可能因超时、连接中断等问题失败,因此需要使用
try-except
块包裹代码,避免程序崩溃。
try:
response = requests.get(url, timeout=5) # 设置超时时间为 5 秒
except requests.exceptions.RequestException as e:
print(f"请求异常:{str(e)}")
第二步:解析 HTML 内容
解析 HTML 的核心工具:BeautifulSoup
BeautifulSoup
是 Python 中最易用的 HTML 解析库。它将复杂的 HTML 文档转换为可遍历的对象树,开发者可以通过标签名、属性等快速定位目标数据。
示例:提取网页中的所有链接
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
all_links = soup.find_all('a')
for link in all_links:
href = link.get('href')
if href:
print(href)
关键知识点:CSS 选择器与标签遍历
- CSS 选择器:类似网页开发中的 CSS 语法,可以精准定位元素。例如,
soup.select('div.content p')
表示选择所有在div
标签内且类名为content
的p
标签。 - 属性访问:通过
.text
获取标签内的文本,通过.attrs
获取标签的所有属性。
形象比喻
可以把 HTML 解析比作“在迷宫中找钥匙”。BeautifulSoup
就像一个手持地图的向导,能根据你的指令(如标签名、类名)快速定位到目标位置。
第三步:存储与处理数据
数据存储的常见方式
爬取到的数据需要持久化存储,常用的方法包括:
- 文本文件:适合小规模数据,如
json
或csv
格式。 - 数据库:如 SQLite、MySQL,适合需要频繁查询或处理大规模数据的场景。
示例:将链接保存为 CSV 文件
import csv
with open('links.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['URL']) # 写入表头
for link in all_links:
href = link.get('href')
if href:
writer.writerow([href])
进阶优化:让爬虫更健壮
遵守网站规则:robots.txt
在爬取任何网站前,必须先查看其 robots.txt
文件,了解允许或禁止爬取的路径。例如:
robots_url = "https://example.com/robots.txt"
robots_response = requests.get(robots_url)
print(robots_response.text)
防止被封禁:添加请求头与延迟
- 模拟浏览器行为:通过设置
User-Agent
头,伪装成真实浏览器:headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" } response = requests.get(url, headers=headers)
- 添加延迟:使用
time.sleep()
控制请求频率,避免短时间内发送过多请求:import time time.sleep(2) # 每次请求间隔 2 秒
完整代码示例:爬取豆瓣电影 Top 250
目标:提取电影名称、评分和简介
步骤 1:分析网页结构
访问 豆瓣电影 Top 250 ,观察 HTML 结构:
- 电影名称位于
<span class="title">
标签中。 - 评分位于
<span class="rating_num">
标签中。 - 简介位于
<span class="inq">
标签中(部分条目可能没有此标签)。
步骤 2:编写爬虫代码
import requests
from bs4 import BeautifulSoup
import csv
import time
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
movies = []
for page in range(0, 250, 25): # 步长为 25,对应 URL 中的 start 参数
url = f"https://movie.douban.com/top250?start={page}"
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 检查请求是否成功
soup = BeautifulSoup(response.text, 'html.parser')
items = soup.select('.item') # 所有电影条目
for item in items:
title = item.select_one('.title').text.strip()
rating = item.select_one('.rating_num').text.strip()
inq = item.select_one('.inq') # 可能不存在
if inq:
inq = inq.text.strip()
else:
inq = "无简介"
movies.append({
'title': title,
'rating': rating,
'intro': inq
})
print(f"第 {page//25 + 1} 页爬取完成")
time.sleep(2) # 避免请求过快
except Exception as e:
print(f"错误:{str(e)}")
with open('douban_movies.csv', 'w', newline='', encoding='utf-8-sig') as file:
fieldnames = ['title', 'rating', 'intro']
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(movies)
print("数据保存完成!")
结论与扩展方向
总结
本文通过一个具体的案例,展示了如何使用 Python 实现一个简单的 web 爬虫。从发送请求到解析数据,再到存储和优化,每个步骤都紧扣编程初学者的需求。关键点包括:
- 基础工具:
requests
和BeautifulSoup
是入门的黄金组合。 - 伦理与规范:尊重网站的
robots.txt
,合理控制爬取频率。 - 代码健壮性:通过异常处理和延迟机制,提升程序的可靠性。
进阶方向
- 动态网页爬取:使用
Selenium
或Playwright
处理 JavaScript 渲染的页面。 - 分布式爬虫:利用
Scrapy
框架实现高效的大规模爬取。 - 数据清洗与分析:结合
Pandas
或NLTK
进行数据处理和自然语言处理。
通过不断实践和学习,开发者可以逐步掌握更复杂的爬虫技术,解锁互联网数据的价值。
希望这篇文章能为你的 Python 爬虫之旅提供清晰的起点!