200字
用 Python 写你的第一个网络爬虫:从零开始,轻松抓取网页数据
2025-12-08
2025-12-08

爬虫2.png

  • 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手

用 Python 写你的第一个网络爬虫:从零开始,轻松抓取网页数据

前言:数据世界的“魔法”之门

在这个信息爆炸的时代,数据无处不在。从商品价格到新闻头条,从天气预报到社交媒体动态,海量数据蕴藏着巨大的价值。然而,这些数据往往散落在互联网的各个角落,以非结构化的网页形式呈现。如何高效、自动化地获取这些数据呢?答案就是——网络爬虫 (Web Crawler)

网络爬虫,顾名思义,就像一只勤劳的蜘蛛,在互联网这张巨大的“网”上爬行,根据你设定的规则,抓取并收集所需的信息。它能帮你省去大量手动复制粘贴的时间,将网页上的“非结构化”数据转化为你可以分析、利用的“结构化”数据。

本篇博客将作为你进入爬虫世界的第一站。我们将使用 Python 这一强大且易学的语言,手把手教你编写一个简单的网络爬虫,即使你是编程小白,也能轻松掌握数据抓取的乐趣。

准备工作:你的工具箱

在开始编写爬虫之前,我们需要确保你的开发环境已经准备就绪。

1. 安装 Python

如果你还没有安装 Python,请访问 Python 官方网站 下载并安装最新版本的 Python 3.x。安装时,请务必勾选“Add Python to PATH”选项,这样你就可以在命令行中直接运行 Python 了。

2. 学习基础 Python 知识 (如果需要)

虽然本教程尽量简化,但如果你对 Python 的变量、列表、循环和函数等基本概念有所了解,学习过程会更加顺畅。如果你是完全的编程新手,建议先花一些时间学习 Python 官方教程 的前几章。

3. 安装必要的第三方库

我们将使用两个核心的 Python 库来构建我们的爬虫:

  • requests: 用于发送 HTTP 请求,获取网页内容。
  • BeautifulSoup4: 用于解析 HTML 和 XML 文档,从中提取数据。

打开你的命令行工具 (Windows 用户是 cmd 或 PowerShell,macOS/Linux 用户是 Terminal),运行以下命令来安装它们:

pip install requests beautifulsoup4

如果安装成功,你就可以开始你的爬虫之旅了!

手把手教学:编写你的第一个爬虫

我们将以一个经典的爬虫练习网站 http://quotes.toscrape.com/ 为例,目标是抓取该网站上的所有名言及其作者。

步骤一:理解网页结构 (知己知彼,百战不殆)

在开始写代码之前,最重要的一步是分析目标网页的结构。我们需要知道我们想要的数据(名言和作者)在 HTML 代码中的位置和特征。

  1. 打开目标网站: 在你的浏览器中访问 http://quotes.toscrape.com/
  2. 打开开发者工具:
    • 大多数浏览器可以通过右键点击页面上的任何元素,然后选择“检查”或“检查元素”来打开开发者工具。
    • 或者使用快捷键:F12 (Windows/Linux) 或 Cmd + Option + I (macOS)。
  3. 定位目标数据:
    • 在开发者工具中,点击左上角的“选择元素”小图标 (一个鼠标箭头指向一个方块的图标)。
    • 将鼠标移动到页面上的一条名言上,例如“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”,你会看到对应的 HTML 代码被高亮显示。
    • 仔细观察,你会发现每条名言都包含在一个 <div class="quote"> 标签中。
    • 名言本身在 <span class="text" itemprop="text"> 标签里。
    • 作者在 <small class="author" itemprop="author"> 标签里。

通过这一步,我们明确了数据在 HTML 中的“身份信息”:它们都位于 div 标签中,并且带有特定的 class 属性。

步骤二:发送 HTTP 请求,获取网页内容

现在,我们使用 requests 库来模拟浏览器访问目标网页,获取其 HTML 内容。

import requests

# 目标网页的 URL
url = 'http://quotes.toscrape.com/'

try:
    # 发送 GET 请求,获取网页响应
    response = requests.get(url)

    # 检查 HTTP 状态码,200 表示成功
    if response.status_code == 200:
        print("网页请求成功!")
        # 获取网页的 HTML 内容
        html_content = response.text
        # print(html_content[:500]) # 打印前500个字符,查看是否成功获取
    else:
        print(f"网页请求失败,状态码:{response.status_code}")

