简单来说,爬虫就是通过程序自动抓取网页信息的技术。当你右键查看网页源代码时,看到的 HTML 结构就是爬虫工作的对象。本文将以 Python 为例,从零开始讲解如何编写一个稳定的爬虫程序。
一、爬虫的基本流程
无论复杂的爬虫架构如何,核心逻辑通常包含三步:
- 发送请求:向目标网页发起 HTTP 请求,获取原始内容。
- 解析网页:从返回的 HTML 或 JSON 数据中提取关键信息。
- 保存数据:将提取到的信息存储到本地文件或数据库中。
二、常用工具库
在 Python 生态中,有几个库是开发爬虫时的标配:
- requests:处理网络请求,获取网页内容。
- BeautifulSoup:解析 HTML 文档,快速定位标签和数据。
- Selenium:模拟浏览器行为,用于处理动态加载的内容。
- Scrapy:强大的爬虫框架,适合大规模数据采集。
安装依赖
首先确保安装了必要的库。推荐使用国内镜像源加速下载:
pip install requests beautifulsoup4 selenium scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple
三、静态页面爬虫实战
我们以百度首页为例,演示最基础的抓取流程。
1. 获取网页源码
使用 requests 库发送 GET 请求。为了模拟真实浏览器访问,建议添加 User-Agent 请求头。
import requests
url = 'https://www.baidu.com'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(url, headers=headers)
print(response.text)
这里的关键在于 response.text,它包含了服务器返回的完整 HTML 字符串。
2. 解析标题与链接
拿到 HTML 后,用 BeautifulSoup 进行解析。我们可以轻松提取页面标题和所有超链接。
from bs4 import BeautifulSoup
# 初始化解析器
soup = BeautifulSoup(response.text, 'html.parser')
# 获取标题
title = soup.title.text
print(f'网页标题:{title}')
# 提取所有链接
links = soup.find_all('a')
for link in links:
href = link.get('href')
if href:
print(href)
注意,find_all('a') 会返回所有 <a> 标签,我们需要遍历并获取 href 属性。实际项目中,通常还需要过滤掉无效链接(如空值或以 # 开头的锚点)。
四、进阶场景处理
1. 动态网页(JavaScript 渲染)
如果网页内容是通过 JavaScript 异步加载的,普通的 requests 拿不到数据。这时需要 Selenium 来驱动浏览器。
from selenium import webdriver
# 启动 Chrome 浏览器
driver = webdriver.Chrome()
try:
driver.get('https://www.example.com')
print(driver.title)
finally:
driver.quit()
Selenium 能像真人一样操作页面,比如点击按钮、滚动加载更多内容,非常适合处理现代前端应用。
2. 反爬机制应对
很多网站有反爬策略,常见的几种应对方式如下:
- 伪装请求头:如上例所示,设置 User-Agent。
- 控制频率:频繁请求会被封禁,加入随机延迟。
import time
import random
time.sleep(random.uniform(1, 3)) # 随机等待 1-3 秒
- 代理 IP:如果单 IP 被封,可切换代理池。
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'https://10.10.1.10:1080'
}
response = requests.get(url, proxies=proxies)
五、数据存储方案
数据抓下来后,通常需要持久化存储。
1. CSV 文件
适合轻量级数据导出,Excel 可直接打开。
import csv
with open('data.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['标题', '链接']) # 表头
for link in links:
writer.writerow([link.text, link.get('href')])
2. SQLite 数据库
适合结构化数据,便于后续查询和分析。
import sqlite3
conn = sqlite3.connect('data.db')
cursor = conn.cursor()
# 建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS links (
title TEXT,
href TEXT
)
''')
# 插入数据
for link in links:
cursor.execute(
'INSERT INTO links (title, href) VALUES (?, ?)',
(link.text, link.get('href'))
)
conn.commit()
conn.close()
六、总结
爬虫开发的核心在于理解 HTTP 协议和 HTML 结构。对于初学者,掌握 requests 和 BeautifulSoup 足以应对大部分静态页面需求。遇到动态加载内容时,引入 Selenium;面对大规模采集任务,则应转向 Scrapy 框架。同时,务必遵守网站的 robots.txt 协议,合理控制请求频率,避免对目标服务器造成压力。


