一、前言

对于爬虫入门者而言,最核心的需求是 “能看懂、能运行、能落地”。本文从零开始,循序渐进讲解 Python 爬虫核心技术 —— 从基础的requests请求、UA 伪装、数据保存,到re正则解析、lxml的 XPath 提取,再到 Selenium 自动化浏览器操作,全程附完整可运行代码 + 详细注释,帮你快速上手,避开入门常见坑。

入门提醒:静态网页用requests结合解析工具即可高效爬取,但如今多数网站采用 JavaScript 动态渲染(如滚动加载、点击加载更多、登录后才显示内容),此时requests无法获取渲染后的完整数据,而 Selenium 能完美解决这一痛点。下面先吃透 Selenium 核心知识,再逐步开展实战演练。


二、基础篇:requests 请求与 UA 伪装(入门必学)

1. 基础 GET 请求 + UA 伪装(避坑核心)

很多新手刚入门时,直接用requests发送请求会被网站拦截,核心原因是未进行 UA 伪装 —— 网站会识别出请求来自 Python 程序,而非真实浏览器。因此,UA 伪装是爬虫入门的第一个必学技巧。

python

'''UA伪装:模拟浏览器请求,避免被服务器拦截(入门必写)'''
import requests

# 目标URL(百度首页,可直接替换为其他静态网页)
url = "https://www.baidu.com/"

# UA伪装:模拟Chrome浏览器的请求头(复制自己浏览器的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"
}

# 发送GET请求(带UA伪装,避免被拦截)
response = requests.get(url, headers=headers)

# 自动识别网页编码,彻底解决中文乱码问题(新手必加)
response.encoding = response.apparent_encoding

# 打印网页源码(验证请求是否成功)
print(response.text)

2. 保存网页中的图片 / 文件(实战常用)

爬虫实战中,经常需要下载图片、文档等资源,核心是通过requests获取资源的二进制内容,再以二进制写入模式保存到本地,步骤简单且通用。

python

'''保存网页中的图片(二进制文件写入,实战通用模板)'''
import requests

# 图片URL(可替换为任意图片链接)
img_url = 'https://cdn.ptpress.cn/uploadimg/Material/978-7-115-68312-0/72jpg/68312_s300.jpg'

# 发送请求获取图片二进制数据(图片、视频均为二进制资源)
response = requests.get(img_url)

# 以二进制写入模式保存图片(wb=二进制写,不可修改)
with open('book_cover.jpg', 'wb') as f:
    f.write(response.content)
print("图片保存成功!可在当前文件夹查看")

# 补充:保存文本文件示例(爬虫结果保存常用)
with open('a.txt', 'w', encoding='utf-8') as f:
    f.write('人工智能')
print("文本文件保存成功!")

3. 正则解析网页数据(简单场景首选)

对于简单的文本提取场景(如提取标题、链接),无需复杂解析工具,用re.findall()即可快速提取目标信息,适合新手入门练习。

python

'''使用正则表达式提取网页中的图书信息(简单场景实战)'''
import requests
import re

# 目标网页(可替换为自己需要爬取的静态网页)
url = 'https://www.ryjiaoyu.com/tag/details/7'

# 发送请求(带UA伪装更佳,此处简化演示)
response = requests.get(url)
html = response.text

# 正则表达式:匹配标题和链接(根据网页源码调整正则规则)
pattern = r'title="(.+?)">(.+?)'
result = re.findall(pattern, html)

# 打印提取结果(格式化输出,更易查看)
for i, (link, title) in enumerate(result, 1):
    print(f'第{i}本书:{title},链接:{link}')

# 注意:若提取结果为空,需检查正则表达式是否与网页源码匹配'

三、进阶篇:XPath 解析与数据提取(实战核心)

1. XPath 基础用法(复杂网页首选)

当网页结构复杂、需要精准提取结构化数据时,XPath 比正则更高效、更易维护。下面通过本地 HTML 文件,快速掌握 XPath 核心定位方法,新手可直接复制代码练习。

python

'''XPath解析本地HTML文件基础示例(新手必练)'''
from lxml import etree

# 解析本地HTML文件(需提前创建test.html文件,或替换为在线网页解析)
tree = etree.parse("test.html")

