一、HTTP协议:爬虫的"对话语言"
想象你走进一家图书馆,想借一本《Python入门》。你需要先到前台登记(请求),馆员根据登记信息找到书(响应),最后把书交给你。HTTP协议就是爬虫与服务器之间的"对话规则"。
1.1 一次完整的HTTP请求流程
- 建立连接:爬虫(客户端)通过IP和端口(如80或443)找到服务器。
- 发送请求:包含方法(GET/POST)、路径(如/books/python)、请求头(如User-Agent)和可选请求体(如表单数据)。
- 服务器处理:服务器解析请求,查询数据库或生成动态内容。
- 返回响应:状态码(如200成功)、响应头(如Content-Type)和响应体(HTML/JSON数据)。
- 断开连接:默认短连接,可通过Connection: keep-alive复用TCP连接。
示例:用curl命令模拟请求
sql
curl -X GET "https://example.com/api/books" \
-H "User-Agent: Mozilla/5.0" \
-H "Accept: application/json"
1.2 关键组件解析
请求方法:
- GET:获取数据(如搜索页面),参数在URL中(?q=python)。
- POST:提交数据(如登录表单),参数在请求体中。
状态码:
- 200:成功;404:页面不存在;500:服务器错误;403:权限不足(常因反爬触发)。
请求头:
- User-Agent:标识客户端类型(浏览器/爬虫)。
- Cookie:维持会话状态(如登录后保持登录状态)。
响应头:
- Content-Type:指定数据格式(text/html或application/json)。
- Set-Cookie:服务器返回的Cookie,需保存用于后续请求。
二、Python爬虫的"三板斧"
用Python写爬虫,核心是控制HTTP请求、解析响应数据、存储结果。
2.1 发送请求:从urllib到requests
原始方法:使用标准库urllib(复杂且易出错)
vbscript
from urllib.request import urlopen, Request
req = Request("https://example.com", headers={"User-Agent": "Mozilla/5.0"})
response = urlopen(req)
print(response.read().decode("utf-8"))
推荐方法:第三方库requests(简洁强大)
vbscript
import requests
response = requests.get("https://example.com", headers={"User-Agent": "Mozilla/5.0"})
print(response.text) # 自动解码为字符串
2.2 解析数据:HTML与JSON的"抽丝剥茧"
HTML解析:BeautifulSoup或lxml
ini
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, "html.parser")
title = soup.find("h1").text # 提取标题
links = [a["href"] for a in soup.find_all("a")] # 提取所有链接
JSON处理:直接转为Python字典
ini
import json
data = response.json() # 假设响应是JSON格式
print(data["books"][0]["title"])
2.3 存储数据:文件、数据库与CSV
保存到文件:
python
with open("output.html", "w", encoding="utf-8") as f:
f.write(response.text)
写入CSV:
kotlin
import csv
with open("books.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["Title", "Author"])
for book in data["books"]:
writer.writerow([book["title"], book["author"]])
三、反爬虫与应对策略:道高一尺,魔高一丈
网站常通过IP限制、验证码、行为检测等手段阻止爬虫,需针对性破解。
3.1 IP封禁与代理池
- 问题:同一IP频繁请求会被封禁。
解决方案:
使用代理IP(如requests配合proxies参数):
ini
proxies = {"http": "http://123.123.123.123:8080"}
requests.get("https://example.com", proxies=proxies)
代理池工具:如scrapy-proxies或第三方服务(如站大爷)。
3.2 验证码识别
- 图形验证码:用Tesseract OCR或打码平台(如超级鹰)。
- 行为验证码(如滑块):需模拟人类操作(Selenium拖动滑块)。
示例:用pytesseract识别简单验证码
python
import pytesseract
from PIL import Image
image = Image.open("captcha.png")
code = pytesseract.image_to_string(image)
print(code)
3.3 模拟浏览器行为
- 问题:JavaScript渲染的页面无法直接获取数据。
解决方案:
Selenium:控制真实浏览器(Chrome/Firefox)。
scss
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
element = driver.find_element_by_id("content")
print(element.text)
driver.quit()
Playwright:更现代的替代方案,支持无头模式。
四、实战案例:爬取豆瓣电影Top250
目标:获取电影名称、评分、评价人数,保存为CSV。
4.1 分析页面结构
- URL模式:movie.douban.com/top250?star...
- 数据位置:每部电影在
中,标题在,评分在。
4.2 编写爬虫代码
ini
import requests
from bs4 import BeautifulSoup
import csv
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
def scrape_douban_top250():
base_url = "https://movie.douban.com/top250"
movies = []
for start in range(0, 250, 25):
url = f"{base_url}?start={start}"
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "html.parser")
for item in soup.find_all("div", class_="item"):
title = item.find("span", class_="title").text
rating = item.find("span", class_="rating_num").text
num_reviews = item.find("div", class_="star").find_all("span")[-1].text[:-3]
movies.append([title, rating, num_reviews])
return movies
# 保存数据
movies = scrape_douban_top250()
with open("douban_top250.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["标题", "评分", "评价人数"])
writer.writerows(movies)
4.3 优化与扩展
- 异常处理:添加try-except捕获网络错误。
- 随机延迟:避免被封禁。
arduino
import time
import random
time.sleep(random.uniform(1, 3)) # 随机延迟1-3秒
多线程:用concurrent.futures加速爬取(需控制并发数)。
五、常见问题Q&A
Q1:被网站封IP怎么办?
A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。
Q2:爬虫需要学哪些Python库?
A:基础三件套:requests(发送HTTP请求)、BeautifulSoup(解析HTML)、re(正则匹配)。进阶可选Scrapy框架或Selenium模拟浏览器。
Q3:如何避免被反爬?
A:设置请求头(User-Agent)、控制请求频率(随机延迟)、使用会话(Session)保持Cookie,必要时模拟人类操作(如滚动页面)。
Q4:动态加载的数据怎么抓?
A:通过浏览器开发者工具分析XHR请求,直接抓取API接口;或用Selenium驱动真实浏览器渲染页面。
Q5:爬虫合法吗?
A:遵守目标网站的robots.txt协议,仅爬取公开数据,避免高频请求影响服务器,商用前需咨询法律意见。
六、总结与展望
Python爬虫的核心是理解HTTP协议、掌握请求与解析工具、应对反爬机制。从简单请求到模拟浏览器,从单页爬取到分布式架构,技术栈可逐步深化。未来,随着AI和自动化测试的发展,爬虫将更智能(如自动识别验证码、自适应反爬策略),但合法合规始终是第一原则。
进阶建议:
- 学习Scrapy框架实现大规模爬取。
- 探索异步请求(如aiohttp)提升效率。
- 关注WebAssembly和新型前端框架对爬虫的影响。
爬虫的世界充满挑战与乐趣,愿这份指南助你开启数据采集之旅!