except requests.exceptions.RequestException as e:
    print(f"请求发生错误: {e}")

代码解释:

  • import requests: 导入 requests 库。
  • url = 'http://quotes.toscrape.com/': 定义我们要抓取的网页地址。
  • requests.get(url): 这是最核心的部分,它向指定的 URL 发送一个 HTTP GET 请求,并返回一个 Response 对象。
  • response.status_code: 检查请求的状态码。200 表示请求成功,服务器已返回网页内容。
  • response.text: 获取响应的文本内容,这就是我们需要的 HTML 源代码。
  • try...except: 这是一个错误处理机制,用于捕获在网络请求过程中可能发生的异常(例如网络断开)。

运行这段代码,如果看到“网页请求成功!”的输出,说明你已经成功迈出了第一步!

步骤三:解析网页内容

获取到 HTML 内容后,它还是一大串杂乱的字符串。我们需要一个工具来“理解”这些字符串,将它们组织成一个易于操作的结构。这时,BeautifulSoup 就派上用场了。

from bs4 import BeautifulSoup
import requests

url = 'http://quotes.toscrape.com/'
response = requests.get(url)
html_content = response.text

# 使用 BeautifulSoup 解析 HTML 内容
# 'html.parser' 是 Python 内置的解析器
soup = BeautifulSoup(html_content, 'html.parser')

print("网页解析成功!")
# print(soup.prettify()[:1000]) # 打印格式化后的HTML前1000字符,方便查看结构

代码解释:

  • from bs4 import BeautifulSoup: 从 bs4 库中导入 BeautifulSoup 类。
  • BeautifulSoup(html_content, 'html.parser'): 创建一个 BeautifulSoup 对象。它接收两个参数:
    • html_content: 我们从 requests 获取到的 HTML 字符串。
    • 'html.parser': 指定使用 Python 内置的 HTML 解析器。

现在,soup 对象就包含了整个网页的结构,我们可以像操作树形结构一样,方便地查找和提取其中的元素。

步骤四:提取所需数据

这是爬虫最核心的部分。根据我们在步骤一中对网页结构的分析,我们将使用 BeautifulSoup 的方法来定位并提取名言和作者。

from bs4 import BeautifulSoup
import requests

url = 'http://quotes.toscrape.com/'
response = requests.get(url)
html_content = response.text
soup = BeautifulSoup(html_content, 'html.parser')

# 查找所有 class 为 'quote' 的 div 标签
# 每个这样的 div 标签都包含一条名言和作者信息
quotes = soup.find_all('div', class_='quote')

# 创建一个列表来存储所有提取到的数据
all_quotes_data = []

# 遍历每一个 quote 标签,提取名言和作者
for quote_tag in quotes:
    # 提取名言文本
    text = quote_tag.find('span', class_='text').get_text()

    # 提取作者
    author = quote_tag.find('small', class_='author').get_text()

    # 提取标签(可选)
    # tags_elements = quote_tag.find('div', class_='tags').find_all('a', class_='tag')
    # tags = [tag.get_text() for tag_element in tags_elements]

    # 将提取到的数据存储为字典
    quote_data = {
        'text': text,
        'author': author,
        # 'tags': tags
    }
    all_quotes_data.append(quote_data)

# 打印提取到的数据
for data in all_quotes_data:
    print(f"名言: {data['text']}")
    print(f"作者: {data['author']}")
    print("-" * 30)

print(f"\n成功提取了 {len(all_quotes_data)} 条名言。")

代码解释:

  • soup.find_all('div', class_='quote'): 这是 BeautifulSoup 最常用的方法之一。
    • 它会在整个 soup 对象中查找所有符合条件的标签。
    • 'div': 指定要查找的标签名是 div
    • class_='quote': 指定标签的 class 属性必须是 'quote' (注意 class 是 Python 关键字,所以这里用 class_ 表示)。
    • 它会返回一个列表,其中包含了所有匹配的 div 标签对象。
  • for quote_tag in quotes:: 遍历我们找到的每一个名言容器。
  • quote_tag.find('span', class_='text'): 在当前的 quote_tag (也就是一个 <div class="quote"> 标签内部) 中,继续查找 span 标签,且 class'text'find() 方法只会返回第一个匹配的元素。
  • .get_text(): 提取标签内部的纯文本内容,去除所有 HTML 标签。
  • all_quotes_data.append(quote_data): 将每条名言和作者信息存储为一个字典,然后添加到 all_quotes_data 列表中。