# 1. 获取网页标题(最基础定位,必学)
print("网页标题:", tree.xpath("/html/head/title/text()"))

# 2. 获取body下所有div的p标签文本(批量提取)
print("所有段落文本:", tree.xpath("/html/body/div/p/text()"))

# 3. 索引定位(重点:XPath索引从1开始,而非0)
print("第一个div下的p文本:", tree.xpath("/html/body/div[1]/p/text()"))
print("第二个div下的p文本:", tree.xpath("/html/body/div[2]/p/text()"))
print("第二个div下第二个p文本:", tree.xpath("/html/body/div[2]/p[2]/text()"))

# 4. 属性定位(最常用,根据class、id筛选元素)
print("class为song的div下第二个p文本:", tree.xpath("//div[@class='song']/p[2]/text()"))

# 5. 层级定位(//表示跨层级,无需写完整路径,高效)
print("跨层级定位class为song的div下第三个p文本:", tree.xpath("//div[@class='song']/p[3]/text()"))

# 6. 获取标签属性值(爬取链接、图片常用,@src/@href)
print("图片的src属性:", tree.xpath("//div[@class='song']/img/@src"))
print("链接的href属性:", tree.xpath("//div[@class='tang']/ul/li[3]/a/@href")[0])

2. 实战:爬取虎扑热榜(XPath 实战演练)

结合在线网页,实战练习 XPath 解析,提取虎扑热榜话题,代码可直接运行,新手可通过此案例熟悉 “请求 - 解析 - 提取” 完整流程。

python

'''爬取虎扑热榜话题(XPath解析版,新手可直接运行)'''
import requests
from lxml import etree

# 目标URL(虎扑热榜移动端,结构更简洁,适合新手)
url = "https://m.hupu.com/hot"

# 发送请求(建议添加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"}
response = requests.get(url, headers=headers)
tree = etree.HTML(response.text)  # 解析在线网页源码

# 定位热榜话题容器(根据网页源码调整XPath路径)
hot_list = tree.xpath("//article[@class='hot_hot-page__jgBZU']/div")

# 遍历提取话题(添加异常捕获,避免报错终止程序)
for i, item in enumerate(hot_list, 1):
    try:
        topic = item.xpath("./section/div[2]/text()")[0].strip()
        print(f"热点第{i}:{topic}")
    except:
        continue

# 补充:更简洁的写法(直接定位话题文本,新手推荐)
topics = tree.xpath('//div[@class="hot_hot-page-item-title__HL2kw"]/text()')
for i, topic in enumerate(topics, 1):
    print(f"热点第{i}:{topic.strip()}")

3. 实战:批量爬取壁纸图片(综合实战)

结合fake_useragent随机 UA 伪装(提升反爬能力),批量爬取壁纸网站图片并保存到本地文件夹,整合 “请求 - 解析 - 下载 - 保存” 全流程,适合新手巩固基础。

python

'''批量爬取壁纸图片(含随机UA伪装,综合实战案例)'''
import fake_useragent
import requests
from lxml import etree
import os

# 全局计数器,用于图片命名(避免文件名重复)
n = 0
def count():
    global n
    n += 1
    return n

# 创建保存图片的文件夹(不存在则创建,避免报错)
if not os.path.exists("./Picture"):
    os.mkdir("./Picture")

# 随机UA伪装(自动生成不同浏览器UA,降低被拦截概率)
headers = {
    "User-Agent": fake_useragent.UserAgent().random
}

# 爬取多页图片(可修改range范围,控制爬取页数)
for page in range(1, 4):
    url = f"https://10wallpaper.com/List_wallpapers/page/{page}"
    response = requests.get(url, headers=headers)
    tree = etree.HTML(response.text)
    
    # 定位所有图片容器(若提取不到,需检查XPath路径是否正确)
    p_list = tree.xpath("//div[@id='pics-list']/p")
    
    for p in p_list:
        try:
            # 提取图片URL并拼接完整地址(避免URL不完整导致下载失败)
            img_url = p.xpath("./a/img/@src")[0]
            full_img_url = 'https://10wallpaper.com' + img_url
            print("图片地址:", full_img_url)
            
            # 下载图片(添加异常捕获,避免单张图片下载失败影响全局)
            img_response = requests.get(full_img_url, headers=headers)
            img_name = count()
            
            # 保存图片到本地(wb模式,适配所有图片格式)
            with open(f"./Picture/{img_name}.jpg", "wb") as f:
                f.write(img_response.content)
            print(f"图片{img_name}.jpg 保存成功!")
        except Exception as e:
            print(f"图片下载失败:{e}")
            continue

