• 用Python爬取斗鱼网站的一个小案例


    思路解析:

      1、我们需要明确爬取数据的目的:为了按热度查看主播的在线观看人数

      2、浏览网页源代码,查看我们需要的数据的定位标签

            

      3、在代码中发送一个http请求,获取到网页返回的html(需要注意的是,许多网页都有反爬虫机制,所以需要在请求中添加user-agent,伪装成客户端访问)

      4、对获取到的html进行分析,使用正则表达式提取我们需要的部分(需要注意的是要把主播名称和观看人数所在的块整个提取,分别提取的话如果网页设计不规律的话很难对应)

      5、将得到的单个主播的数据存储在字典中,并把所有主播的数据存储在list中

      6、如果抓取到的数据中包含空格换行等无用字符,还需要对数据进行精炼。

      7、对抓取到的数据从大到小进行排序(需要注意的是:我们抓取到的数据是字符串,并且单位可能是人或者万人,所以要对观看人数进行处理)

      8、将排好序的数据遍历输出。

    由于斗鱼网站的网页是采用模板实现的,案例是抓取王者荣耀的主播的数据,想抓取别的类目的话,只需要修改url即可~

    代码实现:

    '''
        爬取斗鱼网站的王者荣耀分类主播的观看人数和主播名字,并按热度排名
    '''
    from urllib import request
    from io import BytesIO
    import gzip
    import re
    
    
    class Spider():
        url = 'https://www.douyu.com/g_wzry'
    
        # 根节点的字符串匹配正则表达式,匹配除了根节点中间的所有字符,非贪婪模式,找到第一个</div>就结束
        root_pattern = '<div class="DyListCover-info">([sS]*?)</div>'
    
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36'}
    
        # 观看人数匹配字符串
        number_pattern_str = '<span class="DyListCover-hot is-template">([sS]*?)</span>'
        # 观看人数的字符串,删除前面的icon部分
        number_pattern = '<svg><use xlink:href="#icon-hot_8a57f0b"></use></svg>'
    
        name_pattern_str = '<h2 class="DyListCover-user is-template">([sS]*?)</h2>'
        name_pattern = '<svg><use xlink:href="#icon-user_c95acf8"></use></svg>'
    
        # 抓取自定网页内容并解码
        def __fetch_content(self):
            # 发送一个http的请求,获取返回的html代码
            req = request.Request(Spider.url, headers=Spider.headers)
            htmls = request.urlopen(req).read()
    
            # 解码
            buff = BytesIO(htmls)
            f = gzip.GzipFile(fileobj=buff)
            htmls = f.read().decode('utf-8')
            return htmls
    
        # 分析抓取内容,选取标签时尽量选取闭合标签,标签成组的选择好对应
        def __analysis(self, htmls):
            # 获取到需要的全部数据
            root_html = re.findall(Spider.root_pattern, htmls)
            # 由于网页中一个块有两个相同的class类,其中第一个主播介绍
            # 第二个才是需要的数据,所以选取奇数下标元素
            root_info_html = root_html[1::2]
    
            # 最后获取到的数据列表
            anchors = []
            # 遍历列表,提取用户名和观看人数
            for html in root_info_html:
                # 提取到的是带icon的部分
                watch_num_str = re.findall(Spider.number_pattern_str, html)
                # 剔除icon部分
                watch_num = re.sub(Spider.number_pattern, '', watch_num_str[0])
    
                # 提取带icon的name的部分
                name_str = re.findall(Spider.name_pattern_str, html)
                name = re.sub(Spider.name_pattern, '', name_str[0])
    
                # 将名字和观看人数用字典存储,最后再用列表存储每个主播的数据
                anchor = {'name': name, 'number': watch_num}
                anchors.append(anchor)
    
            return anchors
    
        # 精炼函数
        # def __refine(self, anchors):
        #    lam = lambda anchor: {'name': anchor['name'][0], 'number': anchor['number'][0]}
        #    return map(lam, anchors)
    
        # 排序
        def __sort(self, anchors):
            anchors = sorted(anchors, key=self.__sort_key, reverse=True)
            return anchors
    
        # 排序规则
        def __sort_key(self, anchor):
            # 提取数字并计算
            r = re.findall('d*', anchor['number'])
            number = float(r[0])
            if '' in anchor['number']:
                number *= 10000
            return number
    
        # 显示数据
        def __show(self, anchors):
            # for anchor in anchors:
            #    print(anchor['name'], ':', anchor['number'])
            for rank in range(0, len(anchors)):
                print("Rank ", rank+1, ": ", anchors[rank]['name'], "    ", anchors[rank]['number'])
    
        # 入口方法
        def go(self):
            htmls = self.__fetch_content()
            anchors = self.__analysis(htmls)
            anchors = self.__sort(anchors)
            self.__show(anchors)
    
    
    spider = Spider()
    spider.go()

      

  • 相关阅读:
    python协程爬取某网站的老赖数据
    python异步回调顺序?是否加锁?
    go语言循环变量
    使用memory_profiler异常
    安装python性能检测工具line_profiler
    等我!
    pytorch代码跟着写
    Python异常类型总结
    Python项目代码阅读【不断更新】
    夏令营体会
  • 原文地址:https://www.cnblogs.com/syq816/p/12637776.html
Copyright © 2020-2023  润新知