微博爬虫

准备写论文了,需要爬取些互联网的数据进行分析下,Pyhton爬虫是一个比较简单的方法,虽然有许多的爬虫框架但是我并不需要太复杂的爬虫,所以决定从零开始写一个简单的爬虫爬一下微博和评论。

准备工具

爬虫就是一个分析HTTP请求的工作,首先需要一些抓取http的工具,推荐使用 Fiddler,简单免费。

还需要浏览器 GoogleChrome

分析微博网站

微博有三个入口,分别是

weibo.com
weibo.cn
m.weibo.cn

第一个是PC网页版,后两个是手机版,手机版网站结构相对简单爬取容易,所以选择m.weibo.cn为爬取对象。

打开浏览器开发者模式,观察Network,在热门频道刷新,发现一个API

image

https://m.weibo.cn/api/container/getIndex?containerid=102803&openApp=0

这个地址的response就是热门微博的数据,接下来寻找翻页的方法,向下刷新观察发现一个地址在变化。

https://m.weibo.cn/api/container/getIndex?containerid=102803&openApp=0&since_id=1

image

since_id这个参数是控制翻页的。

用同样的方法观察评论页面

https://m.weibo.cn/detail/{微博编号}

这个地址就是具体微博的详细,

https://m.weibo.cn/comments/hotflow?id={mblogid}&mid={mblogid}&max_id={max_id}&max_id_type=0

mblogid是微博的编号,max_id控制翻页,前一个request会告诉这个id的数,如果是0则表示最后一页。

微博页面分析完毕,接下来编写代码模仿浏览器发Http请求就OK了。

编写代码

首先我们需要用到urllib这个库来发送请求。
还需要json化一下数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -*- coding: utf-8 -*-
# env python3.7

import json
import time
import random

from urllib import request
from urllib import parse

# 热门微博的url
HotWeiBoUrl = 'https://m.weibo.cn/api/container/getIndex?containerid=102803&since_id={sinceid}'
# 微博评论的Url
WeiBoCommentsUrl = 'https://m.weibo.cn/comments/hotflow?id={mblogid}&mid={mblogid}&max_id={max_id}&max_id_type=0'

首先访问热门微博页面,解析当前页面的热门微博的response,提取出每个微博的内容和地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def GetHotWeiBoData(url):
scheme_url = []
body_text = []

req = request.Request(url)
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
with request.urlopen(req) as f:
print('Status:', f.status, f.reason)
if f.status == 200:
data = f.read().decode('utf-8')
data = json.loads(data)
for i in data['data']['cards']:
scheme_url.append(i['scheme'])
body_text.append(i['mblog']['text'])
return body_text, scheme_url
return None, None

获取评论和下一页评论

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def GetCommentsData(comments_url):
text = []
req = request.Request(comments_url)
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
print(comments_url)
with request.urlopen(req) as f:
if f.status == 200:
data = f.read().decode('utf-8')
data = json.loads(data)
if "data" in data:
data = data["data"]
for i in data["data"]:
text.append(i["text"])
next_id = data['max_id']
return text, next_id
return None, None

循环执行上面两个函数,就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def GetCommentsUrl(url, max_id=0):
parsed_tuple = parse.urlparse(url)
mblogid = parsed_tuple.path[8:]
comments_url = WeiBoCommentsUrl.format(mblogid=mblogid, max_id=max_id)
return comments_url, mblogid

def GetWeiBo(sinceid):
data = {}
url = HotWeiBoUrl.format(sinceid=0)
body_text, scheme_url = GetHotWeiBoData(url)

for i in range(len(scheme_url)):
url = scheme_url[i]
body = body_text[i]
comments_url, mblogid = GetCommentsUrl(url)
comments, next_id = GetCommentsData(comments_url)
if comments:
data[mblogid] = {}
data[mblogid]['comments'] = []
data[mblogid]['comments'].extend(comments)
data[mblogid]['body'] = body

# while next_id != 0:
# comments_url, mblogid = GetCommentsUrl(url, next_id)
# comments, next_id = GetCommentsData(comments_url)
# data[mblogid]['comments'].extend(comments)

return data

把数据保存起来

1
2
3
4
5
def SaveData(data):
data = json.dumps(data, ensure_ascii=False) + "\n"
WeiBoData.write(data)
# 关闭打开的文件
# fo.close()

让爬虫开始工作,为防止被禁,把爬取频率调低点。

1
2
3
4
5
6
7
# 打开一个文件 a 已追加的方式打开,编码方式为 utf-8
WeiBoData = open("./WeiBoData.txt", "a", encoding="utf-8")

while True:
data = GetWeiBo(0)
SaveData(data)
time.sleep(random.randint(280, 320))

如果想要爬取多页评论,需要登陆操作,设置 cookie。

0%