前言
上篇文章介绍了如何获取Cookie并爬取微博评论,但评论千千万,我们可能只对点赞数高的评论感兴趣,也就是热门评论。但要想获取热门评论,用之前的方法得把评论爬个遍,然后按点赞数排序。这种做法一来费时,二来爬的不完整(除非把微博数据库全爬下来)。但微博后台已经帮我们给所有评论排了序,所以我们直接爬热门评论就好了。
获取Cookie
1、用浏览器进入手机版微博页面登陆微博,如进入https://m.weibo.cn/status/4173028302302955后登陆,再使用Chrome(其他浏览器也可以),Chrome是按F12打开开发者工具:
2、点击最上方一行的Network,找到左下的config,带⚙,应该很好找。点击,往下拉,可以看到当前访问的Request Head,其中有一个Cookie就是该账号登陆微博后的Cookie,这个待会儿会用到,如下图打码部分所示:
动态获取微博热门评论
首先,我们需要get评论内容的url,很简单,找到该微博页面的⚙hotflow(看不到就刷新一下),点开即可查看Request URL,如下图红框部分:
PS:不难发现url格式都类似,只是id不同。
然后在代码中设置url和headers:
#要爬取热评的起始url
url='https://m.weibo.cn/comments/hotflow?id=4281013208904762&mid=4281013208904762&max_id='
headers={
'Cookie':'替换为你的Cookie',
'Referer': 'https://m.weibo.cn/detail/4281013208904762',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
url和Referer中的id改成你想爬取网页的id即可。
这样可以爬下第一个热评,但我们想爬取更多热评就需要知道下一串热评的url。众所周知,手机上看热评需要不断下滑才能刷新,同理,我们下滑也可以加载到新的评论,新评论的⚙hotflow页面如下图所示:
可以发现新评论的url之前的url差距不大,但多了一个max_id=318050281200929。所以要想获得下一次的url,我们需要从某个地方得到这个max_id和max_id_type,但明显我们不能每次手动获取这个max_id和max_id_type,那从哪里可以得到这个值呢?
经我一哥们指点,在之前的返回的json文件的最后面有这个max_id和max_id_type。打开之前的⚙hotflow的preview,如下图所示:
然后我们看当前的⚙hotflow,如下图所示,果然有下一串热评的max_id和max_id_type:
所以我们只要不断更新这个max_id和max_id_type就可以实现热评的多次爬取:
maxpage = 1000
m_id = 0
id_type = 0
for page in range(0,maxpage):
print(page)
jsondata=get_page(m_id, id_type)
write_csv(jsondata)
results=parse_page(jsondata)
time.sleep(1)
m_id=results['max_id']
id_type=results['max_id_type']
最后,我们实现一下爬取函数就可以啦~是不是很简单?
环境配置
操作系统 | win10/64 |
语言 | python2 |
结果
从左到右依次是:用户名,发表时间,点赞数,所在楼层,来源及评论内容,为了便于查看,我们可以使用BeautifulSoup的get_text()让它变得更clearn:
结论
可以看到,有一条热评出现在第2441楼,如果我们爬取所有评论再排序可能要爬2000多条,才能爬完整前50条,而第64条出现在53284楼,所以学会爬热评是分析微博评论必不可少的。
100多条之后就没按点赞数来排序了,可能和微博后台的排序算法有关系。如果你不想爬太多设置一下maxpage就好了。
未来工作
如果能获取某些人或某类微博的id列表,或许可以挖到一些有意思的东西。
附完整代码及Github链接:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#爬取某条微博热评并存为csv文件
import requests
import time
import os
import csv
import codecs
import sys
import json
from bs4 import BeautifulSoup
reload(sys)
sys.setdefaultencoding('utf8')
#要爬取热评的起始url
url='https://m.weibo.cn/comments/hotflow?id=4312409864846621&mid=4312409864846621&max_id='
headers={
'Cookie':'Your Cookie',
'Referer': 'https://m.weibo.cn/detail/4312409864846621',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
#存为csv
path = os.getcwd()+"/weibo.csv"
csvfile = open(path, 'wb')
csvfile.write(codecs.BOM_UTF8)
writer = csv.writer(csvfile)
#First Row
writer.writerow(('Usename', 'Time', 'Like_count','Floor_number','Sourse', 'Comments'))
def get_page(max_id, id_type):
#参数
params={
'max_id':max_id,
'max_id_type': id_type
}
try:
r=requests.get(url, params=params, headers=headers)
if r.status_code==200:
return r.json()
except requests.ConnectionError as e:
print('error',e.args)
def parse_page(jsondata):
if jsondata:
items=jsondata.get('data')
item_max_id={}
item_max_id['max_id']=items['max_id']
item_max_id['max_id_type']=items['max_id_type']
return item_max_id
def write_csv(jsondata):
datas = jsondata.get('data').get('data')
for data in datas:
created_at = data.get("created_at")
like_count = data.get("like_count")
source = data.get("source")
floor_number = data.get("floor_number")
username = data.get("user").get("screen_name")
comment = data.get("text")
comment = BeautifulSoup(comment,'lxml').get_text()
#print jsondata.dumps(comment, encoding="UTF-8", ensure_ascii=False)
writer.writerow((username, created_at, like_count, floor_number, source,json.dumps(comment, encoding="UTF-8", ensure_ascii=False)))
maxpage = 1000
m_id = 0
id_type = 0
for page in range(0,maxpage):
print(page)
jsondata=get_page(m_id, id_type)
write_csv(jsondata)
results=parse_page(jsondata)
time.sleep(1)
m_id=results['max_id']
id_type=results['max_id_type']