python爬虫入门

介绍

传统爬虫的工作流程通常始于编写代码来定义采集规则,随后程序会向目标网页发送请求以获取原始数据,接着对返回的页面内容进行解析并提取所需信息,若存在多页数据则需自动处理分页逻辑以遍历所有目标页面,最终将清洗整理后的结构化数据存储到数据库中,从而完成从网页到数据的全自动化采集过程。

  • 发送 HTTP 请求获取网页资源。

  • 解析 HTML 内容提取有用信息。

  • 将数据存储到本地或数据库。

  • 处理提取到的链接加入待抓取队列。

关于解析

程序会先用解析器把 HTML 构建成一棵文档树,比如 div,a 这些标签会形成层级关系;然后再通过 CSS 选择器、XPath 或正则表达式,从这棵树里定位目标节点,取出其中的文本、链接、图片地址、属性值等有用信息。

常见方式大致有三类:

方式 适合做什么 注意点
CSS 选择器 按 class、id、标签、属性快速定位元素 写法短、直观,适合结构稳定的页面
XPath 按层级、父节点、文本内容精确定位 表达能力更强,但语法稍复杂
正则表达式 从纯文本里抠手机号、编号、JSON 片段等 不适合直接解析完整 HTML,容易因页面变化失效

DOM 树

写爬虫时,很多人会被 DOM 树吓到,觉得它属于前端知识。其实对爬虫来说,你不需要掌握 DOM API、事件冒泡、浏览器渲染机制,也不需要理解 JavaScript 如何操作页面。你只需要学会一件事:把 HTML 看成一棵有层级关系的树,然后顺着树找到目标数据。

HTML 被解析后,会形成一棵文档树。每个标签都是一个节点,标签之间通过嵌套形成父子、兄弟、祖先、后代关系。属性挂在标签上,文本则藏在标签内部。理解了这些,你写 CSS 选择器或 XPath 时就不会只是"照着抄",而是能真正判断该往哪里定位。

复制代码
<div class="news-list">
  <article class="news-item">
    <h2>
      <a href="/news/123">标题</a>
    </h2>
    <span class="time">2026-10-13</span>
  </article>
</div>

你需要知道:

  • div 是外层容器

  • article 是 div 的子节点

  • h2 和 span 是同级

  • a 是 h2 的子节点

  • 文本 "标题" 属于 a

  • href="/news/123" 是 a 的属性

CSS Selector

CSS Selector 原本是前端用来给页面元素设置样式的,但在爬虫里,它几乎是最直观的 HTML 定位方式。你不需要写复杂的语法,只要像读句子一样,把元素的层级、类名、标签、属性串起来,就能精准找到目标数据。

先看几个常见的写法:

选择器 含义
.news-item 找 class 包含 news-item 的元素
.news-item h2 a 在 .news-item 下面,找 h2 里面的 a
article.news-item 找标签是 article、且 class 包含 news-item 的元素
a[href] 找带有 href 属性的 a 标签
span.time 找标签是 span、且 class 包含 time 的元素

重点理解 .news-item h2 a

这个选择器可以拆成三段:

复制代码
.news-item   h2   a
   ↓         ↓    ↓
 外层容器   中间层  目标元素

它表示:

先找到 class 为 news-item 的元素,再在这个元素内部,找到 h2 标签,最后找到 h2 里面的 a 标签。

结合前面的 HTML:

html 复制代码
<div class="news-list">
  <article class="news-item">
    <h2>
      <a href="/news/123">标题</a>
    </h2>
    <span class="time">2026-10-13</span>
  </article>
</div>

.news-item h2 a 会命中:

html 复制代码
<a href="/news/123">标题</a>

这里的空格表示"后代关系",也就是说,a 不一定要直接紧挨着 h2,只要它在 h2 内部就可以了。

和 XPath 相比,CSS Selector 更短、更直观,适合结构清晰的页面;XPath 表达能力更强,比如可以按文本内容定位、向上找父节点,但语法会更复杂一些。日常写爬虫,先掌握 CSS Selector 已经能解决大部分问题。

XPath

