用Python实现原生爬取某牙直播平台数据

最近学习了一大堆和大数据相关的东西,Hadoop、Elastic、Python等。写一个简单的实战项目贯通一下。爬取一下某牙直播平台的人气排行。

一.确定自己需要的数据,并找到最适合爬取的页面

首先我们需要找到最适合爬取的页面。一般而言最好是一个展示列表。在这个爬虫,最适合的页面肯定是游戏分类页面。

  • 如图所示红框圈出的部分,是我们需要的数据。

二.分析数据所在的标签

	用浏览器的开发者调试工具,可以很方便的查看标签信息。在选取标签的时候,我们最好遵循两个原则:
  1. 尽量寻找具有唯一性的标签
  2. 尽量距离所需内容最近的定位标签

用Python实现原生爬取某牙直播平台数据_第1张图片
我们需要的是,主播名和观看人数标签,这两个标签被一个打的 li 标签所包含。不难发现每一个 li 包含一个主播的信息。隐藏这正是我们需要的信息。

三.模拟http获取服务器返回的html
分析完页面数据,终于可以开始编写爬虫代码了。

    url = 'https://www.huya.com/g/wzry'
    headers = {
    'cookie': 'Hm_lvt_51700b6c722f5bb4cf39906a596ea41f=1564389526; __yasmid=0.40853709224889045; __yamid_tt1=0.40853709224889045; __yamid_new=C88A54814D100001D1791CD16F0019D9; _yasids=__rootsid%3DC88A54814DB0000113A7D4A71FB71BBD; PHPSESSID=vbo6lo3mjm62rmrc3hpe4o03s0; Hm_lpvt_51700b6c722f5bb4cf39906a596ea41f=1564389529; udb_passdata=3; SoundValue=0.50; alphaValue=0.80; isInLiveRoom=true',
    'User-Agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
    }

    @staticmethod
    def __fetch_content(self):
        '''
        执行网页访问
        '''
        req = request.Request(Spider.url, None, Spider.headers)
        r = request.urlopen(req)
        htmls = r.read()
        htmls = str(htmls, encoding='utf-8')
        return htmls
  • 需要注意的是,大多数网站都有简单的返爬虫验证,会判断你的访问,是否是正常通过浏览器访问的,会验证浏览器的cookie信息等。
  • 同样使用浏览器调试工具,我们可以很方便的查看页面请求的header 头信息,并进行模拟.
  • 用Python实现原生爬取某牙直播平台数据_第2张图片

四.用正则表达式提取我们需要的信息

  • 现在正常情况,我们可以获取到页面的html代码。如果有获取不到的情况,还是网站反爬虫方面的限制。这里就不做过多研究了。

  • 那么如何从上千行代码中提取到自己需要的数据呢?这里就需要借助强大的正则匹配了。

  • 上面我们分析了,我们需要获取的是

  • 这个为开头的标签,因此正则表达式不容易就设置为
  • (.*)?
  • 然后正常情况下,我们需要对获取的每组 li 内部的元素,再进行正则匹配,提取我们需要的数据。然而在这次的爬虫中,对方使用了接口,动态获取数据。无法通过标签获取数据,但是我们可以直接获取返回的 json 数据,然后转成dict。进行筛选处理。

	root_pattern = '(?<=var LIST_DATA =).*?](?=;)'
    def __analysis(self, htmls):
        '''
        正则匹配页面数据标签
        '''
        html = re.findall(Spider.root_pattern, htmls)
        html = html[0].strip("'")
        html = html.strip(" ")
        # json转码
        return json.loads(html)

五.存储和展示数据

  • 最终我们获取到了数据了,in this case 我们需要对数据进行简单的排序,使用python 内置的 sorted() 函数,可以很轻松的实现这个功能。

贴上所有代码:

from urllib import request
import re
import json


class Spider():
    url = 'https://www.huya.com/g/wzry'
    root_pattern = '(?<=var LIST_DATA =).*?](?=;)'
    headers = {
    'cookie': 'Hm_lvt_51700b6c722f5bb4cf39906a596ea41f=1564389526; __yasmid=0.40853709224889045; __yamid_tt1=0.40853709224889045; __yamid_new=C88A54814D100001D1791CD16F0019D9; _yasids=__rootsid%3DC88A54814DB0000113A7D4A71FB71BBD; PHPSESSID=vbo6lo3mjm62rmrc3hpe4o03s0; Hm_lpvt_51700b6c722f5bb4cf39906a596ea41f=1564389529; udb_passdata=3; SoundValue=0.50; alphaValue=0.80; isInLiveRoom=true',
    'User-Agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
    }

    @staticmethod
    def __fetch_content(self):
        '''
        执行网页访问
        '''
        req = request.Request(Spider.url, None, Spider.headers)
        r = request.urlopen(req)
        htmls = r.read()
        htmls = str(htmls, encoding='utf-8')
        return htmls

    def __analysis(self, htmls):
        '''
        正则匹配页面数据标签
        '''
        html = re.findall(Spider.root_pattern, htmls)
        html = html[0].strip("'")
        html = html.strip(" ")
        # json转码
        return json.loads(html)
    
    def __refine(self, anchors):
        '''
        精炼数据
        '''
        datas = []
        for anchor in anchors:
            data = {
                'name' : anchor['nick'],
                'number' : anchor['totalCount']
            }
            datas.append(data)
        return datas
    
    def __sort(self, anchors):
        # 数据排序
        anchors = sorted(anchors, key=self.__sort_sedd, reverse = True)
        return anchors

    def __sort_sedd(self, anchor):
        # 排序处理
        return int(anchor['number'])

    def __show(self, anchors):
        '''
        展示排行榜数据
        '''
        for anchor in anchors:
            print(anchor['name'] + '----' + anchor['number'] + '人')

    def go(self):
        '''
        入口方法
        '''
        htmls = self.__fetch_content(self)
        anchors = self.__analysis(htmls)
        anchors = self.__refine(anchors)
        anchors = self.__sort(anchors)
        self.__show(anchors)


spider = Spider()
spider.go()

贴上整个过程简单的思维导图( 后续还会更新 )

用Python实现原生爬取某牙直播平台数据_第3张图片

你可能感兴趣的:(Python)