开篇:什么是爬虫?

昨天有个刚学编程的朋友问我:"爬虫是什么?是不是像蜘蛛一样爬网页?"

这个问题其实问得挺好。爬虫的本质,就是自动化地获取网页数据。

想象一下,你想收集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 爬虫超详细讲解(零基础入门,适合小白)- 下篇》- 反爬策略与进阶实战

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