一、项目背景
社交媒体数据是舆情分析、用户画像的重要来源。但社交平台的反爬机制通常比较严格,需要更高级的技术手段。
项目目标
- 采集用户发布的内容
- 提取文本、图片、点赞数等信息
- 处理动态加载和反爬
- 数据保存到数据库
二、需求分析
2.1 数据来源
以某社交平台的用户主页为例,数据通过 API 接口返回。
2.2 数据结构
{
"code": 0,
"data": {
"posts": [
{
"id": "12345",
"content": "今天天气真好!",
"images": ["url1", "url2"],
"likes": 100,
"comments": 20,
"create_time": 1705315200
}
]
}
}
三、环境准备
pip install requests
pip install fake-useragent
pip install pymongo
四、代码实现
4.1 基础爬虫
import requests
import json
import time
import random
from fake_useragent import UserAgent
class SocialMediaCrawler:
def __init__(self):
self.ua = UserAgent()
self.session = requests.Session()
self.base_url = 'https://api.example.com/posts'
def get_headers(self):
return {
'User-Agent': self.ua.random,
'Accept': 'application/json',
'Referer': 'https://www.example.com',
'X-Requested-With': 'XMLHttpRequest'
}
def fetch_posts(self, user_id, page=1):
"""获取用户帖子"""
params = {
'user_id': user_id,
'page': page
}
try:
response = self.session.get(
self.base_url,
params=params,
headers=self.get_headers(),
timeout=10
)
response.raise_for_status()
return response.json()
except Exception as e:
print(f"请求失败: {e}")
return None
def parse_posts(self, data):
"""解析帖子数据"""
if not data or data.get('code') != 0:
return []
posts = data['data']['posts']
results = []
for post in posts:
results.append({
'id': post.get('id'),
'content': post.get('content'),
'images': post.get('images'),
'likes': post.get('likes'),
'comments': post.get('comments'),
'create_time': post.get('create_time')
})
return results
def crawl(self, user_id, max_pages=5):
"""采集数据"""
all_posts = []
for page in range(1, max_pages + 1):
print(f"正在采集第 {page} 页...")
data = self.fetch_posts(user_id, page)
if not data:
break
posts = self.parse_posts(data)
all_posts.extend(posts)
print(f"第 {page} 页采集完成,获取 {len(posts)} 条数据")
# 随机延时
time.sleep(random.uniform(2, 5))
return all_posts
五、反爬处理
5.1 处理签名验证
import hashlib
def generate_sign(params, secret_key):
"""生成签名"""
sorted_params = sorted(params.items())
param_str = '&'.join([f'{k}={v}' for k, v in sorted_params])
sign_str = f'{param_str}&key={secret_key}'
return hashlib.md5(sign_str.encode()).hexdigest()
# 在请求中添加签名
params['sign'] = generate_sign(params, 'your_secret_key')
5.2 使用代理池
class SocialMediaCrawler:
def __init__(self):
# ... 其他初始化 ...
self.proxy_pool = ProxyPool()
def fetch_posts(self, user_id, page=1):
# ... 添加代理 ...
proxy = self.proxy_pool.get_proxy()
response = self.session.get(
self.base_url,
params=params,
headers=self.get_headers(),
proxies=proxy,
timeout=10
)
六、总结
社交媒体爬虫的关键点:
- 分析数据接口和加密方式
- 模拟真实用户行为
- 使用代理池轮换 IP
- 控制请求频率