零基础Python爬虫入门:从HTTP协议到 requests + BeautifulSoup 实战

📌 适合人群:完全没有爬虫经验的初学者 🛠️ 涉及工具:Python 3、requests、BeautifulSoup4、浏览器开发者工具 🎯 学习目标:看懂网页本质 → 发送请求 → 解析数据 → 批量爬取


一、爬虫到底是什么?先看大图景

在写任何代码之前,先建立整体认知。所谓网络爬虫 ,本质上是模拟浏览器向服务器发送请求,获取网页内容,然后从中提取我们想要的数据。

整个流程可以拆成三步(这也是几乎所有爬虫的灵魂框架):

plain

复制代码
① 获取网页内容 ------ 向服务器要数据,服务器把网页"源代码"返回给我们
        ↓
② 解析网页内容 ------ 从一大堆 HTML 代码里,精准找到想要的数据
        ↓
③ 存储 / 分析数据 ------ 存成表格(Excel/CSV)、做数据分析、画可视化图表

对应到你的学习笔记,就是:获取 → 解析 → 存储分析。


二、前置知识一:HTTP协议(爬虫的地基)

2.1 什么是HTTP

HTTP(Hypertext Transfer Protocol,超文本传输协议 )是客户端(浏览器)和服务器之间的请求-响应协议。

你每打开一个网页,背后都在发生一次对话:

浏览器:"服务器你好,我要 /movie/top250 这个页面的内容" 服务器:"好的,给你(返回网页代码)"

爬虫的第一步,就是用代码代替浏览器去完成这个对话。

2.2 HTTP请求的结构

一个HTTP请求由三部分组成:

(1)请求行
复制代码
POST /user/info?new_user=true HTTP/1.1
  • POST:请求方法(常见的还有 GET)

  • /user/info?new_user=true:资源路径 + 查询参数

  • HTTP/1.1:协议版本(还有 0.9、1.0、2.0 等)

