1. 网页抓取的本质:理解HTML结构
当你第一次尝试用Python写爬虫时,最困惑的问题往往是:我到底要从网页中抓取什么?答案就藏在网页的HTML结构中。HTML(超文本标记语言)是构成网页的骨架,它用标签来定义内容的结构和含义。
一个典型的HTML文档看起来是这样的:
html复制<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>示例网页</title>
</head>
<body>
<div class="content">
<h1>这是标题</h1>
<p class="intro">这是一段介绍文字</p>
<ul id="list">
<li>项目1</li>
<li>项目2</li>
</ul>
</div>
</body>
</html>
在这个结构中,每个标签都有其特定作用:
<div>定义文档中的区块<h1>表示一级标题<p>表示段落<ul>和<li>创建无序列表
关键提示:爬虫工作的第一步永远是先查看目标网页的HTML源码。在Chrome浏览器中,右键点击页面选择"检查"或按F12打开开发者工具。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. CSS选择器:精准定位元素的利器
CSS选择器是定位HTML元素最直观的方式之一。它通过元素标签名、类名、ID等属性来选取元素,语法与CSS样式定义完全一致。
2.1 基础选择器类型
-
标签选择器:直接使用HTML标签名
css复制p /* 选择所有<p>元素 */ -
类选择器:使用点号(.)加类名
css复制.intro /* 选择class="intro"的元素 */ -
ID选择器:使用井号(#)加ID名
css复制#list /* 选择id="list"的元素 */
2.2 组合选择器
选择器可以组合使用实现更精确的定位:
css复制div.content > p.intro /* 选择div中class为content的直接子p元素,且p的class为intro */
ul#list li:nth-child(2) /* 选择id为list的ul中第二个li元素 */
在Python中,BeautifulSoup和pyquery等库都支持CSS选择器。例如:
python复制from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
# 使用CSS选择器
title = soup.select_one('h1').text
items = [li.text for li in soup.select('ul#list li')]
3. XPath:更强大的定位语言
XPath(XML Path Language)是一种在XML和HTML文档中查找信息的语言,它比CSS选择器更强大灵活,特别适合处理复杂的文档结构。
3.1 XPath基础语法
-
基本路径表达式:
code复制/html/body/div # 从根节点开始的绝对路径 //div # 文档中所有的div元素 -
谓语(条件筛选):
code复制//ul[@id='list'] # 选择id属性为list的ul元素 //li[position()>1] # 选择位置大于1的li元素 -
通配符和运算符:
code复制//div[@*] # 选择带有任意属性的div元素 //h1|//h2 # 选择所有h1和h2元素
3.2 在Python中使用XPath
lxml库提供了优秀的XPath支持:
python复制from lxml import etree
html = etree.HTML(html_doc)
# 使用XPath提取数据
title = html.xpath('//h1/text()')[0]
items = html.xpath('//ul[@id="list"]/li/text()')
实战技巧:在Chrome开发者工具中,可以右键元素选择"Copy XPath"快速获取元素的XPath表达式,但自动生成的XPath往往过于冗长,需要手动优化。
4. CSS选择器 vs XPath:如何选择?
两种定位方式各有优劣:
| 特性 | CSS选择器 | XPath |
|---|---|---|
| 语法简洁度 | ⭐⭐⭐⭐ | ⭐⭐ |
| 功能强大性 | ⭐⭐ | ⭐⭐⭐⭐ |
| 浏览器兼容性 | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 性能 | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| 文本内容匹配 | 不支持 | 支持(contains()) |
| 轴选择 | 有限 | 强大(parent, following等) |
选择建议:
- 简单页面:优先使用CSS选择器,语法更简洁
- 复杂页面:考虑XPath,特别是需要根据文本内容或复杂关系定位时
- 性能敏感场景:XPath通常略快,但差异不大
5. 实战避坑指南
5.1 动态内容处理
现代网站大量使用JavaScript动态加载内容,直接请求HTML可能获取不到完整数据。解决方案:
- 使用Selenium等工具模拟浏览器
- 分析AJAX请求接口
- 寻找隐藏的JSON数据
5.2 反爬虫策略应对
常见反爬手段及对策:
- User-Agent检测:设置合理的请求头
python复制headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...' } - 频率限制:添加随机延迟
python复制import time import random time.sleep(random.uniform(0.5, 1.5)) - 验证码:考虑使用打码平台或机器学习方案
5.3 数据清洗技巧
爬取的数据常需要清洗:
python复制# 去除空白字符
clean_text = ' '.join(raw_text.split())
# 提取数字
import re
price = re.search(r'\d+\.?\d*', price_text).group()
# 处理编码问题
content = content.encode('raw_unicode_escape').decode('utf-8')
6. 进阶学习路径
掌握基础定位技术后,可以进一步学习:
- 正则表达式:处理非结构化文本的强大工具
- Selenium:自动化测试工具,适合动态网页
- Scrapy:专业的爬虫框架
- 反反爬技术:IP代理、请求指纹伪装等
- 分布式爬虫:提高爬取效率
记住,优秀的爬虫工程师不仅要会写代码,更要理解网页结构、网络协议和数据处理。每次写爬虫前,多花时间分析目标网站的结构和规律,往往能事半功倍。