# 注意:若出现404报错,说明壁纸网站页面不存在,可替换为其他壁纸网站URL'

4. 实战:爬取豆瓣 Top250 电影信息(高频实战)

豆瓣 Top250 是爬虫入门高频实战案例,结合 XPath 和正则表达式,提取电影名称、导演、主演、年份、评分和简介,同时将结果保存到本地文件,贴近真实爬虫需求。

python

'''爬取豆瓣Top250电影信息(高频实战,新手必练)'''
import fake_useragent
import requests
from lxml import etree
import re

# 目标URL(豆瓣Top250首页)
url = 'https://movie.douban.com/top250'

# 随机UA伪装(豆瓣反爬较严格,必须添加)
headers = {
    "User-Agent": fake_useragent.UserAgent().random
}

# 发送请求(添加超时设置,避免程序卡死)
response = requests.get(url, headers=headers, timeout=10)
html = response.text

# 打开文件保存结果(utf-8编码,避免中文乱码)
with open("doubanFilm.txt", "w", encoding="utf8") as f:
    # 解析HTML
    tree = etree.HTML(html)
    li_list = tree.xpath("//ol[@class='grid_view']/li")
    
    for li in li_list:
        try:
            # 提取电影名称(核心信息,精准定位)
            film_name = li.xpath(".//div[@class='hd']/a/span[1]/text()")[0]
            
            # 提取导演和主演信息(正则+XPath结合,处理复杂文本)
            info_text = li.xpath(".//div[@class='bd']/p[1]/text()")[0].strip()
            film_director = re.match(r"导演: (.+?) .*", info_text).group(1)
            film_star = re.match(r".*主演: (.+)", info_text).group(1)
            film_year = re.match(r".*?(\d+).*", info_text).group(1)
            
            # 提取评分和简介(用户关注的核心信息)
            film_star_rating = li.xpath(".//div[@class='star']/span[2]/text()")[0]
            film_quote = li.xpath(".//div[@class='bd']/p[@class='quote']/span/text()")[0]
            
            # 打印并写入文件(用#分隔,方便后续处理数据)
            print(film_name, film_director, film_star, film_year, film_star_rating, film_quote)
            f.write(f"{film_name}#{film_director}#{film_star}#{film_year}#{film_star_rating}#{film_quote}\n")
        except Exception as e:
            print(f"提取失败:{e}")
            continue

print("豆瓣电影信息已保存到doubanFilm.txt!可在当前文件夹查看")

四、自动化篇:Selenium 浏览器操作(附详细介绍,动态网页必学)

1. 什么是 Selenium?

很多新手疑惑:有了requests,为什么还要学 Selenium?答案很简单 ——requests无法处理动态渲染网页,而 Selenium 能完美解决这一问题。

Selenium 是一款开源的 Web 自动化测试工具,诞生于 2004 年,最初用于 Web 应用程序的自动化测试,后来被广泛应用于爬虫开发。它的核心作用是模拟真实用户的浏览器操作,包括打开浏览器、访问网页、点击按钮、填写表单、滚动页面、切换标签页等,就像真实用户在操作浏览器一样,能够获取到 JavaScript 渲染后的完整网页源码,彻底解决动态网页爬取的痛点。

2. Selenium 的核心特性与工作原理

核心特性(新手重点关注)
  • 跨浏览器支持:兼容 Chrome、Firefox、Edge、Safari 等所有主流浏览器,适配 Windows、Mac、Linux 等操作系统,新手优先用 Chrome/Edge。
  • 多语言支持:支持 Python、Java、C#、JavaScript 等多种编程语言,爬虫开发中最常用 Python 语言绑定,上手门槛低。
  • 模拟真实交互:可模拟点击、输入、下拉、前进 / 后退、切换窗口等所有用户操作,还原真实浏览行为,避开网站反爬。
  • 支持无头模式:可在不显示浏览器界面的情况下运行脚本,节省系统资源,提高运行效率,适合服务器部署和批量爬取。
  • 核心组件完善:包含 Selenium WebDriver(核心驱动,控制浏览器)、Selenium IDE(录制回放工具,新手快速生成脚本)、Selenium Grid(分布式并行测试),满足不同场景需求。
