作为编程新手,你是否也曾好奇:那些网站上的信息、图片、榜单,能不能用 Python 轻松获取?今天这篇文章,我会带着大家从 0 开始,手把手拆解 Python 爬虫的核心知识点,结合实战案例(爬取虎扑热榜、豆瓣电影 Top250、壁纸图片、网站登录),让新手也能快速上手!
一、爬虫前置准备:安装核心库
首先我们需要安装爬虫必备的第三方库,为了下载更快,推荐使用清华镜像源:
bash
运行
# 发送HTTP请求核心库
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
# 解析HTML的XPath库
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple
# 生成随机User-Agent,避免被反爬
pip install fake_useragent -i https://pypi.tuna.tsinghua.edu.cn/simple
二、爬虫基础:Requests 库核心用法
Requests 是 Python 处理 HTTP 请求的 "神器",也是爬虫的基础,先掌握这些核心操作:
1. 最基础的 GET 请求
GET 请求是获取网页内容最常用的方式,一行代码就能拿到网页数据:
python
运行
import requests
# 发送GET请求,获取网页响应对象
r = requests.get('https://www.baidu.com')
# 打印响应状态码(200表示成功)
print("状态码:", r.status_code)
# 打印网页文本内容
print("网页内容:", r.text)
2. 响应对象的核心属性
拿到响应对象后,这些属性能帮我们获取关键信息:
python
运行
import requests
r = requests.get('https://www.baidu.com')
print("状态码:", r.status_code) # 请求状态(200成功/404不存在/500服务器错误)
print("响应头:", r.headers) # 网页的头部信息(服务器类型、编码等)
print("最终URL:", r.url) # 实际访问的URL(可能重定向)
print("编码方式:", r.encoding) # 网页编码
print("Cookies:", r.cookies) # 服务器返回的Cookies
3. 带参数的 GET 请求(搜索功能)
爬取搜索结果时,不用手动拼接 URL,用params参数更优雅:
python
运行
import requests
# 定义搜索参数
info = {'keyword':'excel'}
# 发送带参数的GET请求
r = requests.get('https://www.bilibili.com/search', params=info)
# 打印最终拼接的URL(https://www.bilibili.com/search?keyword=excel)
print(r.url)
# 打印搜索结果
print(r.text)
4. 解决中文乱码:设置编码
很多网页会出现中文乱码,这行代码能自动识别编码:
python
运行
import requests
r = requests.get('https://www.baidu.com')
r.encoding = r.apparent_encoding # 自动识别网页编码
print(r.text) # 正常显示中文
5. UA 伪装:避免被反爬
直接用 Python 请求会被网站识别为 "爬虫",伪装成浏览器请求:
python
运行
import requests
url = "https://www.baidu.com/"
# 模拟浏览器的User-Agent(可替换为自己浏览器的UA)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0"
}
# 带headers发送请求
r = requests.get(url, headers=headers)
r.encoding = r.apparent_encoding
print(r.text)
6. 下载二进制文件(图片 / 视频 / 音频)
爬取图片、视频等二进制文件时,用r.content而非r.text:
python
运行
import requests
# 图片URL
img_url = 'https://cdn.ptpress.cn/uploadimg/Material/978-7-115-68312-0/72jpg/68312_s300.jpg'
# 获取图片二进制数据
r = requests.get(img_url)
# 保存图片到本地(wb=二进制写入模式)
with open('壁纸.jpg', 'wb') as f:
f.write(r.content) # content存储二进制数据
print("图片下载完成!")
三、数据解析:从网页中提取有用信息
拿到网页内容后,需要从杂乱的 HTML 中提取目标数据,常用 2 种方式:正则表达式、XPath。
1. 正则表达式:灵活匹配文本
适合简单的文本提取,核心用re.findall()匹配目标内容:
实战:爬取虎扑热榜(正则版)
python
运行
import requests
import fake_useragent
import re
# 随机生成User-Agent,更隐蔽
headers = {"User-Agent": fake_useragent.UserAgent().random}
# 虎扑热榜移动端URL(更简洁)
r = requests.get("https://m.hupu.com/hot", headers=headers)
r.encoding = r.apparent_encoding
# 正则匹配热榜标题(根据网页结构调整正则表达式)
result = re.findall(r'"hot_hot-page-item-title__HL2kw">(.+?)</div><div class', r.text)
# 遍历打印热榜
for i, title in enumerate(result):
print(f'热点第{i+1}名:{title}')
2. XPath:精准解析 HTML 结构
XPath 是解析 HTML 的 "利器",通过标签路径精准定位内容,比正则更易维护:
先掌握 XPath 基础语法
| 语法 | 说明 | 示例 |
|---|---|---|
/ |
单层级定位 | /html/body/div |
// |
多层级定位(忽略中间层级) | //div[@class='song'] |
[@属性='值'] |
属性定位 | //div[@id='pics-list'] |
[n] |
索引定位(从 1 开始) | //li[3] |
/text() |
提取标签内文本 | //div/text() |
/@属性 |
提取标签属性值 | //img/@src |
实战:爬取虎扑热榜(XPath 版,更简洁)
python
运行
import requests
from lxml import etree
# 发送请求
r = requests.get("https://m.hupu.com/hot", headers={"User-Agent": fake_useragent.UserAgent().random})
r.encoding = r.apparent_encoding
# 解析HTML为XPath可操作的对象
tree = etree.HTML(r.text)
# 精准提取热榜标题
topics = tree.xpath('//div[@class="hot_hot-page-item-title__HL2kw"]/text()')
# 打印结果
for i, title in enumerate(topics):
print(f'热点第{i+1}名:{title}')
四、进阶实战:爬取豆瓣电影 Top250
结合 Requests+XPath + 正则,爬取豆瓣电影 Top250 的名称、导演、主演、评分等信息:
python
运行
import fake_useragent
import requests
from lxml import etree
import re
# 豆瓣电影Top250 URL
url = 'https://movie.douban.com/top250'
# 随机UA
headers = {"User-Agent": fake_useragent.UserAgent().random}
# 发送请求
resp = requests.get(url, headers=headers)
resp.encoding = resp.apparent_encoding
# 解析HTML
tree = etree.HTML(resp.text)
# 获取所有电影项
li_list = tree.xpath("//ol[@class='grid_view']/li")
# 保存结果到文件
with open("豆瓣Top250.txt", "w", encoding="utf8") as fp:
for li in li_list:
try:
# 提取电影名称
film_name = li.xpath("./div/div[2]/div[1]/a/span[1]/text()")[0]
# 提取导演/主演信息
film_actor = li.xpath("./div/div[2]/div[2]/p[1]/text()")
# 正则匹配导演和主演
daoyan = re.match("导演: (.+?) (.+)主演: (.+)", film_actor[0].strip()).group(1)
zhuyan = re.match("导演: (.+?) (.+)主演: (.+)", film_actor[0].strip()).group(3)
# 提取上映年份
year = re.match(".*?(\d+).*", film_actor[1].strip()).group(1)
# 提取评分
star = li.xpath("./div/div[2]/div[2]/div/span[2]/text()")[0]
# 提取经典台词
quote = li.xpath("./div/div[2]/div[2]/p[2]/span/text()")[0]
# 打印并保存
print(f"《{film_name}》| 导演:{daoyan} | 主演:{zhuyan} | 年份:{year} | 评分:{star} | 台词:{quote}")
fp.write(f"{film_name}#{daoyan}#{zhuyan}#{year}#{star}#{quote}\n")
except Exception as e:
# 忽略个别解析失败的情况
print(f"解析《{film_name}》失败:{e}")
pass
print("豆瓣电影Top250爬取完成,结果已保存到【豆瓣Top250.txt】")
五、高级实战:批量爬取壁纸图片
爬取多页壁纸并保存到本地文件夹,掌握循环 + 文件操作 + XPath 的综合用法:
python
运行
import fake_useragent
import requests
from lxml import etree
import os
# 计数器:给图片命名
img_count = 0
def get_img_num():
global img_count
img_count += 1
return img_count
# 创建文件夹存储图片
if not os.path.exists("./壁纸"):
os.mkdir("./壁纸")
# 随机UA
headers = {"User-Agent": fake_useragent.UserAgent().random}
# 爬取第1-2页的壁纸
for page in range(1, 3):
# 拼接分页URL
url = f'https://10wallpaper.com/List_wallpapers/page/{page}'
resp = requests.get(url, headers=headers)
resp.encoding = resp.apparent_encoding
# 解析HTML
tree = etree.HTML(resp.text)
# 获取所有图片项
p_list = tree.xpath("//div[@id='pics-list']/p")
# 遍历下载每张图片
for p in p_list:
# 提取图片相对URL
img_url = p.xpath("./a/img/@src")[0]
# 拼接完整URL
img_full_url = 'https://10wallpaper.com' + img_url
print(f"正在下载:{img_full_url}")
# 下载图片
img_resp = requests.get(img_full_url, headers=headers)
# 保存图片
with open(f"./壁纸/{get_img_num()}.jpg", "wb") as fp:
fp.write(img_resp.content)
print("壁纸下载完成!所有图片已保存到【壁纸】文件夹")
六、爬虫高级技巧
1. POST 请求:模拟表单提交(如登录)
POST 请求常用于提交数据(登录、改密码等),用data参数传递表单数据:
python
运行
import requests
# 登录表单数据
login_data = {'Email': '你的邮箱', 'Password': '你的密码'}
# 发送POST请求
r = requests.post('https://account.ryjiaoyu.com/log-in', data=login_data)
print("登录响应:", r.text)
2. 会话保持:模拟登录后访问页面
直接用 POST 登录后,GET 请求会丢失登录状态,用Session()保持会话:
python
运行
import requests
# 创建会话对象(自动保存Cookies)
s = requests.Session()
# 1. 登录
login_data = {'Email': '你的邮箱', 'Password': '你的密码', 'RememberMe': 'true'}
r1 = s.post('https://account.ryjiaoyu.com/log-in?returnUrl=https%3a%2f%2fwww.ryjiaoyu.com%2f', data=login_data)
# 2. 访问登录后的页面(自动携带登录Cookies)
r2 = s.get('https://www.ryjiaoyu.com/user')
print("登录后页面内容:", r2.text)
3. 处理防跨站请求伪造(CSRF Token)
很多网站登录需要 Token 验证,先爬取 Token 再提交:
python
运行
import requests
import re
# 获取登录页面的Token
def get_csrf_token(session):
# 访问登录页面
r = session.get('https://account.ryjiaoyu.com/log-in?ReturnUrl=https%3A%2F%2Fwww.ryjiaoyu.com%2Fuser')
# 正则匹配Token
token = re.findall(r'__RequestVerificationToken(.+)value="(.+)" />', r.text)[0][1]
return token
# 创建会话
s = requests.Session()
# 获取Token
token = get_csrf_token(s)
# 登录数据(包含Token)
login_data = {
'__RequestVerificationToken': token,
'Email': '你的邮箱',
'Password': '你的密码',
'RememberMe': 'true'
}
# 登录并访问用户页面
r1 = s.post('https://account.ryjiaoyu.com/log-in', data=login_data)
r2 = s.get('https://www.ryjiaoyu.com/user')
print("登录后用户页面:", r2.text)
4. 使用代理:隐藏 IP 地址
避免 IP 被封,用代理服务器发送请求:
python
运行
import requests
# 代理配置(替换为可用的代理)
proxies = {'http': 'http://115.29.199.16:8118', 'https': 'https://115.29.199.16:8118'}
# 带代理发送请求
r = requests.get('https://www.ryjiaoyu.com/', proxies=proxies)
print(r.text)
七、新手爬虫注意事项
- 遵守网站规则 :查看网站的
robots.txt(如https://www.baidu.com/robots.txt),不爬取禁止的内容; - 控制请求频率 :不要频繁请求,可添加
time.sleep(1)延迟,避免给服务器造成压力; - 处理异常 :添加
try-except捕获请求失败、解析失败等异常,避免程序崩溃; - 不要爬取敏感信息:如用户隐私、付费内容等,遵守法律法规。
总结
本文从基础到实战,覆盖了 Python 爬虫的核心知识点:
- Requests 库的 GET/POST 请求、UA 伪装、编码处理、二进制文件下载;
- 数据解析的 2 种方式:正则表达式(灵活)、XPath(精准);
- 实战案例:爬取虎扑热榜、豆瓣电影 Top250、批量下载壁纸;
- 高级技巧:会话保持、Token 处理、代理使用。
作为新手,建议先从简单的静态网页爬取开始,熟悉核心库的用法后,再尝试处理登录、分页、反爬等复杂场景。爬虫的核心是 "模拟浏览器请求 + 解析数据",多练、多调试,你也能轻松爬取想要的信息!