如果说 CSS Selector 是直观的"视觉定位",那 XPath 就是一把功能更强的"手术刀"。它原本是为 XML 文档设计的查询语言,但在 HTML 解析中同样强大。XPath 的最大优势在于表达能力极强------它不仅能向下查找,还能向上回溯、按文本内容筛选、甚至进行逻辑运算。当 CSS Selector 搞不定的复杂场景(比如"查找包含特定文字的按钮"或"定位父级元素")时,XPath 往往是最佳解法。

核心语法速查表

你不需要背诵复杂的规范,掌握下面这几招就能覆盖 90% 的爬虫需求:

语法 含义 示例
//tag 在整个文档中查找所有该标签 //a 查找所有链接
/ 选取直接子节点 //div/a 查找 div 下的直接链接
// 选取后代节点(子孙均可) //div//a 查找 div 内所有层级的链接
[@attr='val'] 属性筛选 //div[@id='main']
text() 获取标签内的文本内容 //h2/text()
contains() 模糊匹配(属性或文本) //div[contains(@class, 'news')]
结合实例理解

回到我们熟悉的 HTML 结构:

html 复制代码
<div class="news-list">
  <article class="news-item">
    <h2>
      <a href="/news/123">标题</a>
    </h2>
    <span class="time">2026-10-13</span>
  </article>
</div>

1. 基础定位

html 复制代码
//article[@class='news-item']//a

这句话的意思是:先在全文找到 class 为 news-item 的 article 标签,然后在它内部任意层级找到 a 标签。

2. 提取文本

html 复制代码
//article[@class='news-item']/h2/a/text()

这会直接提取出文本内容:标题。注意这里用了单斜杠 /,表示严格的父子层级关系。

3. 模糊匹配(实战神器)

html 复制代码
//span[contains(@class, 'time')]

很多网站为了反爬,class 名会写成 time-wrapper 或 time-box。用 contains 就能轻松命中包含 time 字符的 class。

什么时候必须用 XPath?

虽然 CSS Selector 写起来更顺手,但在以下场景 XPath 是无可替代的:

  • 按文本查找 :比如 //button[text()='下一页'],CSS 做不到。

  • 向上查找父节点 :比如 //a[@href='...']/../..,找到链接的祖父节点。

  • 复杂的逻辑组合 :比如 //div[@id='list' and @data-type='news']。

正则表达式

正则表达式(Regular Expression)在爬虫里的定位非常明确:它不适合直接解析 HTML 结构,但极其擅长处理已经提取出来的文本片段。

为什么不用正则解析 HTML?

HTML 是树状嵌套结构,而正则是基于线性文本匹配的。用正则硬扒整个 HTML 会遇到很多坑:

  • 标签嵌套层级复杂,正则难以准确匹配开闭标签;

  • 属性顺序不固定,class="a" id="b" 和 id="b" class="a" 会让同一套正则失效;

  • 页面稍有改动,正则就可能全盘崩溃。

所以业界共识是:结构问题交给 DOM(CSS/XPath),文本问题交给正则。

正确的使用姿势

典型的爬虫解析流程是这样的:

复制代码
HTML 源码
    ↓  CSS/XPath 定位节点
拿到目标文本(如 "发布时间:2026年10月13日 15:30")
    ↓  正则进一步清洗
提取纯数据(如 "2026-10-13 15:30")
常用正则模式速查

表格

需求 正则写法 匹配示例
4位数字 \d{4} 2026
1~2位数字 \d{1,2} 1 ~ 12
中文日期 \d{4}年\d{1,2}月\d{1,2}日 2026年10月13日
手机号 1\d{10} 13812345678
邮箱 \w+@\w+\.\w+ test@example.com
非贪婪匹配 .*? 匹配最短内容
实战示例

假设你已经用 CSS Selector 拿到了这段文本:

html 复制代码
发布时间:2026年10月13日 15:30

用正则提取日期和时间:

html 复制代码
import re
​
text = "发布时间:2026年10月13日 15:30"
match = re.search(r"(\d{4}年\d{1,2}月\d{1,2}日)\s*(\d{1,2}:\d{2})", text)
if match:
    date = match.group(1)   # "2026年10月13日"
    time = match.group(2)   # "15:30"