运行这段代码,你将看到所有名言和作者清晰地打印在控制台上。

步骤五:保存数据

仅仅在控制台打印数据是不够的,通常我们需要将数据保存到文件中,以便后续分析或使用。这里我们演示如何将数据保存为 CSV (Comma Separated Values) 文件,这是一种常见的表格数据格式,可以用 Excel 或其他数据分析工具打开。

import csv
from bs4 import BeautifulSoup
import requests

url = 'http://quotes.toscrape.com/'
response = requests.get(url)
html_content = response.text
soup = BeautifulSoup(html_content, 'html.parser')

quotes = soup.find_all('div', class_='quote')
all_quotes_data = []

for quote_tag in quotes:
    text = quote_tag.find('span', class_='text').get_text()
    author = quote_tag.find('small', class_='author').get_text()
    all_quotes_data.append({'text': text, 'author': author})

# 定义保存的文件名
filename = 'quotes.csv'

# 使用 csv 模块将数据写入 CSV 文件
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
    # 定义 CSV 文件的列名(表头)
    fieldnames = ['text', 'author']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    # 写入表头
    writer.writeheader()
    # 写入所有数据
    writer.writerows(all_quotes_data)

print(f"\n数据已成功保存到 {filename} 文件中。")

代码解释:

  • import csv: 导入 Python 内置的 csv 模块。
  • with open(filename, 'w', newline='', encoding='utf-8') as csvfile::
    • open() 函数用于打开文件。
    • filename: 我们指定的文件名 quotes.csv
    • 'w': 以写入模式打开文件(如果文件不存在则创建,如果存在则清空内容)。
    • newline='': 这是 csv 模块推荐的参数,可以防止在 Windows 上写入空行。
    • encoding='utf-8': 指定文件编码为 UTF-8,以支持中文字符或其他特殊字符。
    • with 语句确保文件在使用完毕后自动关闭,即使发生错误。
  • fieldnames = ['text', 'author']: 定义 CSV 文件的列名,这与我们字典的键相对应。
  • writer = csv.DictWriter(csvfile, fieldnames=fieldnames): 创建一个 DictWriter 对象,它允许我们以字典的形式写入数据。
  • writer.writeheader(): 写入 CSV 文件的表头。
  • writer.writerows(all_quotes_data): 写入 all_quotes_data 列表中的所有字典数据。

运行这段代码后,你的项目目录下会生成一个 quotes.csv 文件,用 Excel 或文本编辑器打开,你就能看到整齐排列的名言和作者数据了!

完整代码示例

将以上所有步骤整合在一起,这就是你的第一个网络爬虫的完整代码:

import requests
from bs4 import BeautifulSoup
import csv

def scrape_quotes(url):
    """
    抓取指定URL的名言和作者信息。
    """
    all_quotes_data = []
    try:
        response = requests.get(url)
        if response.status_code == 200:
            print(f"成功访问 {url}")
            html_content = response.text
            soup = BeautifulSoup(html_content, 'html.parser')

            quotes = soup.find_all('div', class_='quote')
            for quote_tag in quotes:
                text = quote_tag.find('span', class_='text').get_text()
                author = quote_tag.find('small', class_='author').get_text()
                all_quotes_data.append({'text': text, 'author': author})
            print(f"成功提取 {len(all_quotes_data)} 条名言。")
        else:
            print(f"访问 {url} 失败,状态码:{response.status_code}")
    except requests.exceptions.RequestException as e:
        print(f"请求 {url} 发生错误: {e}")
    return all_quotes_data

def save_to_csv(data, filename='quotes.csv'):
    """
    将数据保存到CSV文件。
    """
    if not data:
        print("没有数据可保存。")
        return

    fieldnames = ['text', 'author']
    try:
        with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(data)
        print(f"数据已成功保存到 {filename}。")
    except IOError as e:
        print(f"保存文件时发生错误: {e}")

if __name__ == "__main__":
    target_url = 'http://quotes.toscrape.com/'
    quotes_data = scrape_quotes(target_url)
    save_to_csv(quotes_data, 'my_first_quotes.csv')

常见问题与解决方案

