使用 Python 实现一个简单的 web 爬虫(建议收藏)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言

在互联网时代,数据如同空气般无处不在。无论是商业决策、学术研究还是个人兴趣,获取并分析网络上的海量信息都是一项核心能力。使用 Python 实现一个简单的 web 爬虫,可以帮助开发者快速入门这一领域。本文将通过循序渐进的方式,带领读者从零开始构建一个基础但完整的爬虫程序,并深入浅出地解释关键知识点。


知识准备:理解 web 爬虫的基本原理

什么是 web 爬虫?

web 爬虫(Web Crawler)可以看作是互联网上的“数字蜘蛛”。它通过模拟人类浏览网页的行为,自动抓取目标网站的数据,如文本、图片、链接等。想象一下:当用户在浏览器中输入网址时,浏览器会向服务器发送请求,服务器返回网页内容,用户再通过浏览器解析并展示内容。而爬虫正是通过自动化这一过程,将数据直接提取到本地。

爬虫的三大核心步骤

  1. 发送请求:向目标网站发送 HTTP 请求,获取网页内容。
  2. 解析响应:将服务器返回的 HTML、JSON 等格式的内容解析为可处理的数据。
  3. 存储或处理数据:将提取的数据保存到本地文件、数据库,或进行进一步分析。

环境配置与工具选择

Python 的优势

Python 在 web 爬虫领域占据主导地位,主要得益于其简洁的语法和丰富的第三方库。以下是一些常用的工具:

工具名称功能描述
requests发送 HTTP 请求,获取网页内容
BeautifulSoup4解析 HTML 和 XML 文档,提取数据
Scrapy高级框架,适合大规模、复杂的爬虫项目
lxml高效的 HTML/XML 解析库

本文的工具选择

由于目标读者是编程初学者,我们将以 requestsBeautifulSoup4 为基础,构建一个轻量级爬虫。这两个库的学习成本较低,且功能足够覆盖基础场景。

pip install requests beautifulsoup4

第一步:发送 HTTP 请求

HTTP 请求的基础概念

当用户访问网页时,浏览器会向服务器发送一个 HTTP 请求(如 GET 请求),服务器则返回对应的网页内容。爬虫的核心任务之一,就是模拟这一过程。

示例:获取网页内容

import requests

url = "https://example.com"
response = requests.get(url)

if response.status_code == 200:
    print("请求成功!")
    print("响应内容:", response.text[:200])  # 打印前 200 字符
else:
    print(f"请求失败,状态码:{response.status_code}")

关键知识点:状态码与异常处理

  • 状态码:HTTP 响应的状态码(如 200 表示成功,404 表示页面不存在)是判断请求是否成功的重要依据。
  • 异常处理:网络请求可能因超时、连接中断等问题失败,因此需要使用 try-except 块包裹代码,避免程序崩溃。
try:
    response = requests.get(url, timeout=5)  # 设置超时时间为 5 秒
except requests.exceptions.RequestException as e:
    print(f"请求异常:{str(e)}")

第二步:解析 HTML 内容

解析 HTML 的核心工具:BeautifulSoup

BeautifulSoup 是 Python 中最易用的 HTML 解析库。它将复杂的 HTML 文档转换为可遍历的对象树,开发者可以通过标签名、属性等快速定位目标数据。

示例:提取网页中的所有链接

from bs4 import BeautifulSoup

soup = BeautifulSoup(response.text, 'html.parser')

all_links = soup.find_all('a')

for link in all_links:
    href = link.get('href')
    if href:
        print(href)

关键知识点:CSS 选择器与标签遍历

  • CSS 选择器:类似网页开发中的 CSS 语法,可以精准定位元素。例如,soup.select('div.content p') 表示选择所有在 div 标签内且类名为 contentp 标签。
  • 属性访问:通过 .text 获取标签内的文本,通过 .attrs 获取标签的所有属性。

形象比喻

