(声明:该文章只作学习探讨,爬取内容不用作任何商业目的。)
经常混微博的同学应该知道“榜姐”(微博搞笑排行榜),她经常会在深夜发一些话题让粉丝自由发挥,一般来说这些微博的质量都比较高,这篇的需求就是爬取这些话题微博以及热门评论。
图1.榜姐的微博涉及知识:
1、request的基本使用
2、json解析
3、正则匹配
4、xpath的string函数过滤多余标签
本篇目录:
- 绕过登录访问博主的主页
- 寻找获取微博内容的api
- 寻找获取某条微博的所有评论的api
- 思路
- 完整代码
- 输出示例:(按Markdown格式的输出)
- 参阅
绕过登录访问博主的主页
一般pc站信息比较全,但同时也不太容易爬取,因为一些登录验证的问题或者其他原因。所以一般写爬虫,pc站比较困难的时候,我们可以选择m站或者wap站。
这篇我们就爬取微博的m站,也就是移动端的站点m.weibo.cn。我们选择它的一个重要原因就是,可以不用登录。例如,要访问某博主(这里以“榜姐”为例)的微博主页,只需要访问:
m.weibo.cn/u/1713926427
u是user的意思,后面的数字就是她的用户id。我们可以通过在pc端自己手动登录,搜索某个博主,访问其主页时,按F12打开Network抓包找到id号码。如图:
图2.找到用户id这是通用的方法,因为“榜姐”有个性域名,所以需要这样找,其他没有个性域名的用户,通过搜索找到以后,其实不难发现搜索结果上的博客地址里就有用户id。
寻找获取微博内容的api
找到用户id后,我们用来访问m站,在Network搜索api发现有两个已经发送的api请求。
图3.榜姐微博主页此时在“主页”页面,我们点击“微博”,会发现又发送了一个api请求,这就是我们要找的获取所有微博的api。就是下图中containerid是107开头的这条,我们点击查看一下详细信息。
图4.新发送的api请求在右边选择preview预览一下json,可以发现在cards中任选一个card,其中的mblog标签下果然有我们要的博文数据。说明这就是我们要找的api。
图5.找到第一个api(注:在cardlistInfo标签下,可以发现这个第一页对应的page值是2,说明page是从2开始的,之后会用到page参数来翻页。同时注意一下这个scheme里的url,之后会讲到。)
接下来我们来分析一下这个api的参数,很明显这是一个用get方式发送的请求,从headers里也可以看到请求方式是GET。所以只需要分析?后面这些参数就可以了。
https://m.weibo.cn/api/container/getIndex?type=uid&value=1713926427&containerid=1076031713926427
显然type=uid肯定是不变的,value=1713926427就是用户的id值,经过对比也可以发现后面的containerid其实只是107603后跟着用户id。多验证几个用户会发现确实如此。
寻找获取某条微博的所有评论的api
看到之前提到的scheme,将它的url复制粘贴到地址栏访问,可以发现是进入到了这条微博,在Network搜索api发现我们需要的获取评论的api。
图6.找到第二个api分析一下第二个api的参数(在控制台里对api右键可以copy这条url)
https://m.weibo.cn/api/comments/show?id=4112893156959108&page=1
显而易见,id就是该条微博的id,page是评论的翻页参数。
思路
获得了两个api,我们接下来就要写代码进行爬取了。思路很清晰:
1、获取目标博主id。
2、根据博主id,用第一个api获取指定页的微博的json返回(包括内容和对应id)。
3、根据微博id,用第二个api获取评论的json返回。
4、解析json即可。这里推荐一个比较好用的在线解析json的网站: json.cn 。当然,你也可以在控制台的Network里用Preview对json进行预览。
完整代码
细节见注释~
# -*- coding:utf-8 -*-
'''
Created on 2017年5月30日
@author: wycheng
'''
from lxml import html
import requests
import json
import re
class CrawlWeibo:
# 获取指定博主的所有微博card的list
def getWeibo(self,id,page):#id(字符串类型):博主的用户id,page(整型):微博翻页参数
url='https://m.weibo.cn/api/container/getIndex?type=uid&value='+id+'&containerid=107603'+id+'&page='+str(page)
response=requests.get(url)
ob_json=json.loads(response.text)
list_cards=ob_json['cards']
return list_cards# 返回本页所有的cards
# 返回某条微博的热门评论的list
def getComments(self,id,page):# id(字符串类型):某条微博的id,page(整型):评论翻页参数
url='https://m.weibo.cn/api/comments/show?id='+id+'&page='+str(page)
response=requests.get(url)
ob_json=json.loads(response.text)
list_comments=ob_json['hot_data']
return list_comments
def printAllTopic(self,page):
list_cards=self.getWeibo('1713926427',page)
# 遍历当页所有微博,输出内容,并根据id查找输出热门评论
for card in list_cards:
if card['card_type']==9:# 过滤出微博,card_type=9的是微博card,card_type=11的是推荐有趣的人
id=card['mblog']['id']
text=card['mblog']['text']
if re.search('___', text)!=None:# 用正则匹配,将博文有下划线的微博过滤出来,有下划线的是“话题微博”
print '***'
print u"### 话题: "+text+'\n'
#根据微博id获取热门评论,并输出
list_comments=crawl_weibo.getComments(id, 1)# 热门评论只需要访问第一页
count_hotcomments=1
for comment in list_comments:
created_at=comment['created_at']# 发表日期时间
like_counts=comment['like_counts']# 点赞数
text=comment['text']# 评论内容
tree=html.fromstring(text)
text=tree.xpath('string(.)')# 用string函数过滤掉多余标签
name_user=comment['user']['screen_name']# 评论者的用户名
source=comment['source']# 来源于哪个终端
if source=='':
source=u'未知'
pic_url=''# 评论内容的图片
if 'pic' in comment:
pic_url=comment['pic']['url']
# 输出评论数据
print str(count_hotcomments),': **',name_user,'**',u' **发表于:**'+created_at,u' **点赞:**'+str(like_counts)+u' **来自:**'+source
print text+'\n'
count_hotcomments=count_hotcomments+1
print '***'
#实例化爬虫类并调用成员方法进行输出
crawl_weibo=CrawlWeibo()
crawl_weibo.printAllTopic(2)# 只输出一页进行示例展示
输出示例:(按Markdown格式的输出)
话题: 你是在什么时候决定放弃一个人的 _____________________________
1 : ** 沢与樹 ** 发表于:05-29 00:00 点赞:65690 来自:iPhone 6s
“当我点开这条微博的时候,我就知道我还没放弃”
2 : ** 华水第一帅 ** 发表于:05-29 00:41 点赞:35305 来自:红米Note 3
带上你的备注,滚回你的大众分组。
3 : ** 关键我叫梅仁耀丶 ** 发表于:05-29 00:00 点赞:49771 来自:未知
她恋爱了。
4 : ** 圈儿大王 ** 发表于:05-29 00:00 点赞:46084 来自:未知
发现自己爱他卑微到没有了自尊,终于攒够了失望,狠心决定还是离开吧。一瞬间心如刀绞,一瞬间如释重负。有关于你,绝口不提,但如果有下次,可不可以换你,爱我到疯掉
5 : ** 饭真的好好吃啊 ** 发表于:05-29 00:08 点赞:37621 来自:猫吃了那个iPhone
“你哭够了没有,哭够了我挂电话了。”
6 : ** 你猜我是不是你妈啊 ** 发表于:05-29 00:03 点赞:35029 来自:vivo X5·K歌之王
3分钟两万评论 被爱的那两万人真幸福
7 : ** 纳达斯克 ** 发表于:05-29 00:00 点赞:30216 来自:未知
真心喜欢的人好像从来都放弃不了
8 : ** qqyyhh丶 ** 发表于:05-29 00:02 点赞:25563 来自:iPhone 6
每次失望一次,我就少做一件爱你的事,直到最后备注改成全名。取消特别关注,上线不主动找你,收起你送的东西,删掉你所有的照片,再也不偷偷看你的时候,就是该说再见的时候了。
网友评论