工作原理(通俗理解,无需深入)

Selenium 采用 “客户端 - 服务器” 架构,运行流程简单易懂,新手无需深入底层,知道大致逻辑即可:

  1. 开发者编写 Python Selenium 脚本,调用 Selenium WebDriver 客户端 API(就是我们写的代码)。
  2. WebDriver 客户端将脚本中的操作指令(如打开网页、点击按钮)转换为符合 W3C 标准的 HTTP 请求。
  3. HTTP 请求发送给对应浏览器的驱动程序(如 Chrome 对应 ChromeDriver,Edge 对应 EdgeDriver)。
  4. 浏览器驱动接收请求后,通过浏览器内置调试接口,控制浏览器执行对应操作(如打开百度、点击搜索)。
  5. 浏览器执行操作后,将结果(如网页源码)通过驱动、WebDriver 客户端反馈给脚本,完成一次交互。
Selenium 与 requests 的核心区别(新手必看,避免用错工具)

很多新手会混淆两者的用途,这里用一张表格清晰区分,帮你根据场景选择合适的工具,避免做无用功:

表格

对比维度 requests Selenium
核心定位 发送 HTTP 请求,直接与服务器交互 控制浏览器,模拟用户操作,获取渲染后内容
动态网页支持 不支持,无法解析 JavaScript 渲染内容 完全支持,可获取 JS 渲染后的完整源码
运行速度 快,轻量无冗余,资源消耗低 慢,需启动浏览器,资源消耗大
交互能力 无交互能力,仅能发送请求、接收响应 强,可模拟点击、输入、滚动等所有用户操作
适用场景 静态网页爬取、API 接口调用、高频数据采集 动态网页爬取、需要交互的场景(登录、下拉加载)、浏览器环境检测的网站
前置准备(必看,否则必报错)

