美文网首页全栈工程师
爬取新浪微博热搜

爬取新浪微博热搜

作者: 交易狗二哈 | 来源:发表于2017-04-15 19:47 被阅读2466次

    一、准备工作

    在搜索中查看榜单,先爬取实时热搜榜



    老样子,在Chrome中检查下元素,可以发现我们想要的内容


    但在网页源代码里并没有,看来这用到了 js 了。


    对于 js 动态网页,还是老样子俩种方法,但我们如果我们想要的是定时多次爬取热搜呢,这样子的话用 selenium 模仿浏览器显然效率很低,就用第一种吧,通过 json 数据爬取。详情见以前的文章
    监视下 XHR ,只有一个,并不是我们想要的

    那 js 呢。都找了一遍也没发现符合的,那怎么办?得来个详细的查找

    检查下大的标签,发现热搜标题都在 "star_name" 里,在网页源代码里搜下


    找到了50个匹配项,热搜榜正好是50个。看下都在<script> 这个javascript里,再仔细看下,里面有些链接不正是网页链接么,只是怪怪的。


    复制下 href 里的这个
    %E6%9C%9D%E9%B2%9C%E9%98%85%E5%85%B5
    这不是中文在网址的格式么,老样子,处理下

    >>> import urllib
    >>> a = '%E6%9C%9D%E9%B2%9C%E9%98%85%E5%85%B5'
    >>> urllib.parse.unquote(a)
    '朝鲜阅兵'
    

    咦,就是热搜第一个!
    每个热搜的链接只要在前面加上 'http://s.weibo.com/weibo/' 就行了。
    那么直接用 requests + re 获取 "star_name" 里的 href 的热搜关键词。
    这时又碰到了问题了,居然一直找不到,把 requests 获得的代码输出下


    比网页源代码中的文件多了些 \ , 25 。前面我们查看网页源代码时,热搜是存在 <script> 里的,这个 js 的作用是应该就是把这些链接加上一些字符干扰,不让轻易爬取。
    现在在回到 js 里找找,点开 player.js,复制下链接打开

    在里面发现大量的 replace。估计就是这页啦

    原理知道了,就没什么难了,用正则获取网页源代码中包含热搜链接的内容,再处理下就 OK 了

    二、代码

    import requests
    import re
    import urllib
    r = requests.get('http://s.weibo.com/top/summary?cate=realtimehot')
    html = r.text
    raw = re.findall(r'class=\\"star_name\\"><a href=\\"\\/weibo\\/(.*?)&Refer=top', html)
    titles = []
    names = []
    links = []
    
    for i in raw:
        titles.append(i.replace('25', ''))
    
    for i in titles:
        names.append(urllib.parse.unquote(i))
        link = 'http://s.weibo.com/weibo/' + i
        links.append(link)
    
    
    for k,v in enumerate(names, 1):
        print(k, v, links[int(k)-1])
    

    运行下

    1 朝鲜阅兵 http://s.weibo.com/weibo/%E6%9C%9D%E9%B2%9C%E9%98%85%E5%85%B5
    2 baby+小海绵 http://s.weibo.com/weibo/baby%2B%E5%B0%8F%E6%B5%B7%E7%BB%B5
    3 土豪这么滑雪 http://s.weibo.com/weibo/%E5%9C%9F%E8%B1%AA%E8%BF%99%E4%B9%88%E6%BB%91%E9%9B%AA
    4 学霸关晓彤 http://s.weibo.com/weibo/%E5%AD%A6%E9%9C%B8%E5%85%B3%E6%99%93%E5%BD%A4
    5 邓超+小何 http://s.weibo.com/weibo/%E9%82%93%E8%B6%85%2B%E5%B0%8F%E4%BD%95
    6 陈羽凡发文 http://s.weibo.com/weibo/%E9%99%88%E7%BE%BD%E5%87%A1%E5%8F%91%E6%96%87
    7 小镇诞生50年来唯一婴儿 http://s.weibo.com/weibo/%E5%B0%8F%E9%95%87%E8%AF%9E%E7%94%9F50%E5%B9%B4%E6%9D%A5%E5%94%AF%E4%B8%80%E5%A9%B4%E5%84%BF
    8 七岁女儿顺手牵羊 http://s.weibo.com/weibo/%E4%B8%83%E5%B2%81%E5%A5%B3%E5%84%BF%E9%A1%BA%E6%89%8B%E7%89%B5%E7%BE%8A
    9 大学其实是把整容刀 http://s.weibo.com/weibo/%E5%A4%A7%E5%AD%A6%E5%85%B6%E5%AE%9E%E6%98%AF%E6%8A%8A%E6%95%B4%E5%AE%B9%E5%88%80
    10 雄安新区凌晨发布政策 http://s.weibo.com/weibo/%E9%9B%84%E5%AE%89%E6%96%B0%E5%8C%BA%E5%87%8C%E6%99%A8%E5%8F%91%E5%B8%83%E6%94%BF%E7%AD%96
    

    三、优化

    要爬别的榜单只要换个榜单的网址就行了,那如果我们要更深入的分析呢,比如说爬取每个热点的热门评论等
    干脆用个类

    import requests
    import re
    import urllib
    
    class Top(object):
    
        def __init__(self, banner):
            self.banner = banner
            self.titles = []
            self.names = []
            self.links = []
    
        def get_top(self, url):
            r = requests.get(url)
            html = r.text
            raw = re.findall(r'class=\\"star_name\\"><a href=\\"\\/weibo\\/(.*?)&Refer=top', html)
            for i in raw:
                self.titles.append(i.replace('25', ''))
            for i in self.titles:
                self.names.append(urllib.parse.unquote(i))
                link = 'http://s.weibo.com/weibo/' + i
                self.links.append(link)
    
        def out_put(self):
            print(self.banner)
            for k,v in enumerate(self.names, 1):
                print(k, v, self.links[int(k)-1])
    
    
    if __name__ == '__main__':
    
        realtimehot = Top('实时热搜榜')
        realtimehot.get_top("http://s.weibo.com/top/summary?cate=realtimehot")
        realtimehot.out_put()
    
    
        pointhot = Top('热点热搜榜')
        pointhot.get_top("http://s.weibo.com/top/summary?cate=total&key=all")
        pointhot.out_put()
    

    运行下

    ================= RESTART: C:/Users/Why Me/Desktop/爬微博热搜2.py =================
                                       实时热搜榜                                   
    1 卓伟回应陈羽凡 http://s.weibo.com/weibo/%E5%8D%93%E4%BC%9F%E5%9B%9E%E5%BA%94%E9%99%88%E7%BE%BD%E5%87%A1
    2 范冰冰弟弟 http://s.weibo.com/weibo/%E8%8C%83%E5%86%B0%E5%86%B0%E5%BC%9F%E5%BC%9F
    3 Xplay6库里定制版 http://s.weibo.com/weibo/Xplay6%E5%BA%93%E9%87%8C%E5%AE%9A%E5%88%B6%E7%89%88
    4 许昕+丹羽孝希 http://s.weibo.com/weibo/%E8%AE%B8%E6%98%95%2B%E4%B8%B9%E7%BE%BD%E5%AD%9D%E5%B8%8C
    5 张信哲薛之谦 http://s.weibo.com/weibo/%E5%BC%A0%E4%BF%A1%E5%93%B2%E8%96%9B%E4%B9%8B%E8%B0%A6
    6 女子遭家暴身亡 http://s.weibo.com/weibo/%E5%A5%B3%E5%AD%90%E9%81%AD%E5%AE%B6%E6%9A%B4%E8%BA%AB%E4%BA%A1
    7 你是手机的爸爸 http://s.weibo.com/weibo/%E4%BD%A0%E6%98%AF%E6%89%8B%E6%9C%BA%E7%9A%84%E7%88%B8%E7%88%B8
    8 郑渊洁买10套房 http://s.weibo.com/weibo/%E9%83%91%E6%B8%8A%E6%B4%81%E4%B9%B010%E5%A5%97%E6%88%BF
    9 交警一查朋友也是酒驾 http://s.weibo.com/weibo/%E4%BA%A4%E8%AD%A6%E4%B8%80%E6%9F%A5%E6%9C%8B%E5%8F%8B%E4%B9%9F%E6%98%AF%E9%85%92%E9%A9%BE
    10 陈羽凡朋友圈 http://s.weibo.com/weibo/%E9%99%88%E7%BE%BD%E5%87%A1%E6%9C%8B
    ...
    

    爬取热搜里的有关内容

    如果要获取每个热搜里面的相关新闻呢


    例如下面这些


    还是一样,我们找到内容的大标签,这次我们先在网页源代码里找找看



    居然跟前面找热搜榜是一样的,这次文字以 utf-8 的形式存在里面,如下面这些,怎么转化为中文呢,可以直接print,以前关于编码的文章有别的方法介绍,这里就不多说了。


    还是老样子加了点干扰防止爬的。。提取的好辛苦。直接上代码了,有点麻烦。

    import requests
    import re
    import urllib
    import time
    
    class Top(object):
    
        def __init__(self, banner):
            self.banner = banner
            self.titles = []
            self.names = []
            self.links = []
            self.summary = {}
            self.headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"}
    
        def get_top(self, url):
            r = requests.get(url, headers=self.headers)
            html = r.text
            raw = re.findall(r'class=\\"star_name\\"><a href=\\"\\/weibo\\/(.*?)&Refer=top', html)
            for i in raw:
                self.titles.append(i.replace('25', ''))
            for i in self.titles:
                self.names.append(urllib.parse.unquote(i))
                link = 'http://s.weibo.com/weibo/' + i
                self.links.append(link)
                time.sleep(1.5)
                self.get_news(link)
                #print('Down One Hot')
    
        def get_news(self, link):
            new = []
            ne = []
            n = []
            z = []
            
            r2 = requests.get(link, headers=self.headers)
            html2 = r2.text
            news = re.findall(r'node-type=\\"feed_list_content\\" nick-name=\\"(.*?) <', html2)
            for i in news:
                c = i.encode()
                new.append(c.decode('unicode_escape'))
            for i in new:
                a = re.sub(r'\s', '',i).replace('"><emclass="red">', "-").replace('<\\/em>', '-')
                ne.append(a)
            for i in ne:
                s = re.sub(r'<.*?>|\u200b','', i)
                n.append(s)
            for i in n:
                z.append(i.split('">'))
            self.summary[link] = z
    
    
        def out_put(self):
            print(self.banner.center(75))
            for k,v in enumerate(self.names, 1):
                print(k, v, self.links[int(k)-1])
                for i in self.summary[self.links[int(k)-1]]:
                    try:
                        print('{} :  {}'.format(i[0], i[1]))
                    except:
                        print('信息缺失')
    
    if __name__ == '__main__':
    
        realtimehot = Top('实时热搜榜')
        realtimehot.get_top("http://s.weibo.com/top/summary?cate=realtimehot")
        realtimehot.out_put()
    
    
        pointhot = Top('热点热搜榜')
        pointhot.get_top("http://s.weibo.com/top/summary?cate=total&key=all")
        pointhot.out_put()
                    
    

    运行下:

    1 白百何颁奖 http://s.weibo.com/weibo/%E7%99%BD%E7%99%BE%E4%BD%95%E9%A2%81%E5%A5%96
    南都娱乐周刊 :  #第八届导演协会年度盛典#范冰冰凭借《我不是潘金莲》获得2017导演协会年度盛典最佳女演员奖,再得影后!白-百何-作为颁奖-嘉宾上台为冰冰颁奖-。(内场图via@吴尊家的宝)新浪电影的...
    明星那些事儿 :  #白百合颁奖#
    北京晨报 :  #第八届导演协会年度盛典#范冰冰凭借《我不是潘金莲》获得2017导演协会年度盛典最佳女演员奖,再得影后!白-百何-作为颁奖-嘉宾上台为冰冰颁奖-。白-百何-现场穿的非常低调。
    信息缺失
    吐槽污 :  2017年4月22日,第八届中国电影导演协会年度盛典举行,刚经历了出轨风波的白-百何-在颁奖-环节登台亮相,为范冰冰颁发年度女演员奖项。P.S.范冰冰:第一次被别人抢了风头
    娱乐圈avi :  #白百何颁奖-#导演协会年度表彰盛典@范冰冰凭借《我不是潘金莲》获最佳女演员,白百何登场为其颁奖。恭喜范冰冰再拿影后!
    方晓东 :  范冰冰凭借《我不是潘金莲》获得2017导演协会年度盛典最佳女演员奖!#白百何颁奖-#,现场穿着非常低调。这个颁奖人你服不服!秒拍视频
    信息缺失
    直播新合肥 :  #白百何颁奖-#恭喜范冰冰凭借《我不是潘金莲》获得2017导演协会年度盛典最佳女演员奖,演技棒!当之无愧影后!最近舆论不断的白百何作为颁奖嘉宾。又一次上了头条。
    就是不吃饭呢 :  【白百何颁奖-前片场照曝光还在剧组智斗小朋友】白百何在“出轨门”后,便“销声匿迹”,除了一封迟来的声明,大众便再没见到她的身影。22日,白百何意外现身某盛典,终于再度现身。其实,此前也有博主曝光过白百何近照,这天她一身商务范look,举手投足间满满的白骨精画风
    g王传民 :  哈哈哈大家好
    sherry向斯瑞 :  今天一看微博又是关于白-百何-的,说什么白-百何-出轨后颁奖-我想问,人家怎么出轨了。陈羽凡和白百何两年前就离婚了,只是没有公布,在这期间人家不可以有新欢吗?真的是奇了怪了,离了婚找新欢还算出轨了不成,真的是太没有道理了。这真心不叫出轨好嘛,关于陈羽凡,两个人之间没有了感情离婚了也的确让人...展开全文c
    信息缺失
    申请个人微博加V-互粉橙V服务 :  有时候,一个人生气是因为他认为你拒绝的不仅仅是他的建议,而是你根本瞧不起他这个人。所以,在白百何颁奖-拒绝某个人建议的时候,要简单地陈述两个你赞成李宏毅的原因,然后再陈述你为什么要按自己skt的方式来做。如果可能,征询地球护卫队对其他一些事情的意见,让他明白,你其实是非常尊重他的。
    首都在线 :  #白百何颁奖-#在#第八届导演协会年度盛典#上,#白百何#给范冰冰颁奖。@中国电影导演协会
    护肤达人__David :  #白百何颁奖-#看到说出轨门的白百何我是有点不大理解的,陈羽凡和白百何不是已经发表声明说是已经离婚了吗?那么白百何就不能找男人了?何来的出轨?还有白百何给范冰冰颁奖这不是对白百何演技的肯定吗?不说白百何演的怎么怎么好,我觉得最起码看的过去
    ...
    

    有些错误的地方有时间再查看下,现在先直接异常处理跳过,打印 "信息缺失"
    发现了个问题,在 20 条热搜后,查不到对应的内容了



    用浏览器打开热搜看下,原来是被新浪封ip了
    奇怪,都设置 1.5 秒 延时了
    那就只能设置更久或用selenium了,或者再看看有别的方法不


    暂时先这样子,得先破解了验证码再继续完善别的功能了

    相关文章

      网友评论

      本文标题:爬取新浪微博热搜

      本文链接:https://www.haomeiwen.com/subject/plunattx.html