小爬虫

爬取panda.tv主播name和观看人数

1.  c1.py


# 分析前奏:
    # 首先:明确目的;
    # 其次:找到数据对应的网页;
    # 然后:分析网页的结构找到数据所在标签位置;

# 书写代码步骤
    # 第一步:模拟HTTP请求,向服务器发送请求,获取到服务器返回给我们的HTML;
    # 第二步:用正则表达式提取我们要获取的数据(名字,人气)
    # 第三步:精炼数据

# 断点调试
    # 加入断点 (在需要查看的变量后再加一行,在这行打上断点)
    # 按F5进入断点调试
    # F10单目运行代码
    # F5进入下一个断点
    # F11进入一个函数内部

# 说明
    # 找到闭合标签,定位姓名和观看人数的信息
    # 在vscode左侧有个小虫子,在断点调试时点击它可以查看所有变量
    # 匹配所有字符 \s\S  
    # 非贪婪  ?
    # 利用组提取标签内的部分  ()

# 小爬虫案例小结
    # go() 是一个入口方法,也是一个组方法 (也能清晰看到数据的处理流程,也方便维护)
    # 推荐多写一些平级函数,少用嵌套
    # 多行注释
    # 利用空行增加代码 '块' 的概念 (不能滥用空行)
    # 不要在一个函数中写太多行代码  (建议10-20,最多不超过30行)
        # 这时的函数名,就是对该函数的最好说明
        # 函数越小,越有利于复用

# 对于一些中大型爬虫项目
    # BeautifulSoup,Scrapy这样的爬虫框架,更加方便提炼代码 (其实精炼的就是正则表达式的代码)
    # 爬虫,反爬虫,反反爬虫
    # 对于爬回的海量数据,怎样提取,精炼,利用
    # ip 可能会被封,代理ip库

2.  爬虫部分  spider.py

import re
from urllib import request
# 断点调试
class Spider():
    # 网络地址
    url = 'http://www.panda.tv/cate/lol'
    # 包裹name和观看人数最近的父节点
    root_pattern = '<div class="video-info">([\s\S]*?)</div>'
    # 第一次先匹配到 video-nickname,第二次再匹配里的name
    name_pattern1 = '<span class="video-nickname"[\s\S]*?</span>'
    name_pattern2 = '</i>([\s\S]*?)</span>'
    # 先匹配到 video-number,第二次再匹配到里边的number
    number_pattern1 = '<span class="video-number">[\s\S]*?</span>'  
    number_pattern2 = '</i>([\s\S]*?)</span>'      

    # 获取总的HTML代码
    def __fetch_content(self):
        r = request.urlopen(Spider.url) 
        # bytes 
        htmls = r.read()
        # 将bytes转为HTML的utf-8编码
            # str(第一个参数为bytes,第二个参数为encoding关键字的编码格式)
        htmls = str(htmls,encoding='utf-8')       
        return htmls
    
    # 分析HTML代码
    def __analysis(self,htmls):
        root_html = re.findall(Spider.root_pattern,htmls)
        anchors = []
        for html in root_html:
            name = re.findall(Spider.name_pattern1,html)
            # name为list类型,只有一项,正则表达式为str的匹配
            name = re.findall(Spider.name_pattern2,name[0])
            number = re.findall(Spider.number_pattern1,html)
            # number为list类型,只有一项,正则表达式为str的匹配
            number = re.findall(Spider.number_pattern2,number[0])
            anchor = {'name':name,'number':number}
            anchors.append(anchor)

        return anchors

    # 精炼数据(数据不太规范,进行精炼)
    def __refine(self,anchors):
        # 通过内置的strip去除空格,精炼数据
        l = lambda anchor: {
            'name':anchor['name'][0].strip(),
            'number':anchor['number'][0]
        }

        return map(l,anchors)
    
    # 对数据排序
    def __sort(self,anchors):
        # anchors为dict,需要指定通过那一项为排序标准,第三个参数为升(False(默认))/降(True)序的指定
        anchors = sorted(anchors,key = self.__sort_seed,reverse=True)
        return anchors
    
    def __sort_seed(self,anchor):
        # 正则匹配获取人数
        r = re.findall('\d*',anchor['number']) 
        # 转为数字类型
        number = float(r[0])
        # 将万换算为数值
        if '万' in anchor['number']:
            number *= 10000 
        return number

    # 展示函数
    def __show(self,anchors):
        # 这里打印出排名,主播name和光看人数
        for rank in range(0,len(anchors)):
            print('rank ' + str(rank + 1)
            + ' : ' + anchors[rank]['name']
            + '        ' + anchors[rank]['number']
            )

    # go是一个总控方法
    def go(self):
        htmls = self.__fetch_content()
        anchors = self.__analysis(htmls)
        anchors = list(self.__refine(anchors)) 
        anchors = self.__sort(anchors)
        self.__show(anchors)

spider = Spider()
spider.go()

(备注:以上内容来自七月老师的学习笔记,仅作为学习使用)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值