基础知识
数据采集核心概念
网络爬虫是按照一定规则自动抓取网络信息的程序。数据采集是数据分析和机器学习的第一步,获取高质量数据至关重要。
HTTP 协议
HTTP(超文本传输协议)是互联网上应用最广泛的协议。理解 HTTP 请求方法、状态码和请求头对爬虫开发至关重要。
- GET:获取资源
- POST:提交数据
- 状态码:200 成功、404 未找到、500 服务器错误
- 请求头:User-Agent、Referer、Cookie 等
requests 库
requests 是 Python 中简洁优雅的 HTTP 库,用于发送各种 HTTP 请求,是爬虫开发的基础工具。
BeautifulSoup
BeautifulSoup 是 Python 的 HTML/XML 解析库,可以从 HTML 或 XML 文件中提取数据。支持多种解析器如 lxml、html.parser。
Scrapy
Scrapy 是 Python 的一个快速、高层次的 Web 爬虫框架,用于抓取网站并提取结构化数据。它提供了完整的爬虫开发解决方案。
反爬策略
- User-Agent 检测:识别非浏览器请求
- IP 限制:限制单个 IP 的请求频率
- 验证码:要求人工验证
- 动态渲染:使用 JavaScript 加载内容
- 反爬应对:代理 IP、请求间隔、浏览器模拟
图文教程
步骤一:发送请求
import requests
# 基本 GET 请求
response = requests.get('https://api.example.com/data')
print(response.status_code)
print(response.json())
# 带请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json'
}
response = requests.get('https://example.com', headers=headers)
# POST 请求
data = {'username': 'admin', 'password': '123456'}
response = requests.post('https://api.example.com/login', data=data)
步骤二:解析 HTML
from bs4 import BeautifulSoup
html = '''
<html>
<body>
<div class="item">
<h2>Title 1</h2>
<span class="price">$100</span>
</div>
<div class="item">
<h2>Title 2</h2>
<span class="price">$200</span>
</div>
</body>
</html>
'''
soup = BeautifulSoup(html, 'html.parser')
# 查找元素
titles = soup.find_all('h2')
for title in titles:
print(title.text)
# CSS 选择器
items = soup.select('.item')
for item in items:
title = item.select_one('h2').text
price = item.select_one('.price').text
print(f'{title}: {price}')
步骤三:数据提取与存储
import csv
import json
# 提取数据
data = []
for item in soup.select('.item'):
data.append({
'title': item.select_one('h2').text,
'price': item.select_one('.price').text
})
# 保存为 CSV
with open('data.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['title', 'price'])
writer.writeheader()
writer.writerows(data)
# 保存为 JSON
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
代码实操
阅读以下代码,理解实现原理,然后尝试修改并运行
实践任务:爬虫与数据清洗类
import requests
from bs4 import BeautifulSoup
import re
class WebScraper:
def __init__(self, base_url):
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
})
def fetch(self, url):
"""获取页面内容"""
try:
response = self.session.get(url, timeout=10)
response.raise_for_status()
return response.text
except requests.RequestException as e:
print(f"Error fetching {url}: {e}")
return None
def parse(self, html):
"""解析并提取数据"""
soup = BeautifulSoup(html, 'html.parser')
items = []
for card in soup.select('.product-card'):
item = {
'name': self.clean_text(card.select_one('.name')),
'price': self.extract_price(card.select_one('.price')),
'rating': self.extract_rating(card.select_one('.rating'))
}
items.append(item)
return items
def clean_text(self, element):
"""清洗文本"""
if not element:
return ''
text = element.get_text(strip=True)
return re.sub(r'\s+', ' ', text)
def extract_price(self, element):
"""提取价格数字"""
text = self.clean_text(element)
match = re.search(r'[\d,]+\.?\d*', text)
return float(match.group().replace(',', '')) if match else None
def extract_rating(self, element):
"""提取评分"""
text = self.clean_text(element)
match = re.search(r'(\d+\.?\d*)', text)
return float(match.group(1)) if match else None
练习任务
- 添加代理 IP 支持,实现 IP 轮换
- 添加请求间隔和重试机制
- 将数据保存到 SQLite 数据库