一篇最全Python 爬虫超详细讲解(零基础入门,适合小白)- 上篇
开篇:什么是爬虫?
昨天有个刚学编程的朋友问我:"爬虫是什么?是不是像蜘蛛一样爬网页?"
这个问题其实问得挺好。爬虫的本质,就是自动化地获取网页数据。
想象一下,你想收集1000个商品的价格信息:
• 手动复制粘贴:一个人不吃不喝可能要干一周
• 写个爬虫程序:几分钟搞定
爬虫就是帮你"自动化浏览网页、提取数据"的工具。它像是一个不知疲倦的助手,24小时不停歇地帮你"逛网站、记笔记"。
爬虫的应用场景
其实爬虫在生活中的应用很广泛:
数据分析场景:比如你想分析某个城市的房价走势,可以爬取链家、贝壳的房源 数据,然后做统计分析。
舆情监控场景:公司想了解用户对某个产品的评价,可以爬取微博、小红书的用 户评论,分析情感倾向。
竞争情报场景:电商平台想监控竞品的价格变化,可以爬取对方网站的价格数 据。
个人兴趣场景:比如你想批量下载某个网站的图片、批量获取某个UP主的所有 视频标题,都可以用爬虫实现。
不过要注意:爬虫技术本身是中立的,但如何使用涉及法律和道德边界。这个我们在文章最后会详细讨论。
环境准备
开始写爬虫之前,得先把"装备"准备好。
1. 安装Python
如果你还没安装Python,推荐去官网下载:https://www.python.org/downloads/
Windows用户:
• 下载Windows安装包(建议选3.10或3.11版本)
• 安装时务必勾选"Add Python to PATH",不然后续会有坑
• 安装完成后,打开CMD输入python --version,看到版本号就成功了
Mac用户:
• 推荐用Homebrew安装:brew install python
• 或者直接下载官网的pkg安装包
Linux用户:
• Ubuntu/Debian:sudo apt install python3
• CentOS/RHEL:sudo yum install python3
2. 安装开发环境
对于新手,我推荐两个选择:
VS Code(免费,轻量级)
• 下载地址:https://code.visualstudio.com/
• 安装Python插件
• 对新手友好,生态丰富
PyCharm(功能强大)
• 社区版免费:https://www.jetbrains.com/pycharm/download/
• 适合做中大型项目
• 但启动稍慢,对电脑配置要求高
我的建议:刚开始学,用VS Code就足够了。等熟练了再考虑PyCharm。
3. 安装必要的库
Python的强大之处在于有丰富的第三方库。写爬虫,这几个库是标配:
# 核心HTTP请求库
pip install requests
# HTML解析库
pip install beautifulsoup4
# XPath解析库
pip install lxml
# 更强大的解析库(支持XPath和CSS选择器)
pip install parsel
# 自动化工具(动态网页用)
pip install selenium
安装完成后,可以用这个命令检查是否成功:
import requests
import bs4
print("库安装成功!")
如果能正常输出,说明环境就准备好了。
HTTP基础:理解爬虫的"语言"
爬虫本质上是和Web服务器"对话"。这种对话用的"语言"就是HTTP协议。
什么是HTTP请求和响应?
HTTP请求:就是你的爬虫对服务器说的话。
HTTP响应:就是服务器给你的回复。
举个通俗的例子:
你(爬虫):老板,给我看一下某件商品的信息
服务器:好的,这是商品的信息(返回HTML页面)
HTTP请求的组成
一个HTTP请求包含几个关键部分:
1. 请求方法
• GET:获取数据(最常用,占90%以上)
• POST:提交数据(比如登录、发表评论)
• PUT:更新数据
• DELETE:删除数据
2. 请求头(Headers)
这是服务器用来识别你的"身份证"。重要的请求头包括:
• User-Agent:告诉服务器你是谁(浏览器类型、操作系统)
• Referer:告诉服务器你从哪里来
• Cookie:你的登录状态、个人偏好
3. 请求参数
比如搜索"Python"时,URL可能是这样的:
https://www.example.com/search?q=Python&page=1
这里的q=Python和page=1就是请求参数。
HTTP响应的组成
服务器返回的响应也包含几个部分:
1. 状态码:这是服务器的"回复状态"
• 200:成功(最常见)
• 404:找不到页面
• 403:禁止访问(可能是被反爬了)
• 500:服务器内部错误
• 301/302:页面跳转
2. 响应头
• Content-Type:返回内容的类型(HTML、JSON、图片等)
• Content-Length:内容长度
• Set-Cookie:服务器给你设置的Cookie
3. 响应体
这是真正的内容,通常是HTML页面、JSON数据、图片等。
实战:用requests发送第一个请求
import requests
# 目标URL
url = "https://www.example.com"
# 发送GET请求
response = requests.get(url)
# 查看状态码
print(f"状态码:{response.status_code}")
# 查看响应内容
print(f"响应内容(前200字符):{response.text[:200]}")
# 查看响应头
print(f"Content-Type: {response.headers.get('Content-Type')}")
运行结果示例:
状态码:200
响应内容(前200字符):<!doctype html>
<html>
<head>
<title>Example Domain</title>
...
Content-Type: text/html; charset=UTF-8
数据解析:从HTML中提取数据
拿到网页内容后,下一步就是从HTML中提取你需要的数据。
HTML是什么?简单说,就是网页的"骨架",用标签来组织内容。
<div class="product">
<h3 class="title">Python编程从入门到实践</h3>
<p class="price">¥89.00</p>
<p class="author">作者:Eric Matthes</p>
</div>
我们的目标就是:从这样的HTML中,提取出书名、价格、作者。
方法1:正则表达式
正则表达式是文本匹配的利器,适合简单、规则明确的场景。
优点:功能强大,灵活性高
缺点:写起来复杂,可读性差,HTML结构变化容易失效
示例:
import re
html = """
<div class="product">
<h3 class="title">Python编程从入门到实践</h3>
<p class="price">¥89.00</p>
</div>
"""
# 提取书名
title = re.search(r'<h3 class="title">(.*?)</h3>', html)
if title:
print(f"书名:{title.group(1)}")
# 提取价格
price = re.search(r'<p class="price">(.*?)</p>', html)
if price:
print(f"价格:{price.group(1)}")
运行结果:
书名:Python编程从入门到实践
价格:¥89.00
方法2:BeautifulSoup
BeautifulSoup是HTML解析神器,用"标签树"的方式理解网页结构。
优点:简单易用,对不规范的HTML容忍度高,语法清晰
缺点:解析速度较慢,功能不如XPath丰富
示例:
from bs4 import BeautifulSoup
html = """
<div class="product">
<h3 class="title">Python编程从入门到实践</h3>
<p class="price">¥89.00</p>
<p class="author">作者:Eric Matthes</p>
</div>
"""
# 创建BeautifulSoup对象
soup = BeautifulSoup(html, 'html.parser')
# 通过class查找元素
product_div = soup.find('div', class_='product')
# 提取书名
title = product_div.find('h3', class_='title').text
print(f"书名:{title}")
# 提取价格
price = product_div.find('p', class_='price').text
print(f"价格:{price}")
# 提取作者
author = product_div.find('p', class_='author').text
print(f"作者:{author}")
运行结果:
书名:Python编程从入门到实践
价格:¥89.00
作者:作者:Eric Matthes
BeautifulSoup常用方法:
# 查找单个元素
soup.find('div') # 找第一个div
soup.find('div', class_='content') # 找class为content的div
soup.find('div', id='main') # 找id为main的div
# 查找所有元素
soup.find_all('a') # 找所有a标签
soup.find_all('div', class_='item') # 找所有class为item的div
# 通过属性查找
soup.find(attrs={'data-id': '123'}) # 找data-id属性为123的元素
# 获取文本内容
element.text # 获取元素内所有文本
element.get_text(strip=True) # 获取文本并去除空白
# 获取属性值
element['href'] # 获取a标签的href属性
element.get('src') # 获取src属性(如果没有返回None)
方法3:XPath
XPath是XML路径语言,可以精确地定位HTML中的元素。
优点:功能强大,选择器丰富,适合复杂结构
缺点:学习曲线较陡,对HTML结构要求高
示例:
from lxml import etree
html = """
<div class="product">
<h3 class="title">Python编程从入门到实践</h3>
<p class="price">¥89.00</p>
<p class="author">作者:Eric Matthes</p>
</div>
"""
# 创建XPath对象
tree = etree.HTML(html)
# 提取书名
title = tree.xpath('//div[@class="product"]//h3[@class="title"]/text()')
print(f"书名:{title[0]}")
# 提取价格
price = tree.xpath('//div[@class="product"]//p[@class="price"]/text()')
print(f"价格:{price[0]}")
# 提取作者
author = tree.xpath('//div[@class="product"]//p[@class="author"]/text()')
print(f"作者:{author[0]}")
运行结果:
书名:Python编程从入门到实践
价格:¥89.00
作者:作者:Eric Matthes
XPath常用语法:
# 路径选择
# / 从根节点选择
# // 从任意节点选择
# . 当前节点
# .. 父节点
# 属性选择
//div[@class="content"] # class为content的div
//a[@href] # 有href属性的a标签
//a[contains(@href, "python")] # href包含"python"的a标签
# 索引选择
//div[1] # 第1个div(索引从1开始)
//div[last()] # 最后一个div
//div[position() < 3] # 前2个div
# 文本选择
//h3/text() # h3标签的文本内容
//h3//text() # h3标签及其子标签的所有文本
三种方法的对比
|
方法 |
难度 |
速度 |
灵活性 |
适用场景 |
|
正则表达式 |
⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
⭐⭐⭐⭐ |
简单文本提取、URL匹配 |
|
BeautifulSoup |
⭐ |
⭐⭐ |
⭐⭐⭐ |
静态网页、不规范的HTML |
|
XPath |
⭐⭐ |
⭐⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
复杂结构、精确选择 |
我的建议:
• 新手入门:从BeautifulSoup开始,简单易用
• 需要精确选择:用XPath
• 简单文本匹配:用正则表达式
实战案例1:爬取静态网站
现在让我们做一个完整的实战案例:爬取一个简单网站的图书信息。
为了演示,我们用一个模拟的图书网站(实际使用时替换为真实网站)。
目标网站分析
假设我们要爬取的网站页面结构如下:
<div class="book-list">
<div class="book-item">
<h3 class="book-title">Python编程从入门到实践</h3>
<p class="book-price">¥89.00</p>
<p class="book-author">作者:Eric Matthes</p>
</div>
<div class="book-item">
<h3 class="book-title">流畅的Python</h3>
<p class="book-price">¥99.00</p>
<p class="book-author">作者:Luciano Ramalho</p>
</div>
</div>
完整代码
import requests
from bs4 import BeautifulSoup
import csv
import time
import random
def crawl_books():
"""爬取图书信息并保存到CSV"""
# 目标URL(实际使用时替换为真实URL)
url = "https://www.example.com/books"
# 请求头(伪装成浏览器)
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'
}
# 发送请求
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 检查请求是否成功
print(f"请求成功,状态码:{response.status_code}")
except requests.exceptions.RequestException as e:
print(f"请求失败:{e}")
return
# 解析HTML
soup = BeautifulSoup(response.text, 'html.parser')
# 提取图书信息
books = []
book_items = soup.find_all('div', class_='book-item')
print(f"找到 {len(book_items)} 本书")
for i, item in enumerate(book_items, 1):
try:
# 提取信息
title = item.find('h3', class_='book-title').text.strip()
price = item.find('p', class_='book-price').text.strip()
author = item.find('p', class_='book-author').text.strip()
# 存储到列表
books.append({
'书名': title,
'价格': price,
'作者': author
})
print(f"[{i}/{len(book_items)}] {title} - {price}")
except AttributeError as e:
print(f"解析第{i}本书时出错:{e}")
continue
# 保存到CSV文件
if books:
save_to_csv(books, 'books.csv')
print(f"成功保存 {len(books)} 本书到 books.csv")
else:
print("未找到任何图书信息")
def save_to_csv(data, filename):
"""保存数据到CSV文件"""
with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
# 运行爬虫
if __name__ == '__main__':
crawl_books()
代码说明
1. 请求头设置
headers = {
'User-Agent': 'Mozilla/5.0...'
}
这是伪装成浏览器的关键。不设置User-Agent,很多网站会拒绝请求。
2. 异常处理
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"请求失败:{e}")
return
网络请求可能失败,所以必须加异常处理。timeout=10设置10秒超时,避免长时间等待。
3. 数据提取
book_items = soup.find_all('div', class_='book-item')
找到所有图书项,然后遍历每个item提取信息。
4. 数据保存
with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
保存到CSV文件,方便后续用Excel打开查看。
运行结果示例
请求成功,状态码:200
找到 2 本书
[1/2] Python编程从入门到实践 - ¥89.00
[2/2] 流畅的Python - ¥99.00
成功保存 2 本书到 books.csv
生成的CSV文件内容:
|
书名 |
价格 |
作者 |
|
Python编程从入门到实践 |
¥89.00 |
作者:Eric Matthes |
|
流畅的Python |
¥99.00 |
作者:Luciano Ramalho |
实战案例2:爬取多页数据
很多网站的数据是分页的,需要爬取多个页面。
修改后的代码
import requests
from bs4 import BeautifulSoup
import csv
import time
def crawl_books_multi_page(max_pages=3):
"""爬取多页图书信息"""
base_url = "https://www.example.com/books"
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'
}
all_books = []
for page in range(1, max_pages + 1):
# 构造分页URL(假设分页参数是page)
url = f"{base_url}?page={page}"
print(f"正在爬取第 {page} 页...")
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
# 解析
soup = BeautifulSoup(response.text, 'html.parser')
book_items = soup.find_all('div', class_='book-item')
print(f"第 {page} 页找到 {len(book_items)} 本书")
for item in book_items:
try:
title = item.find('h3', class_='book-title').text.strip()
price = item.find('p', class_='book-price').text.strip()
author = item.find('p', class_='book-author').text.strip()
all_books.append({
'书名': title,
'价格': price,
'作者': author,
'页码': page # 记录来自哪一页
})
except AttributeError as e:
print(f"解析出错:{e}")
continue
# 随机延时,避免请求过快
time.sleep(random.uniform(1, 3))
except requests.exceptions.RequestException as e:
print(f"第 {page} 页请求失败:{e}")
continue
# 保存
if all_books:
save_to_csv(all_books, 'books_multi_page.csv')
print(f"总共爬取 {len(all_books)} 本书,已保存到 books_multi_page.csv")
else:
print("未找到任何图书信息")
def save_to_csv(data, filename):
"""保存数据到CSV文件"""
with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
# 运行爬虫
if __name__ == '__main__':
crawl_books_multi_page(max_pages=5)
关键点说明
1. 分页URL构造
url = f"{base_url}?page={page}"
不同网站的分页参数可能不同(可能是page、p、offset等),需要根据具体网站调整。
2. 随机延时
time.sleep(random.uniform(1, 3))
这是非常重要的反爬策略,避免请求过快被服务器识别为爬虫。
3. 异常处理
每一页的请求都可能失败,所以要把try-except放在循环内部,避免某一页失败影响整个爬取。
上篇总结
到这里,你已经掌握了Python爬虫的基础知识:
✅ 环境搭建:Python安装、开发环境配置、第三方库安装
✅ HTTP基础:理解请求/响应、状态码、Headers
✅ 数据解析:正则表达式、BeautifulSoup、XPath三种方法
✅ 实战案例:单页爬取、多页爬取、数据存储到CSV
上篇学习建议:
1. 动手敲一遍所有代码,理解每一行的作用
2. 使用练习网站(Quotes to Scrape、Books to Scrape)进行实际练习
3. 遇到错误时,仔细阅读错误信息,学会独立调试
下篇预告:
• 反爬应对策略(User-Agent伪装、频率控制、代理、Cookie、验证码)
• 动态网站处理(Selenium实战)
• 常见错误及解决方案
• 爬虫法律和道德规范
• 学习路径和进阶方向
继续学习下篇,让你从"能跑"进阶到"精通"!
下期预告:《一篇最全Python 爬虫超详细讲解(零基础入门,适合小白)- 下篇》- 反爬策略与进阶实战
更多推荐
所有评论(0)