Python爬虫基础入门:requests+BeautifulSoup完整实战教程(新手易懂)

一、前言

在数据获取、数据分析、个人项目开发等场景中,Python爬虫都是非常实用的技能。而requestsBeautifulSoup则是入门爬虫的黄金组合——requests负责简洁高效地发送网络请求、获取网页数据,BeautifulSoup负责轻松解析网页源码、提取所需有效信息,两者搭配上手快、门槛低,能满足大部分静态网页的爬取需求。本文将从环境搭建到实战案例,一步步带大家掌握这两个工具的使用,全程干货无冗余,适合零基础Python学习者入门。

二、前期环境准备

1. Python环境安装

首先确保你的电脑上已经安装了Python环境(推荐3.7及以上版本,兼容性更好),可以通过Python官网下载对应系统(Windows/Mac/Linux)的安装包,按照默认步骤安装即可,记得勾选“Add Python to PATH”(添加环境变量),方便后续在命令行中调用。

安装完成后,打开命令行(Windows按Win+R输入cmd,Mac打开终端),输入python --version(部分系统可能需要用python3 --version),如果能显示对应的Python版本号,说明安装成功。

2. 安装所需第三方库

本次教程需要两个核心第三方库:requests(发送网络请求)和beautifulsoup4(网页解析),另外还需要安装lxml(高效的解析器,让BeautifulSoup解析速度更快)。

打开命令行,输入以下命令一键安装(推荐使用国内镜像源加速,避免下载超时):

# 豆瓣镜像源(推荐,速度快)
pip install requests beautifulsoup4 lxml -i https://pypi.doubanio.com/simple/

# 若你的环境同时安装了Python2和Python3,可能需要用pip3代替pip
pip3 install requests beautifulsoup4 lxml -i https://pypi.doubanio.com/simple/

安装完成后,命令行无报错提示,即说明库安装成功,接下来就可以进入正式的爬虫学习环节。

三、核心库详解:requests(发送网络请求)

1. requests库核心功能

requests库是Python中最流行的HTTP请求库,相比Python内置的urllib,它的语法更简洁、使用更友好,无需手动构造复杂的请求头和处理编码问题,核心功能就是发送GETPOST等常见HTTP请求,获取网页的响应数据。

2. 最常用:GET请求发送

静态网页爬取中,GET请求是最常用的请求方式,用于从服务器获取指定资源(如网页源码、图片等)。

示例1:基础GET请求,获取网页源码

# 导入requests库
import requests

# 定义要爬取的网页URL(以百度首页为例,可直接访问)
target_url = "https://www.baidu.com"

# 发送GET请求,获取响应对象
response = requests.get(url=target_url)

# 打印响应结果,查看网页源码
print("=== 网页源码(部分)===")
# response.text:以文本形式返回网页源码
print(response.text[:500])  # 只打印前500个字符,避免输出过长

示例2:关键优化:添加请求头伪装

很多网站会通过User-Agent字段识别请求来源,若直接发送裸请求,可能会被判定为爬虫,返回403(禁止访问)错误。因此需要在请求中添加请求头(headers),伪装成浏览器访问。

import requests

target_url = "https://www.baidu.com"

# 构造请求头,核心是User-Agent(浏览器标识)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
}

# 发送带请求头的GET请求
response = requests.get(url=target_url, headers=headers)

# 验证请求是否成功(response.status_code:返回响应状态码,200表示成功)
if response.status_code == 200:
    print("请求成功!")
    print("=== 网页源码(部分)===")
    print(response.text[:500])
else:
    print(f"请求失败,状态码:{response.status_code}")

3. requests响应对象常用属性

在上面的示例中,我们用到了response.textresponse.status_code,这是requests响应对象最常用的两个属性,除此之外,还有两个实用属性:

  1. response.status_code:响应状态码,200=请求成功,404=页面不存在,403=禁止访问,500=服务器内部错误
  2. response.text:以文本形式返回响应内容,适用于网页源码、文本文件等
  3. response.content:以二进制形式返回响应内容,适用于下载图片、视频、音频等文件
  4. response.encoding:设置/获取响应内容的编码格式,解决中文乱码问题(如response.encoding = "utf-8"

四、核心库详解:BeautifulSoup(解析网页源码)

1. BeautifulSoup核心功能

BeautifulSoup(简称bs4)是一款强大的网页解析库,它能将复杂的HTML/XML源码转换成树形结构,提供了简单易用的API,让我们可以快速定位到目标标签,提取标签内的文本或属性值,无需手动编写复杂的正则表达式。

2. 初始化BeautifulSoup对象

使用BeautifulSoup的第一步,是将获取到的网页源码(response.text)和指定的解析器传入,创建一个解析对象。推荐使用lxml解析器(速度快、容错性强),也可以使用Python内置的html.parser(无需额外安装,适合简单场景)。

import requests
from bs4 import BeautifulSoup  # 从bs4中导入BeautifulSoup

# 1. 发送请求,获取网页源码
target_url = "https://www.baidu.com"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
}
response = requests.get(url=target_url, headers=headers)
response.encoding = "utf-8"  # 统一编码,避免中文乱码
html_source = response.text

# 2. 初始化BeautifulSoup对象,指定解析器为lxml
soup = BeautifulSoup(html_source, "lxml")

# 打印格式化后的源码(便于查看标签结构)
print("=== 格式化后的网页源码(部分)===")
print(soup.prettify()[:800])

3. 核心:提取数据的两种常用方式

BeautifulSoup提供了多种数据提取方式,其中最实用的是「标签直接选择」和「find()/find_all()方法查找」,下面分别讲解。