(2)请求头(Headers)
复制代码
Host: www.example.com
User-Agent: curl/7.77.0
Accept: */*

请求头是关于请求的附加信息 。其中 User-Agent(用户代理)告诉服务器"我是谁"。

⚠️ 关键点来了 :如果不加 User-Agent,服务器看到的就是一个"裸奔的程序",很可能直接拒绝你(比如豆瓣会返回 418 错误 )。解决办法是伪装成浏览器:

复制代码
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}
(3)请求体(Body)

POST请求通常带有数据(比如登录时提交账号密码),格式常见为 JSON:

复制代码
{
    "username": "zhangsan",
    "email": "zhangsan@example.com"
}

2.3 GET 和 POST 的区别(面试高频)

表格

对比项 GET POST
用途 获取数据 创建/提交数据
场景 浏览网页、翻页 提交账号、注册表单
参数位置 拼在URL里(?key=value) 放在请求体里
爬虫常用度 ⭐⭐⭐⭐⭐ ⭐⭐

plain

复制代码
# GET请求:参数直接写在URL上
www.douban.com/movie/top250?start=75&filter=unwatched
                              └─────┬─────┘
                              问号后面就是查询参数

2.4 HTTP响应的结构

服务器返回的响应同样由三部分组成:

复制代码
HTTP/1.1 200 OK                     ← 状态行
Date: Fri, 27 Jan 2023 02:10:48 GMT
Content-Type: text/html; charset=utf-8   ← 响应头

<!DOCTYPE html>
<html>
    <head><title>首页</title></head>
    <body><h1>Hello World</h1></body>
</html>                             ← 响应体(真正的网页内容)
  • 状态行:协议版本 + 状态码 + 状态消息

  • 响应头 :比如 Content-Type 告诉我们返回内容的格式是 text/html

  • 响应体:就是我们要爬的 HTML 源码

2.5 常见状态码(务必背下来)

状态码 含义
✅ 200 OK 请求成功,最理想
↪️ 301 Moved Permanently 资源永久移动到新地址
⚠️ 400 Bad Request 客户端请求不能被服务器理解
⚠️ 401 Unauthorized 请求未经授权
⚠️ 403 Forbidden 服务器拒绝提供服务(反爬常见)
⚠️ 404 Not Found 请求的资源不存在
❌ 500 Internal Server Error 服务器内部错误
❌ 503 Server Unavailable 服务器当前无法处理请求

在代码中用 response.status_code 查看,用 response.ok 快速判断是否成功(2xx 返回 True)。


三、前置知识二:HTML网页结构(解析的地图)

3.1 网页三大件

技术 作用
HTML 定义网页的结构和信息(骨架)
CSS 定义网页的样式(皮肤)
JavaScript 定义网页的行为和交互逻辑(肌肉)

爬虫主要和 HTML 打交道。

3.2 HTML的基本结构

复制代码
<html>
    <body>
        <h1>这是一个标题</h1>
        <p>这是一个段落</p>
    </body>
</html>

HTML 由一对一对的标签(tag) 组成:<标签名> 开始,</标签名> 结束。<h1> 和 <p> 是兄弟标签(同级关系)。

3.3 常用标签速查

标签 含义
<h1> ~ <h6> 标题(1最大,6最小)
<p> 段落
<br> 换行
<i> 斜体
<u> 下划线
<a> 链接
<div> 区块容器(最常用,页面布局)
<ul> / <ol> / <li> 无序列表 / 有序列表 / 列表项
<span> 行内容器(常用来包裹小片段文字)
<b> / <strong> 加粗
<table> / <tr> / <td> 表格 / 表格行(table row)/ 单元格
<thead> / <tbody> 表头区 / 表体区

以表格为例,完整结构长这样:

复制代码
<table>
    <thead>
        <tr>
            <td>表头1</td>
            <td>表头2</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>111</td>
            <td>222</td>
        </tr>
        <tr>
            <td>333</td>
            <td>444</td>
        </tr>
    </tbody>
</table>

💡 爬虫提数据的核心思路:数据总是藏在某个标签里,我们要做的就是在 HTML 中找到那个标签,把它"抠"出来。


四、实战第一步:requests库获取网页内容

4.1 安装与导入

复制代码
pip install requests

import requests

4.2 第一个爬虫:获取books.toscrape.com首页

复制代码
import requests

response = requests.get("http://books.toscrape.com/")

if response.ok:
    print(response.text)
else:
    print("请求失败")

到这一步,你就已经完成了爬虫流程里的第一步------拿到了网页的源代码(一大串HTML文本)。

4.3 response对象的常用属性

复制代码
response = requests.get("http://books.toscrape.com/")

print(response)                # 打印响应对象本身
print(response.status_code)    # 状态码,200表示成功
print(response.text)           # 响应体内容(字符串形式)
print(response.headers)        # 响应头
print(response.ok)             # 是否成功(2xx → True)

4.4 反爬入门:伪装User-Agent

直接爬豆瓣 Top250 会遇到 418("我是茶壶"),说明服务器识破了你:

复制代码
import requests

response = requests.get("https://movie.douban.com/top250")
print(response)   # <Response [418]> 被识破了!

加 headers 伪装成浏览器:

复制代码
import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

response = requests.get("https://movie.douban.com/top250", headers=headers)
print(response.status_code)   # 200,成功!
print(response.text)

🔑 记忆口诀:先不加 headers 试试,不行就加 User-Agent;还不行就检查 Cookie、Referer 等。


五、实战第二步:BeautifulSoup解析网页内容

获取到的 response.text 是一大坨字符串,肉眼找数据是不可能的。我们用 BeautifulSoup 把它变成一个结构化、可查询的对象。

5.1 安装与导入

复制代码
pip install beautifulsoup4

from bs4 import BeautifulSoup
import requests

5.2 三步走:请求 → 做汤 → 找料

复制代码
from bs4 import BeautifulSoup
import requests

# 1. 请求网页
content = requests.get("http://books.toscrape.com/").text

# 2. 把字符串"熬成汤"(解析成结构化对象)
soup = BeautifulSoup(content, "html.parser")

经过 BeautifulSoup 处理后,得到的 soup 对象就拥有了非常多的方法和属性,可以像查字典一样查找标签。

5.3 findAll():批量查找标签

复制代码
# 按标签名查找:找到所有 <p> 标签
all_prices = soup.findAll("p", attrs={"class": "price_color"})

for price in all_prices:
    print(price.string[2:])

运行结果:

复制代码
51.77
53.74
50.10
47.82
54.23
...

逐行拆解这个方法:

  • soup.findAll("p", attrs={"class": "price_color"}):找到所有 class 为 price_color 的 <p> 标签,返回一个列表

  • price.string:取标签里的文本内容(如 £51.77)

  • [2:]:字符串切片 ,去掉前2个字符 £,留下纯数字

🔑 注意区分:

  • find() → 找第一个,返回单个对象

  • findAll() → 找所有,返回列表

5.4 案例:提取书名

在 books.toscrape 上,书名藏在 <h3> 标签里的 <a> 标签中:

复制代码
<h3>
    <a href="catalogue/a-light-in-the-attic_1000/index.html" title="A Light in the Attic">A Light in the ...</a>
</h3>

对应代码:

复制代码
all_titles = soup.findAll("h3")

for title in all_titles:
    all_links = title.findAll("a")
    for link in all_links:
        print(link.string)   # 通过string属性拿到标签内的文本

输出:

复制代码
A Light in the ...
Tipping the Velvet
Soumission
Sharp Objects
Sapiens: A Brief History ...
...

💡 嵌套查找 是很常用的技巧:先找大容器(h3),再在容器内部继续找小标签(a)。

5.5 案例:爬豆瓣Top250电影名

先在浏览器里右键 → 检查(审查元素),找到标题对应的标签:

复制代码
<span class="title">三傻大闹宝莱坞</span>

对应代码:

复制代码
import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

response = requests.get("https://movie.douban.com/top250", headers=headers)
html = response.text

soup = BeautifulSoup(html, "html.parser")
all_titles = soup.findAll("span", attrs={"class": "title"})

for title in all_titles:
    title_string = title.string
    # 豆瓣每部电影有中文名和英文名两个title,用"/"判断过滤
    if "/" not in title_string:
        print(title_string)

这里用了一个细节技巧:if "/" not in title_string------因为每部电影的中文名和英文名都是 class="title",通过是否包含 / 来只保留中文名。


六、实战第三步:翻页爬取全部250部电影

豆瓣Top250每页只有25部,URL规律是:

复制代码
第1页: https://movie.douban.com/top250?start=0
第2页: https://movie.douban.com/top250?start=25
第3页: https://movie.douban.com/top250?start=50
...

规律是 start 每次加 25。用 range(0, 250, 25) 生成翻页参数:

复制代码
for start_num in range(0, 250, 25):
    print(start_num)
# 输出: 0, 25, 50, 75, 100, 125, 150, 175, 200, 225

完整代码:

复制代码
import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

for start_num in range(0, 250, 25):
    response = requests.get(
        f"https://movie.douban.com/top250?start={start_num}",
        headers=headers
    )
    html = response.text
    soup = BeautifulSoup(html, "html.parser")
    all_titles = soup.findAll("span", attrs={"class": "title"})

    for title in all_titles:
        title_string = title.string
        if "/" not in title_string:
            print(title_string)

🛡️ 善意提醒 :实际爬取时建议在循环中加入 time.sleep(1~3) 降低请求频率,避免对目标网站造成压力。


七、爬虫法律与道德红线(重要!)

笔记里总结的三条底线,必须刻进DNA:

  1. 不要爬取公民隐私数据

  2. 要尊重版权保护的内容

  3. 国家事务、国防建设相关网站绝对不碰

技术层面的注意点:

  • ⚡ 请求频率不能过高 ,否则无异于 DDoS 攻击(通过给服务器发送海量高频请求,让网站资源被耗尽,无法服务其他正常用户)

  • 🚧 网站如果做出明显的反爬限制 (如有些内容登录后可看),尊重限制机制,不要强行突破

  • 📄 爬取前查看网站的 robots.txt 文件 (如 www.example.com/robots.txt),它声明了允许/禁止爬取的网页路径范围


八、完整知识图谱(复习用)

复制代码
┌─────────────────────────────────────────┐
│              爬虫三步走                   │
├──────────────┬──────────────────────────┤
│ ① 获取网页内容 │ requests库               │
│              │  · requests.get(网址)     │
│              │  · response.status_code   │
│              │  · response.text / .ok    │
│              │  · headers伪装User-Agent  │
├──────────────┼──────────────────────────┤
│ ② 解析网页内容 │ BeautifulSoup库          │
│              │  · BeautifulSoup(text,     │
│              │    "html.parser")         │
│              │  · find() / findAll()     │
│              │  · attrs={"class": "..."} │
│              │  · .string 取文本          │
│              │  · 切片 [2:] 清洗数据      │
├──────────────┼──────────────────────────┤
│ ③ 存储/分析   │ 存CSV/Excel → 数据分析    │
│              │ → 可视化图表              │
└──────────────┴──────────────────────────┘

底层支撑:
  HTTP协议(请求行/请求头/请求体;状态行/响应头/响应体)
  HTML结构(标签、class属性、层级与兄弟关系)

最小可运行模板(背下来,90%的简单爬虫都是它的变体):

复制代码
import requests
from bs4 import BeautifulSoup

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
url = "目标网址"

response = requests.get(url, headers=headers)
if response.ok:
    soup = BeautifulSoup(response.text, "html.parser")
    items = soup.findAll("标签名", attrs={"class": "目标class"})
    for item in items:
        print(item.string)
else:
    print("请求失败:", response.status_code)

九、常见问题速查(FAQ)

Q1:为什么返回418 / 403? 服务器识别出你是爬虫。加上 headers 伪装 User-Agent,必要时补充 Cookie、Referer。

Q2:为什么 findAll 返回空列表? 检查 class 名是否写对(浏览器里右键检查确认);注意有的class有多个值,要用完整字符串匹配。

Q3:price.string 报错 NoneType? 说明该标签内嵌套了子标签,string 无法确定取哪个。改用 .get_text()。

Q4:中文乱码? 尝试 response.encoding = response.apparent_encoding 后再取 .text。


十、写在最后

零基础学爬虫,其实就两条主线:

网络线 :理解HTTP请求-响应 → 用requests发请求 解析线:理解HTML标签结构 → 用BeautifulSoup查标签

把这两条线打通,再加一个 for 循环实现翻页,你就已经具备了爬取绝大多数静态网页的能力。下一步可以进阶学习:数据存储(CSV/Excel/MySQL)、XPath、正则表达式、Selenium动态页面爬取、Scrapy框架。

如果觉得本文对你有帮助,欢迎点赞收藏,复习时直接对照第八节的图谱过一遍即可。评论区欢迎交流爬取中遇到的问题,下期预告:《Python爬虫进阶:数据存储与清洗实战》。

相关推荐
“AI国潮设计-小江”1 小时前
【SDXL实战】用AI生成“财神爷蛋糕×英歌舞人物”潮汕国潮甜品IP,附Prompt与批量生成思路
开发语言·人工智能·python·aigc
DD云验证1 小时前
DD云验证,免费网络验证系统
服务器·python·易语言·网络验证·卡密验证
茶栀(*´I`*)1 小时前
【Python数据分析利器】Pandas从入门到实战:核心数据结构DataFrame与Series全解析
python·数据分析·pandas
码云数智-大飞1 小时前
新手写 Python 代码,如何规范命名、减少 Bug
开发语言·python·php
天天被压力2 小时前
【别再到处找免费股票数据API了:官方204个接口,32篇一次讲透 #06】Python实时行情总报错?五档盘口+逐笔一次跑通
java·人工智能·python
智能RPA2 小时前
农业与矿业行业智能体自动化平台对比评测(计量与巡检场景)
运维·人工智能·python·自动化·agent·rpa
溪语流沙2 小时前
Django + Vue电商项目第005讲:后端骨架|Django初始化、配置分层与DRF接入
vue.js·后端·python·django
代码方舟2 小时前
Python数据工程:利用天远全能消金报告优化消费金融合规体验
人工智能·python
TomEval2 小时前
【测AI】第05篇:Python 爬虫进阶 —— 动态页面爬取与 Scrapy 框架
人工智能·爬虫·python·scrapy·自动化