一句话总结

CSS/XPath 负责"找到在哪里",正则负责"抠出是什么"。 两者配合,才是爬虫解析的最佳实践。

解析的产物:先拿到"节点",再提炼出"数据"

很多初学者会以为爬虫解析的目标就是"把文字抠出来",其实不是。解析器(lxml、parsel、BeautifulSoup)真正返回给你的,是两个层次的东西:一个是节点对象 ,另一个是你最终想要的业务数据。理解这两个层次,才算真正打通了"解析 → 入库"的链路。

第一类:节点对象(中间产物)

当你用 CSS Selector 或 XPath 定位时,命中的往往不是一个字符串,而是一个节点对象。比如你定位到:

复制代码
<a href="/news/123">周杰伦发布新歌</a>

解析器返回的是一个代表这个 `` 标签的对象。这个对象的价值在于它是"活的"------你还能继续从它身上取各种信息:

你想拿的东西 从节点上怎么取
文本内容 周杰伦发布新歌
属性值 href="/news/123"
子节点 该标签内部的嵌套标签
父节点 它的上一层容器
整段 HTML 连标签一起的原始结构

换句话说,节点对象是一个"可继续深挖的入口"。定位这一步只是把范围缩小到某个节点,真正的字段提取是在这个节点上二次操作完成的。这也是为什么 XPath 里有 text()、@href 这些函数------它们就是挂在节点对象上的取值手段。

第二类:业务数据(最终产物)

节点只是手段,你真正要的是把它拆成一个个有语义的字段。一条新闻里常见的业务数据包括:

复制代码
文本     title       = "周杰伦发布新歌"
链接     url         = "/news/123"
图片     image       = "https:1.jpg"
时间     publishTime = "2026-10-13"
作者     author      = "某记者"
正文     content     = "……"
属性     data-id     = "123"

这一步做的事情其实就是:从节点对象上,把文本、属性、子节点分别取出来,再做去空格、补全域名、格式清洗等处理,把"网页上的一块结构"翻译成"程序里的一段干净数据"。

最后:整理成结构化对象

零散字段单独放着没法用,爬虫的收尾工作是把它们归拢成一个结构化对象------通常是字典或对象,一行对应一条数据:

javascript 复制代码
{
  "title": "周杰伦发布新歌",
  "url": "https://xxx.com/news/123",
  "publishTime": "2026-10-13T15:30:00+08:00",
  "author": "某记者",
  "content": "......"
}

到这一步,解析就彻底完成了:HTML 树 → 定位到节点 → 从节点取字段 → 清洗 → 装进结构化对象。这个对象就是要送去"入库"的东西------存进 MySQL、MongoDB 还是导出成 CSV,都以它为标准形态。

相关推荐
傻啦嘿哟5 小时前
天气数据爬虫:基于Scrapy爬取全国天气,做可视化大屏
c++·爬虫·scrapy
雪雪爱冲浪19 小时前
2026 年网络爬虫领域的Puppeteer vs. Playwright
爬虫·网络协议·测试工具·接口隔离原则
深蓝电商API2 天前
mitmproxy高级用法:自定义脚本拦截改包
爬虫·mitmproxy
Fluxproxy2 天前
Python爬虫异步提速终极方案|线程池ThreadPoolExecutor实战,告别单线程慢速爬取
开发语言·爬虫·python
独立开发者阿乐2 天前
llms.txt 是什么?为什么 AI 爬虫需要这个文件
人工智能·爬虫·geo优化·ai爬虫·llms.txt·ai收录·robots.txt
傻啦嘿哟2 天前
高校信息爬虫:爬取全国高校列表与排名,做择校分析
爬虫
深蓝电商API3 天前
HTTP/2 协议逆向:从 Fiddler 抓不到包说起
爬虫·网络协议·http·fiddler
隐擎fox3 天前
深入网络风控底层:解密 IP 信誉评分模型、ASN 属性判定与多租户原生网络隔离架构
网络·爬虫·网络协议·tcp/ip·架构·跨境电商·指纹浏览器
zzp282183 天前
Estyapp逆向分析
爬虫