使用 Selenium 前,必须完成两个核心准备工作,新手最容易栽在这一步,一定要仔细看:

  1. 安装 Selenium 库:打开终端,执行命令 pip install selenium(确保 Python 环境已配置,若安装失败,可加-i https://pypi.tuna.tsinghua.edu.cn/simple用清华源)。
  2. 下载浏览器驱动:驱动必须与本地浏览器版本对应(如 Edge 浏览器 142 版本,需下载 142 版本的 EdgeDriver;Chrome 同理),下载后将驱动路径配置到环境变量,或在代码中指定驱动路径。

关键提示:浏览器驱动版本必须与浏览器版本完全匹配(如 Chrome 142.0.7026.64,需下载对应 142 版本的 ChromeDriver),否则会出现 “驱动不兼容” 报错,新手可在浏览器设置中查看版本,再去对应官网下载驱动。

3. Selenium 实战:基础操作(新手入门必练)

(1)基础:打开网页并获取源码

入门第一步:使用 Selenium 驱动 Edge 浏览器,打开指定网页并获取渲染后的源码,代码可直接运行,新手可先熟悉浏览器启动和关闭流程。

python

'''使用Selenium打开Edge浏览器并访问网页(入门基础)'''
from selenium import webdriver
from selenium.webdriver.edge.options import Options

# 配置Edge浏览器选项(新手可直接复制,修改浏览器路径即可)
edge_options = Options()
# 指定Edge浏览器的安装路径(根据自己的电脑路径修改,避免报错)
edge_options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"

# 初始化浏览器驱动(若驱动已配置环境变量,可省略executable_path参数)
driver = webdriver.Edge(options=edge_options)

# 打开目标网页(可替换为任意网页)
driver.get('https://www.ptpress.com.cn/')

# 暂停脚本,方便观察浏览器窗口(按回车继续执行,避免浏览器瞬间关闭)
input('等待用户操作,按回车继续...')

# 关闭浏览器(释放资源,避免后台残留进程,新手必写)
driver.quit()
(2)进阶:打开多个标签页

实战中经常需要同时访问多个网页,使用 JavaScript 的window.open()方法,可模拟用户打开多个标签页,提升爬取效率。

python

'''使用Selenium打开多个标签页(实战常用)'''
from selenium import webdriver
from selenium.webdriver.edge.options import Options

# 配置Edge浏览器(新手可直接复用)
edge_options = Options()
edge_options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
driver = webdriver.Edge(options=edge_options)

# 打开百度首页(第一个标签页,作为主页面)
driver.get('https://www.baidu.com/')

# 执行JS代码,打开多个新标签页(_blank表示新标签页,不可修改)
driver.execute_script("window.open('https://www.bilibili.com/', '_blank');")
driver.execute_script("window.open('https://www.shuyishe.com/', '_blank');")
driver.execute_script("window.open('https://www.shuyishe.com/course', '_blank');")

# 暂停脚本,方便观察标签页效果
input('等待用户操作,按回车继续...')

# 关闭所有浏览器窗口(释放资源)
driver.quit()
(3)核心:获取渲染后的网页源码

这是 Selenium 最核心的优势!对于 JS 动态渲染的网页(如滚动加载、点击加载更多),requests只能获取到初始的 HTML 源码,无法获取到 JS 渲染后的内容,而 Selenium 可以轻松获取完整源码。

python

'''使用Selenium获取渲染后的网页源码(核心功能)'''
from selenium import webdriver
from selenium.webdriver.edge.options import Options

# 配置Edge浏览器
edge_options = Options()
edge_options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
# 可选:开启无头模式(不显示浏览器界面,适合服务器运行、批量爬取)
# edge_options.add_argument('--headless=new')
driver = webdriver.Edge(options=edge_options)

# 打开需要爬取的动态网页(示例:百度首页,可替换为动态网页URL)
driver.get('https://www.baidu.com')

# 获取渲染后的完整HTML源码(包含JS渲染的内容,核心代码)
html_source = driver.page_source
print("网页源码长度:", len(html_source))
print("前500字符:", html_source[:500])

# 关闭浏览器
driver.quit()

补充提示:开启无头模式(添加--headless=new参数)后,浏览器不会显示界面,脚本在后台运行,能节省系统资源,适合批量爬取或服务器部署,新手可先不开启,方便观察运行过程。

(4)补充:Selenium 常用操作拓展(实战必备)

除了基础操作,Selenium 的表单填写、元素点击、页面滚动等操作,是复杂爬虫(如登录、下拉加载)的核心,补充代码可直接复用,新手重点练习。

python

'''Selenium常用操作拓展(表单填写、点击、滚动,实战必备)'''
from selenium import webdriver
from selenium.webdriver.edge.options import Options
from selenium.webdriver import options
from selenium.webdriver.common.by import By
import time

# 配置浏览器
edge_options = Options()
edge_options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
driver = webdriver.Edge(options=edge_options)

# 1. 打开网页
driver.get('https://www.baidu.com/')
# 等待3秒,让页面完全加载(避免元素未渲染导致定位失败,新手必加)
time.sleep(3)

# 2. 定位元素并填写表单(示例:百度搜索框,实战高频)
# 方式1:通过ID定位(最常用、最高效,优先选择)
search_input = driver.find_element(By.ID, 'kw')
# 填写内容(可替换为任意搜索关键词)
search_input.send_keys('Python爬虫')

# 3. 定位按钮并点击(示例:百度搜索按钮)
search_btn = driver.find_element(By.ID, 'su')
search_btn.click()
time.sleep(3)  # 等待搜索结果加载,避免后续操作报错

# 4. 滚动页面(示例:滚动到页面底部,下拉加载常用)
# 执行JS代码实现滚动(通用模板,无需修改)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
time.sleep(2)

# 5. 获取元素文本(示例:获取搜索结果数量,提取数据常用)
result_text = driver.find_element(By.CLASS_NAME, 'nums_text').text
print("搜索结果:", result_text)

# 6. 后退、前进操作(模拟用户浏览行为,避坑常用)
driver.back()  # 后退到上一页(百度首页)
time.sleep(2)
driver.forward()  # 前进到下一页(搜索结果页)
time.sleep(2)

# 关闭浏览器
driver.quit()

更多推荐