python爬虫入门 实战(四)---爬“榜姐”话题微博及热门评论

(声明:该文章只作学习探讨,爬取内容不用作任何商业目的。)

经常混微博的同学应该知道“榜姐”(微博搞笑排行榜),她经常会在深夜发一些话题让粉丝自由发挥,一般来说这些微博的质量都比较高,这篇的需求就是爬取这些话题微博以及热门评论


图1.榜姐的微博

涉及知识:
1、request的基本使用
2、json解析
3、正则匹配
4、xpath的string函数过滤多余标签

本篇目录:

  1. 绕过登录访问博主的主页
  2. 寻找获取微博内容的api
  3. 寻找获取某条微博的所有评论的api
  4. 思路
  5. 完整代码
  6. 输出示例:(按Markdown格式的输出)
  7. 参阅

绕过登录访问博主的主页

一般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
每次失望一次,我就少做一件爱你的事,直到最后备注改成全名。取消特别关注,上线不主动找你,收起你送的东西,删掉你所有的照片,再也不偷偷看你的时候,就是该说再见的时候了。


参阅

免登录新浪微博爬虫系列之第一篇 单博主微博及评论数据



作者:王雨城
链接:http://www.jianshu.com/p/cc72f42ee0cb
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自blog.csdn.net/ssyyjj88/article/details/76189979