跳转至

14.1 爬虫:Bilibili 搜索页(静态页面)分析

内容梗概

本课是爬虫实战的第一例,以 B 站(哔哩哔哩)关键词搜索结果页为例,演示静态页面的完整抓取流程。老师先强调了爬虫的法律风险(网络安全法、隐私数据不可碰),随后从零开始:建目录、初始化 pipenv 虚拟环境、安装 requests 和 BeautifulSoup4、用 requests.get 验证页面是静态的、用 CSS 选择器定位视频列表项,再循环提取标题、链接、播放量等信息。演示中途 B 站触发反爬机制,返回内容为空并提示 "request was rejected",老师顺势讲解了调试思路和 User-Agent 伪装,最后引出 robots.txt 的概念。

知识点详解

爬虫的法律与风险意识(约 00:00 - 00:53)

  • 学爬虫前必须先了解《网络安全法》:公民隐私数据(收货地址、手机号等)绝对不能爬。
  • 公开数据可以爬,但要有风险意识;技术本身要研究,但行为要有边界。

抓取思路(约 00:53 - 02:00)

  • 目标:B 站搜索"Python"后的视频列表,把每个视频"小块"的标题、播放量、日期、作者提取出来,循环拆解即可。
  • 分析页面:右键"检查"(审查元素),发现视频列表在一个 ul(含 video-list、clearfix 两个类)下,每个视频是一个 li 列表项。

环境搭建(约 02:00 - 12:00)

  • 命令行操作流程:mkdir bilibili → cd bilibili → pipenv install 初始化虚拟环境。
  • 加速技巧:pipenv install -i https://mirror.aliyun.com/pypi... 用 -i 参数指定阿里云镜像源(约 02:45)。
  • 目录下会生成 Pipfile 和 Pipfile.lock(约 07:08)。
  • code ./ 用 VSCode 打开当前目录(前提是安装 VSCode 时加入了环境变量)(约 08:06)。
  • pipenv shell 进入虚拟环境;不确定是否已进入时再执行一次,提示 already activated 即可确认(约 09:32)。
  • 安装两个包:pipenv install requests 和 pipenv install beautifulsoup4;from bs4 import BeautifulSoup 导入(约 11:30)。

验证页面是静态的(约 12:30 - 14:30)

  • 关键第一步:先用 requests.get(url) 抓取页面并 print,对比浏览器里看到的源代码是否一致。若 requests 拿到的 HTML 中能看到视频标题等内容,说明是静态页面,可继续用 BeautifulSoup 分析;若为空则是动态渲染(后一课处理)。

CSS 选择器定位元素(约 14:30 - 22:00)

  • 把抓到的 HTML 交给 BeautifulSoup 解析(html.parser)。
  • 用 CSS 选择器需调用 select() 方法(参考 BeautifulSoup 中文文档)。
  • 完整的层级选择器(约 17:00 - 19:00):#all-list > div.flow-loader > div.mixin-list > ul.video-list.clearfix > li.video-item.matrix
  • > 表示下一级子元素;
  • div.flow-loader 表示"div 元素且类为 flow-loader"(元素名与类名之间无空格);
  • ul.video-list.clearfix 表示同时拥有两个类的 ul(两个点连写)。
  • select 返回的是**列表**,print(len(...)) 验证应得到 20(一页 4 行 × 5 个 = 20 个视频)。
  • 选择器写法不唯一:若页面中没有其他同时具备这两个类的 li,可直接写 li.video-item.matrix 这样的短选择器;能选中前提下越简洁越好(约 21:00)。

被反爬封禁与调试思路(约 21:30 - 26:00)

  • 演示中 select 返回 0,打印 HTML 发现返回 "This request was rejected..." —— IP 被 B 站封了。
  • 调试思维:选择器选中数为 0 时有两种可能——① CSS 选择器写错了;② 请求拿到的 HTML 本身已经不对(被拦截/返回错误页)。要分别排查。
  • 每个网站都有反爬机制;短时间内大量非正常浏览器的请求相当于拒绝服务攻击,被封是正常保护行为。

User-Agent 伪装(约 27:00 - 32:00)

  • User-Agent(用户代理)告诉服务器"你用什么软件访问我"(浏览器类型)。
  • 获取方法:开发者工具 Network 标签页 → 找到第一个(获取页面的)HTTP GET 请求 → 查看 Request Headers 中的 user-agent 字段(约 28:20)。
  • requests 库默认的 UA 是 python-requests,服务器据此可直接拦截爬虫。
  • 伪装方法:定义 UA 字典,作为 requests.get(url, headers=...) 的第二个参数传入(约 30:00),服务器就会把请求当作浏览器接受。

循环提取字段(约 32:00 - 38:00)

  • 对每个 li 元素(变量 video)可以继续调用 .select() 在其内部查找子元素。
  • 提取标题:info div → headline clearfix 类 div → a 标签的文本。
  • 注意:select 即使只匹配一个元素也返回列表,要取下标 [0] 取出,否则报错(约 34:59)。
  • 取链接:a['href'] —— 用类似字典的方式获取标签属性(约 36:10)。
  • 取播放量等文本:.text 后需 .strip() 去掉前后的换行符和空格(约 36:59)。
  • 结果结构:初始化空字典存单条结果(title、url、播放量、弹幕数、上传时间、作者),最终得到 20 个字典组成的列表。

robots.txt(约 38:04 - 42:00)

  • 几乎所有网站都有 robots.txt,声明机器人/爬虫允许(Allow)和不允许(Disallow)访问的位置。
  • B 站的 robots.txt 中 Disallow 包含 search——本次演示爬的正是搜索页,属于不允许抓取的部分。
  • User-agent: * 表示规则对所有程序生效;网站不会封死全部爬虫(否则搜索引擎搜不到它),百度还会针对 Baiduspider、Googlebot、有道、搜狗等不同爬虫给出不同权限。
  • 爬了 Disallow 的内容,网站方可以追究责任——上课演示为技术交流,学生不要再爬。

示例与演示

  • 演示目标:爬取 B 站搜索"Python"的视频列表(标题、链接、播放量、弹幕数、上传时间、UP 主)。
  • 完整流程:pipenv 建环境 → 装 requests/bs4 → requests.get 验证静态 → BeautifulSoup + CSS 选择器选中 20 个 li → 循环提取字段存字典 → 打印结果列表。
  • 意外状况:演示中途被 B 站反爬封禁,后半段只能"动嘴皮子"讲解代码,但完整示例代码逻辑讲完,并补充了 UA 伪装这一应对手段。

重点与难点

  • 先验证静态/动态:requests 拿到的 HTML 与浏览器看到的一致,才能用 bs4 路线。
  • 调试思维:选择器结果为 0 时,先分清是选择器错误还是请求被拦截。
  • select() 永远返回列表,单元素也要取 [0]。
  • CSS 选择器的组合写法:> 子代、.类名 连写表示多类。
  • User-Agent 是最基础的反爬对抗手段,要会从 Network 面板复制浏览器 UA。
  • 法律底线:隐私数据不碰;爬前看 robots.txt;控制频率,避免给服务器造成负担。

关联内容

  • 前置知识:上一节的爬虫原理与自建网站抓取练习;10.x 章的 pip 包管理与国内镜像源、虚拟环境(pipenv);字符串方法(strip);字典与列表操作。
  • 后续:14.2 讲动态页面(Selenium),14.3 讲数据接口(Ajax/JSON),14.4 讲 Scrapy 框架——B 站例子的"封 IP 怎么办"在 14.4 末尾代理部分呼应。