随时随地发现新鲜事!微博带你欣赏世界上每一个精彩瞬间,了解每一个幕后故事。分享你想表达的,让全世界都能听到你的心声!相信很多人都发微博,也通过微博来了解更多的人或事,也可以通过某条微博的评论来提高自身对问题的看法全面性,今天我们获取微博的评论数据,来了解不同的人对相同的事物的有哪些不同的看法。
目录
爬前分析
评论数据
回复评论数据
实战演练
首页评论
多页评论
保存数据
结果展示
爬前分析
评论数据
首先打开某条微博并进入开发者工具,如下图所示:
经过查找,我们发现微博的评论数据有可能保存在图中红框的URL链接中,点击图中红框的show more,如下图所示:
这时我们发现评论数据是保存在上图中的URL链接中,既然知道了评论数据的保存位置,接下来我们将这个数据复制下来,并通过文本文件来展示,如下图所示:
我们发现这样获取下来的数据是非常乱的,提取我们想要的数据是非常困难的,那么怎么办好呢,是不是要硬着头皮将数据整列好并找出它们数据保存规律来提取数据呢,答案是:不是。
刚才我们打开微博的时候,是打开网页版的微博,在开发者工具中,只需一个按钮,我们就可以将电脑版微博变为手机版微博,如下图所示:
首先点击图中的红框1,然后刷新网页,这时就会发现URL从weibo.com/.....变为m.weibo.cn/........,这就代表了我们现在访问的是手机版的微博,接着通过查找发现评论数据保存在图中红框3的URL链接中,既然知道了数据的保存位置,接下来我们将分析它的URL的规律,URL如下:
#首页评论URL
https://m.weibo.cn/comments/hotflow?id=4708201179908955&mid=4708201179908955&max_id_type=0
?
#下一页评论URL
https://m.weibo.cn/comments/hotflow?id=4708201179908955&mid=4708201179908955&max_id=138168791121767&max_id_type=0
?
在URL链接中,发生改变的只有max_id参数,所以我们就可以通过max_id参数来构造url链接,如下所示:
https://m.weibo.cn/comments/hotflow?id=4708201179908955&mid=4708201179908955&max_id={max_id}&max_id_type=0
那么max_id是怎样获取的呢?
这时我们回到首页评论的URL链接,看看有没有我们可以利用的数据,如下图所示:
我们发现在首页URL链接返回的内容中有max_id数据而且刚好对应着下一页URL链接中的max_id参数,所以只需要把每一页URL链接返回的内容提取max_id并将其传递到构造的URL链接中即可获取下一页的评论数据。
回复评论数据
好了,知道了首页url链接和下一页评论数据URL链接的规律了,那么问题来了,有一些评论有其他人评论ta的评论,在评论数据中如何回去评论中的评论呢?
首先我们找到有评论评论的数据,如下图所示:
可以发现他们的对应关系,当评论数据中评论中有评价数据total_number参数就会显示有多少条评论而且会在参数comments中展示展示前两条数据,那么还有其他数据保存在哪里呢?
点击上上图中红框1,如下图所示:
首先在这时出现了新的URL链接:
https://m.weibo.cn/comments/hotFlowChild?cid=4707247845015688&max_id=0&max_id_type=0
明明显示有7条评论,为什么只有四条呢,这可能是评论被删了,所有只有四条评论,可以发现在URL中同样出现了max_id参数,在新的URL链接返回的内容中也有max_id参数,这说明了当回复评论数有很多,可以通过max_id参数来获取多页,那么问题来了cid参数是怎样产生的呢?看上上上图中红框的id或mid是和cid参数值一致的,那么我们就可以构造如下URL链接:
#回复评论首页评论
https://m.weibo.cn/comments/hotFlowChild?cid={mid}&max_id=0&max_id_type=0
?
#回复评论多页评论
https://m.weibo.cn/comments/hotFlowChild?cid={mid}&max_id={max_id}&max_id_type=0
好了,所有评论和回复评论数据的URL链接已经知道了,接下来正式编写代码把评论数据获取下来。
实战演练
这次爬虫程序的基本流程如下图所示:
-
首页评论:当max_id不等于0时,就获取多页的数据,当total_number>2时就获取回复评论的数据,当total_number不等于0且小于等于2时就获取comments中的评论数据; -
多页评论:当max_id不等于0时,将该页获取的max_id和原来的id返回给多页回复评论的代码,当total_number>2时就获取回复评论的数据,当total_number不等于0且小于等于2时就获取comments中的评论数据; -
回复评论:当max_id!=0时就获取多页回复评论数据; -
多页回复评论:当max_id!=0时就继续将该页获取的max_id和原来的id返回给多页回复评论的代码; -
保存数据:将所有数据保存在MySQL数据库中。
这里需要注意的时,这里我们获取的微博评论的回复评论只有很少,有些回复评论数据中有很多回复时,comments参数中的值就会为false,代码需要进行稍微修改。
首页评论
好了,现在正式开始首页评论的代码编写,代码如下所示:
# 获取评论首页
def get_comment_index(mid):
? ?url = f'https://m.weibo.cn/comments/hotflow?id={mid}&mid={mid}&max_id_type=0'
? ?response=requests.get(url,headers=headers).json()
? ?Xpath=response.get('data').get('data')
? ?for i in Xpath:
? ? ? ?total_number=i.get('total_number')
? ? ? ?id=i.get('id')
? ? ? ?data = {
? ? ? ? ? ?'user_name': i.get('user').get('screen_name'),
? ? ? ? ? ?'commtent': emoji.demojize(re.sub('<[^<]+?>', '', i.get('text'))),
? ? ? ? ? ?'data_time': i.get('created_at'),
? ? ? ? ? ?'mid': i.get('mid'),
? ? ? }
? ? ? ?#保存数据
? ? ? ?saving_data(list(data.values()))
? ? ? ?#当回复评论小于3的时候,提取comments中的评论数据
? ? ? ?if 0 < total_number <= 2:
? ? ? ? ? ?comments = i.get('comments')
? ? ? ? ? ?for i in comments:
? ? ? ? ? ? ? ?data = {
? ? ? ? ? ? ? ? ? ?'user_name': i.get('user').get('screen_name'),
? ? ? ? ? ? ? ? ? ?'commtent': emoji.demojize(re.sub('<[^<]+?>', '', i.get('text'))),
? ? ? ? ? ? ? ? ? ?'data_time': i.get('created_at'),
? ? ? ? ? ? ? ? ? ?'mid': i.get('mid'),
? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?saving_data(list(data.values()))
? ? ? ?elif total_number > 2:
? ? ? ? ? ?#当回复评论大于2的时候,将评论微博的id传递给自定义函数来获取多页回复评论
? ? ? ? ? ?get_comment_reply_index(id)
? ?max_id = response.get('data').get('max_id')
? ?if max_id!=0:
? ? ? ?#获取多页评论
? ? ? ?get_comment(mid, max_id)
通过request发送网络请求来获取返回响应数据中的json数据,并通过xpath将数据提取出来,并传递给各个自定义函数,
多页评论
获取到首页评论数据后,接下来获取多页评论数据了,获取多页评论和首页评论代码几乎相同,只是URL链接不同,代码如下所示:
# 获取多页评论
def get_comment(mid, max_id):
? ?url = f'https://m.weibo.cn/comments/hotflow?id={mid}&mid={mid}&max_id={max_id}&max_id_type=0'
? ?response = requests.get(url, headers=headers).json()
? ?Xpath=response.get('data').get('data')
? ?for i in Xpath:
? ? ? ?total_number=i.get('total_number')
? ? ? ?id=i.get('id')
? ? ? ?data = {
? ? ? ? ? ?'user_name': i.get('user').get('screen_name'),
? ? ? ? ? ?'commtent': emoji.demojize(re.sub('<[^<]+?>', '', i.get('text'))),
? ? ? ? ? ?'data_time': i.get('created_at'),
? ? ? ? ? ?'mid': i.get('mid'),
? ? ? }
? ? ? ?#保存数据
? ? ? ?saving_data(list(data.values()))
? ? ? ?#当回复评论小于3的时候,提取comments中的评论数据
? ? ? ?if 0 < total_number <=2:
? ? ? ? ? ?comments=i.get('comments')
? ? ? ? ? ?for i in comments:
? ? ? ? ? ? ? ?data = {
? ? ? ? ? ? ? ? ? ?'user_name': i.get('user').get('screen_name'),
? ? ? ? ? ? ? ? ? ?'commtent': emoji.demojize(re.sub('<[^<]+?>', '', i.get('text'))),
? ? ? ? ? ? ? ? ? ?'data_time': i.get('created_at'),
? ? ? ? ? ? ? ? ? ?'mid': i.get('mid'),
? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?saving_data(list(data.values()))
? ? ? ?#当回复评论大于2的时候,将评论微博的id传递给自定义函数来获取多页回复评论
? ? ? ?elif total_number > 2:
? ? ? ? ? ?get_comment_reply_index(id)
? ?max_id = response.get('data').get('max_id')
? ?#获取多页评论
? ?if max_id!=0:
? ? ? ?get_comment(mid, max_id)
由于回复评论代码、多页回复评论代码与首页评论代码、多页评论代码几乎相同,所以我们希望大家通过自己的思考把回复评论代码与多页回复评论代码编写出来,实在编写不出来可以联系作者。
保存数据
通过上面的步骤,我们已经成功把所有数据获取下来了,接下来就是保存评论数据了,主要代码如下所示:
#保存数据
def saving_data(data):
? ?db = pymysql.connect(host=host, user=user, password=passwd, port=port, db='weibo')
? ?cursor = db.cursor()
? ?sql = 'insert into comment_data(user_name,comment, data_time, mid) values(%s,%s,%s,%s)'
? ?try:
? ? ? ?cursor.execute(sql,data)
? ? ? ?db.commit()
? ?except Exception as e:
? ? ? ?print(e)
? ? ? ?db.rollback()
? ?db.close()
首先我们调用pymysql.connect()方法来连接数据库,通过.cursor()获取游标,再通过.execute()方法执行单条的sql语句,执行成功后返回受影响的行数,使用了try-except语句,当保存的数据不成功,就调用rollback()方法,撤消当前事务中所做的所有更改,并释放此连接对象当前使用的任何数据库锁。 好了,主要代码已经编写好了,接下来将编写启动爬虫代码,代码如下所示:
if __name__ == '__main__':
? ?mid=str(input('输入'))
? ?get_comment_index(mid)
结果展示
这里我们选取了只有4百多条评论的微博来进行演示,这样看评论数据不太直观,所以我们把评论以词云的方式展示,如下图所示:
好了,爬取微博评论并做词云图就讲到这里了,感谢观看!!!
|