美文网首页Python
12、实战:原生爬虫

12、实战:原生爬虫

作者: IT_Freak | 来源:发表于2018-12-25 14:31 被阅读0次

目标:爬取熊猫TV某个分类下面主播的人气排行

分析网站结构

  1. 使用Chrome浏览器
  2. F12查看HTML信息,Ctrl+Shift+C鼠标选取后找到对应的HTML。
  3. 文本分析并提取信息——正则表达式。

搜索引擎,今日头条等app本质上的技术就是爬虫

设计步骤:

  1. 明确目的
  2. 找到数据对应网页
  3. 分析网页的结构,找到数据所在标签的位置
  4. 模拟HTTP请求,向服务器发送请求,获取到服务器返回给我们的HTML
  5. 用正则表达式提取我们要的数据
  6. 处理数据

HTML结构分析基本原则

1. 寻找到标签、标识符,使之能够定位要抓取的信息
  • 尽量选取具有唯一性的标签
  • 尽量选取最接近于数据的标签
2. 把多个个数据看成是一组数据并再次寻找标签
  • 尽量选取可以闭合的标签(父级标签),并包裹其需要的数据。

提取顺序:htmls->video-info->video-nickname/video-number->提取数据

正则匹配

匹配父级标签
root_pattern = '<div class="video-info">([\s\S]*?)</div>'  #此处要使用非贪婪,否则会无限匹配下去。

匹配名字和人数
name_pattern = '</i>([\s\S]*?)</span>'
number_pattern = '<i class="ricon ricon-eye"></i>([\s\S]*?)</span>'

数据精炼

def __refine(self,anchors):
        l = lambda anchor:{
            'name':anchor['name'][0].strip(),   #去除全部空白字符
            'number':anchor['number'][0] #列表转化为单一的字符串
            }
        return map(l,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 __sort(self,anchors):
    anchors = sorted(anchors,key = self.__sort_seed,reverse = True)
    #key确定字典中哪个元素作为比较对象
    #sorted()默认升序排列,reverse = True降序
    return anchors

VSCode中调试代码

断点调试:F5启动,F10单步,F5跳断点,F11进内部

整体代码:
from urllib import request
import re

class Spider():
    url = 'https://www.panda.tv/cate/lol'
    root_pattern = '<div class="video-info">([\s\S]*?)</div>'
    name_pattern = '</i>([\s\S]*?)</span>'
    number_pattern = '<i class="ricon ricon-eye"></i>([\s\S]*?)</span>'
    
    def __fetch_content(self):
        r = request.urlopen(Spider.url) #获取url的界面
        htmls = r.read()    #读取界面(获得字节码)
        htmls = str(htmls, encoding='utf-8')    #字符串转码
        return htmls
    
    def __analysis(self,htmls):
        root_html = re.findall(Spider.root_pattern, htmls)
        anchors = []
        # print(root_html[0])
        for html in root_html:
            name = re.findall(spider.name_pattern, html)
            number = re.findall(spider.number_pattern, html)
            anchor = {'name': name, 'number': number}
            anchors.append(anchor)
        # print(anchors[0])
        return anchors

    def __refine(self,anchors):
        l = lambda anchor:{
            'name':anchor['name'][0].strip(),   #去除全部空白字符
            'number':anchor['number'][0] #列表转化为单一的字符串
            }
        return map(l,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 __sort(self,anchors):
        anchors = sorted(anchors,key = self.__sort_seed,reverse = True)
        #key确定字典中哪个元素作为比较对象
        #sorted()默认升序排列,reverse = True 降序
        return anchors

    def __show(self,anchors):
        for rank in range(0,len(anchors)):
            print('rank ' + str(rank + 1) +':' + ' ' + anchors[rank]['name'] +
            '————' + anchors[rank]['number'])

    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()

相关文章

网友评论

    本文标题:12、实战:原生爬虫

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