🔗 运行环境:PYTHON
🚩 撰写作者:左手の明天
🥇 精选专栏:《python》
🔥 推荐专栏:《算法研究》
#### 防伪水印——左手の明天 ####
💗 大家好🤗🤗🤗,我是左手の明天!好久不见💗
💗今天更新系列【python网络爬虫案例】—— 爬取新浪微博内容💗
📆 最近更新:2025 年 04 月 01 日,左手の明天的第 358 篇原创博客
📚 更新于专栏:python网络爬虫
#### 防伪水印——左手の明天 ####
一、项目背景
1.1 为什么要爬取微博数据
-
舆情分析(热点事件追踪)
-
用户行为研究(传播模式分析)
-
品牌营销监测(产品口碑收集)
1.2 法律合规要点
-
仅采集公开可见数据
-
遵守《网络安全法》第27条
-
禁止商业倒卖数据
-
每日采集量控制在1000条以内
二、技术选型与环境准备
2.1 所需工具清单
# 基础库
pip install requests # 网络请求
pip install pyquery # HTML解析
pip install fake-useragent # 随机UA生成
pip install pandas # 数据存储
# 可选扩展
pip install selenium # 应对复杂反爬
pip install redis # 分布式爬虫
2.2 代理IP配置建议
推荐使用以下服务(需自行注册):
-
快代理(国内高匿IP)
-
BrightData(海外住宅IP)
-
芝麻代理(动态转发服务)
三、微博移动端API逆向分析
3.1 核心接口定位
通过Chrome开发者工具分析发现:
请求地址
https://m.weibo.cn/api/container/getIndex
关键参数:
params = {
"containerid": "107603{uid}", # 用户主页固定格式
"page_type": "uid",
"page": 2 # 分页参数
}
3.2 数据响应结构
{
"data": {
"cards": [
{
"card_type": 9,
"mblog": {
"created_at": "08-20 09:30",
"text": "HTML格式内容",
"reposts_count": 1523,
"comments_count": 892,
"attitudes_count": 15670
}
}
]
}
}
四、完整爬虫代码实现
4.1 基础爬取模块
import requests
import json
import time
import random
from pyquery import PyQuery as pq
class WeiboSpider:
def __init__(self, uid, max_page=5):
self.uid = uid
self.max_page = max_page
self.headers = {
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1',
'X-Requested-With': 'XMLHttpRequest'
}
self.session = requests.Session()
def _get_containerid(self):
"""获取用户主页containerid"""
url = f'https://m.weibo.cn/api/container/getIndex?type=uid&value={self.uid}'
res = self.session.get(url, headers=self.headers)
return res.json()['data']['tabsInfo']['tabs'][0]['containerid']
def parse_page(self, page):
"""解析单页数据"""
containerid = self._get_containerid()
url = 'https://m.weibo.cn/api/container/getIndex'
params = {
'containerid': containerid,
'page': page
}
try:
response = self.session.get(url, params=params, headers=self.headers)
return self._clean_data(response.json())
except Exception as e:
print(f'第{page}页抓取失败:{str(e)}')
return []
def _clean_data(self, json_data):
"""清洗数据"""
cleaned = []
for card in json_data.get('data', {}).get('cards', []):
if card['card_type'] == 9:
mblog = card['mblog']
cleaned.append({
'时间': mblog['created_at'],
'内容': pq(mblog['text']).text(), # 去除HTML标签
'转发': mblog['reposts_count'],
'评论': mblog['comments_count'],
'点赞': mblog['attitudes_count']
})
return cleaned
def run(self):
"""执行采集"""
all_data = []
for page in range(1, self.max_page+1):
print(f'正在采集第 {page}/{self.max_page} 页')
page_data = self.parse_page(page)
all_data.extend(page_data)
time.sleep(random.uniform(2,5)) # 随机延迟
self.save_data(all_data)
return all_data
def save_data(self, data):
"""存储为CSV"""
import pandas as pd
df = pd.DataFrame(data)
df.to_csv(f'weibo_{self.uid}.csv', index=False)
print(f'已保存 {len(df)} 条数据')
if __name__ == '__main__':
spider = WeiboSpider(uid='1736988591', max_page=3) # 人民日报UID
spider.run()
五、反爬策略突破方案
5.1 请求头深度伪装
from fake_useragent import UserAgent
def get_headers():
return {
'User-Agent': UserAgent().random,
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': f'https://m.weibo.cn/u/{uid}',
'MWeibo-Pwa': '1'
}
5.2 IP代理中间件
PROXY_POOL = [
'http://user:pass@ip:port',
'socks5://user:pass@ip:port'
]
def get_proxy():
return {'https': random.choice(PROXY_POOL)}
5.3 验证码处理方案
from PIL import Image
import pytesseract
def handle_captcha(image_url):
response = requests.get(image_url)
with open('captcha.jpg', 'wb') as f:
f.write(response.content)
image = Image.open('captcha.jpg')
text = pytesseract.image_to_string(image)
return text.strip()
六、数据存储与可视化
6.1 数据库存储示例(MySQL)
import pymysql
def save_to_mysql(data):
conn = pymysql.connect(
host='localhost',
user='root',
password='123456',
database='weibo'
)
sql = '''INSERT INTO posts
(time, content, reposts, comments, likes)
VALUES (%s, %s, %s, %s, %s)'''
with conn.cursor() as cursor:
cursor.executemany(sql, [
(d['时间'], d['内容'], d['转发'], d['评论'], d['点赞'])
for d in data
])
conn.commit()
conn.close()
6.2 数据可视化案例
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('weibo_1736988591.csv')
df['时间'] = pd.to_datetime(df['时间'])
# 按小时统计发帖量
hourly = df.groupby(df['时间'].dt.hour).size()
hourly.plot(kind='bar', title='每日发帖时段分布')
plt.xlabel('小时')
plt.ylabel('发帖量')
plt.show()
七、常见问题解决方案
7.1 返回空数据排查
-
检查UID是否正确
-
验证Cookie是否失效
-
测试代理IP可用性
-
降低请求频率
7.2 高频访问被封禁
-
方案1:切换4G网络
-
方案2:使用手机验证码登录获取新Cookie
-
方案3:更换MAC地址和UA组合
八、项目扩展方向
8.1 进阶功能开发
-
实时监控热搜话题
-
用户社交网络分析
-
评论情感分析(NLP)
8.2 部署方案
-
使用Scrapy-Redis构建分布式爬虫
-
通过Docker容器化部署
-
设置Crontab定时任务