可以把 HTML 解析比作“在迷宫中找钥匙”。BeautifulSoup 就像一个手持地图的向导,能根据你的指令(如标签名、类名)快速定位到目标位置。


第三步:存储与处理数据

数据存储的常见方式

爬取到的数据需要持久化存储,常用的方法包括:

  1. 文本文件:适合小规模数据,如 jsoncsv 格式。
  2. 数据库:如 SQLite、MySQL,适合需要频繁查询或处理大规模数据的场景。

示例:将链接保存为 CSV 文件

import csv

with open('links.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(['URL'])  # 写入表头
    for link in all_links:
        href = link.get('href')
        if href:
            writer.writerow([href])

进阶优化:让爬虫更健壮

遵守网站规则:robots.txt

在爬取任何网站前,必须先查看其 robots.txt 文件,了解允许或禁止爬取的路径。例如:

robots_url = "https://example.com/robots.txt"
robots_response = requests.get(robots_url)
print(robots_response.text)

防止被封禁:添加请求头与延迟

  • 模拟浏览器行为:通过设置 User-Agent 头,伪装成真实浏览器:
    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"
    }
    response = requests.get(url, headers=headers)
    
  • 添加延迟:使用 time.sleep() 控制请求频率,避免短时间内发送过多请求:
    import time
    time.sleep(2)  # 每次请求间隔 2 秒
    

完整代码示例:爬取豆瓣电影 Top 250

目标:提取电影名称、评分和简介

步骤 1:分析网页结构

访问 豆瓣电影 Top 250 ,观察 HTML 结构:

  • 电影名称位于 <span class="title"> 标签中。
  • 评分位于 <span class="rating_num"> 标签中。
  • 简介位于 <span class="inq"> 标签中(部分条目可能没有此标签)。

步骤 2:编写爬虫代码

import requests
from bs4 import BeautifulSoup
import csv
import time

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"
}

movies = []

for page in range(0, 250, 25):  # 步长为 25,对应 URL 中的 start 参数
    url = f"https://movie.douban.com/top250?start={page}"
    
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()  # 检查请求是否成功
        
        soup = BeautifulSoup(response.text, 'html.parser')
        items = soup.select('.item')  # 所有电影条目
        
        for item in items:
            title = item.select_one('.title').text.strip()
            rating = item.select_one('.rating_num').text.strip()
            inq = item.select_one('.inq')  # 可能不存在
            if inq:
                inq = inq.text.strip()
            else:
                inq = "无简介"
            
            movies.append({
                'title': title,
                'rating': rating,
                'intro': inq
            })
            
        print(f"第 {page//25 + 1} 页爬取完成")
        time.sleep(2)  # 避免请求过快
        
    except Exception as e:
        print(f"错误:{str(e)}")

with open('douban_movies.csv', 'w', newline='', encoding='utf-8-sig') as file:
    fieldnames = ['title', 'rating', 'intro']
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(movies)
    
print("数据保存完成!")

结论与扩展方向

总结

本文通过一个具体的案例,展示了如何使用 Python 实现一个简单的 web 爬虫。从发送请求到解析数据,再到存储和优化,每个步骤都紧扣编程初学者的需求。关键点包括:

  1. 基础工具requestsBeautifulSoup 是入门的黄金组合。
  2. 伦理与规范:尊重网站的 robots.txt,合理控制爬取频率。
  3. 代码健壮性:通过异常处理和延迟机制,提升程序的可靠性。

进阶方向

  • 动态网页爬取:使用 SeleniumPlaywright 处理 JavaScript 渲染的页面。
  • 分布式爬虫:利用 Scrapy 框架实现高效的大规模爬取。
  • 数据清洗与分析:结合 PandasNLTK 进行数据处理和自然语言处理。

通过不断实践和学习,开发者可以逐步掌握更复杂的爬虫技术,解锁互联网数据的价值。


希望这篇文章能为你的 Python 爬虫之旅提供清晰的起点!

最新发布