方式1:标签直接选择(简单快速,适合结构清晰的网页)

直接通过soup.标签名的方式,可以获取到网页中第一个匹配该标签的内容,适合提取唯一标签(如titlemeta等)。

# 基于上面初始化的soup对象继续操作

# 1. 获取<title>标签的内容
title_tag = soup.title
print("=== 标签对象信息 ===")
print("标签名:", title_tag.name)  # 输出标签名:title
print("标签完整内容:", title_tag)  # 输出完整标签:<title>百度一下,你就知道</title>
print("标签内文本:", title_tag.text)  # 输出标签内文本:百度一下,你就知道

# 2. 获取<a>标签(第一个匹配的a标签)
a_tag = soup.a
print("\n=== 第一个a标签信息 ===")
print("标签内文本:", a_tag.text)
print("标签的href属性值:", a_tag["href"])  # 提取标签的属性值,用["属性名"]

方式2:find()/find_all()方法(灵活强大,适合复杂场景)

当网页中有多个相同标签,或需要根据标签属性(如classid)精准定位时,find()find_all()是更好的选择,这也是实际爬虫中最常用的方法。

  • find():返回网页中第一个匹配条件的标签对象,无匹配结果返回None
  • find_all():返回网页中所有匹配条件的标签列表,无匹配结果返回空列表
# 基于上面初始化的soup对象继续操作

# 1. find():获取第一个class为"mnav"的a标签
a_tag_find = soup.find(name="a", attrs={"class": "mnav"})
print("=== find()获取的标签 ===")
print("文本内容:", a_tag_find.text)
print("href属性:", a_tag_find["href"])

# 简化写法:class属性可以直接用class_(避免与Python关键字class冲突)
a_tag_find_simple = soup.find("a", class_="mnav")
print("简化写法获取的文本:", a_tag_find_simple.text)

# 2. find_all():获取所有class为"mnav"的a标签
a_tags_find_all = soup.find_all("a", class_="mnav")
print("\n=== find_all()获取的标签列表 ===")
print("匹配到的标签数量:", len(a_tags_find_all))

# 遍历列表,提取每个标签的文本和href属性
for index, a_tag in enumerate(a_tags_find_all, 1):
    print(f"第{index}个标签:文本={a_tag.text},href={a_tag['href']}")

4. 提取标签内文本的补充技巧

提取标签内文本时,除了使用.text,还可以使用.get_text(),两者功能基本一致,.get_text()支持更多参数配置(如去除首尾空格、拼接多段文本等),在实际使用中更灵活。

# 提取文本并去除首尾空格、换行符
a_tag_text = soup.find("a", class_="mnav").get_text(strip=True)
print("去除空格后的文本:", a_tag_text)

五、完整实战案例:爬取静态博客文章列表

接下来我们结合requestsBeautifulSoup,做一个完整的实战案例——爬取一个简单的静态博客(以菜鸟教程的Python博客为例,无反爬,适合新手),提取文章标题、文章链接、发布时间。

1. 实战目标

爬取URL:https://www.runoob.com/python/python-blog.html
提取内容:每篇文章的「标题」、「跳转链接」、「发布时间」

2. 完整代码

import requests
from bs4 import BeautifulSoup

def crawl_blog_list():
    # 1. 配置请求信息
    target_url = "https://www.runoob.com/python/python-blog.html"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
    }
    
    try:
        # 2. 发送GET请求,获取网页源码
        response = requests.get(url=target_url, headers=headers)
        response.raise_for_status()  # 若请求失败(非200),抛出异常
        response.encoding = "utf-8"  # 统一编码,解决中文乱码
        html_source = response.text
        
        # 3. 初始化BeautifulSoup对象,解析网页源码
        soup = BeautifulSoup(html_source, "lxml")
        
        # 4. 定位目标标签,提取数据(先分析网页结构,找到文章列表对应的标签)
        blog_list = []
        # 找到所有文章项对应的标签(通过分析网页源码,确定class为"blog-list"下的li标签)
        article_items = soup.find("ul", class_="blog-list").find_all("li")
        
        # 5. 遍历所有文章项,提取所需信息
        for item in article_items:
            # 提取标题和链接
            title_tag = item.find("a")
            article_title = title_tag.get_text(strip=True)
            article_link = "https://www.runoob.com" + title_tag["href"]  # 补全完整URL
            
            # 提取发布时间
            time_tag = item.find("span", class_="date")
            article_time = time_tag.get_text(strip=True) if time_tag else "未知时间"
            
            # 封装数据
            blog_info = {
                "标题": article_title,
                "链接": article_link,
                "发布时间": article_time
            }
            blog_list.append(blog_info)
        
        # 6. 打印爬取结果
        print("=== 爬取完成,共获取{}篇文章 ===".format(len(blog_list)))
        for index, blog in enumerate(blog_list, 1):
            print(f"\n第{index}篇:")
            print(f"标题:{blog['标题']}")
            print(f"链接:{blog['链接']}")
            print(f"发布时间:{blog['发布时间']}")
    
    except Exception as e:
        print(f"爬取过程中出现错误:{e}")

if __name__ == "__main__":
    crawl_blog_list()

3. 运行结果说明

运行上述代码后,会在控制台输出爬取到的所有文章信息,包括标题、完整链接和发布时间。该案例的核心是「先分析网页结构」——通过浏览器的「开发者工具」(F12键)查看网页源码,确定目标数据所在的标签和属性,再用对应的方法提取,这也是爬虫开发的核心思路。

posted @ 2026-01-03 21:30  永动空间  阅读(38)  评论(0)    收藏  举报