在你的爬虫之路上,可能会遇到一些挑战。以下是一些常见问题及其初步解决方案:

1. 反爬机制 (Anti-Scraping)

许多网站不希望自己的数据被轻易抓取,因此会设置各种反爬机制。

  • User-Agent 检测: 网站会检查你的请求头中的 User-Agent 字段,判断你是否是正常的浏览器访问。默认情况下 requestsUser-Agent 比较特殊。

    • 解决方案:requests.get() 中添加 headers 参数,模拟浏览器。
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    
  • IP 限制: 频繁访问同一网站可能导致你的 IP 被暂时或永久封禁。

    • 解决方案: 减慢请求频率 (添加 time.sleep() 延迟),或者使用 IP 代理池 (更高级)。
  • robots.txt: 这是一个网站告诉爬虫哪些页面可以抓取,哪些不可以的文件。

    • 解决方案: 爬虫开发者应自觉遵守网站的 robots.txt 规则,这是爬虫伦理的基本要求。
  • 验证码、JavaScript 动态加载: 某些内容需要用户交互或 JavaScript 渲染才能显示。

    • 解决方案: 对于验证码,可能需要人工识别或使用 OCR 服务;对于 JavaScript 动态加载,可能需要使用 Selenium 等自动化浏览器工具 (超出了本入门教程范围)。

重要提示: 进行网络爬虫时,请务必遵守法律法规和网站的使用条款,尊重网站的 robots.txt 协议,并避免对目标网站造成过大压力。

2. 编码问题 (Encoding Issues)

有时获取到的网页内容显示乱码。

  • 解决方案: requests 库通常会自动检测编码,但有时会出错。你可以手动指定或纠正编码:
    response.encoding = 'utf-8' # 尝试指定为 UTF-8
    # 或者让 requests 自动猜测
    # response.encoding = response.apparent_encoding
    html_content = response.text
    

3. 网络请求错误

网络不稳定或目标服务器问题可能导致请求失败。

  • 解决方案: 使用 try-except 块来捕获 requests.exceptions.RequestException 及其子类,如 ConnectionError (连接错误)、Timeout (超时)。
    import requests
    import time # 用于添加延迟
    
    try:
        response = requests.get(url, timeout=5) # 设置超时时间
        # ... 处理响应
    except requests.exceptions.Timeout:
        print("请求超时")
    except requests.exceptions.ConnectionError:
        print("连接错误,请检查网络或URL")
    except requests.exceptions.RequestException as e:
        print(f"发生未知请求错误: {e}")
    time.sleep(1) # 请求之间暂停1秒
    

总结与进阶

恭喜你!你已经成功编写了你的第一个 Python 网络爬虫。这只是冰山一角,爬虫的世界广阔而有趣。

你学到了什么?

  • 如何使用 requests 库发送 HTTP 请求并获取网页内容。
  • 如何使用 BeautifulSoup 库解析 HTML,定位并提取所需数据。
  • 如何将抓取到的数据保存到 CSV 文件。
  • 了解了基本的爬虫伦理和常见问题的初步解决方案。

接下来可以探索什么?

  1. 多页爬取 (Pagination): 许多网站都有分页,你需要找到下一页的链接或规律,循环抓取所有页面的数据。
  2. 数据清洗与处理: 抓取到的数据可能需要进一步清洗、格式化才能使用。
  3. 更复杂的数据结构: 学习如何抓取嵌套的、更复杂的数据。
  4. 异步爬虫: 对于需要抓取大量页面的场景,异步爬虫可以大大提高效率。
  5. 更强大的爬虫框架: 当项目变得复杂时,可以考虑使用像 Scrapy 这样的专业爬虫框架,它提供了更完善的结构和功能。
  6. API 抓取: 许多网站提供 API 接口,通过 API 获取数据通常比解析 HTML 更稳定高效。

希望这篇博客能为你打开数据抓取的大门,祝你在探索数据世界的旅途中玩得开心!

  • 希望对初学者有帮助;致力于办公自动化的小小程序员一枚
  • 希望能得到大家的【❤️一个免费关注❤️】感谢!
  • 求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍
  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏
  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏
  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏
用 Python 写你的第一个网络爬虫:从零开始,轻松抓取网页数据
作者
一晌小贪欢
发表于
2025-12-08
License
CC BY-NC-SA 4.0

评论