Python爬虫之爬取哔哩哔哩热门视频排行榜


Posted in Python onApril 28, 2021

一、bs4解析

import requests
from bs4 import BeautifulSoup
import datetime
if __name__=='__main__':
    url = 'https://www.bilibili.com/v/popular/rank/all'
    headers = {
       //设置自己浏览器的请求头
    }
    page_text=requests.get(url=url,headers=headers).text
    soup=BeautifulSoup(page_text,'lxml')
    li_list=soup.select('.rank-list > li')
    with open('bZhanRank_bs4.txt','w',encoding='utf-8') as fp:
        fp.write('当前爬取热榜的时间为:'+str(datetime.datetime.now())+'\n\n')
        for li in li_list:
            #解析视频排行
            li_rank=li.find('div',class_='num').string
            li_rank='视频排行为:'+li_rank+','
            #解析视频标题
            li_title=li.find('div',class_='info').a.string.strip()
            li_title='视频标题为:'+li_title+','
            #解析视频播放量
            li_viewCount=li.select('.detail>span')[0].text.strip()
            li_viewCount='视频播放量为:'+li_viewCount+', '
            #解析弹幕数量
            li_danmuCount = li.select('.detail>span')[1].text.strip()
            li_danmuCount='视频弹幕数量为:'+li_danmuCount+', '
            #解析视频作者
            li_upName=li.find('span',class_='data-box up-name').text.strip()
            li_upName='视频up主:'+li_upName+', '
            #解析综合评分
            li_zongheScore=li.find('div',class_='pts').div.string
            li_zongheScore='视频综合得分为:'+li_zongheScore
            fp.write(li_rank+li_title+li_viewCount+li_danmuCount+li_upName+li_zongheScore+'\n')

爬取结果如下:

Python爬虫之爬取哔哩哔哩热门视频排行榜

二、xpath解析

import requests
from lxml import etree
import datetime
if __name__ == "__main__":
    #设置请求头
    headers = {
       //设置自己浏览器的请求头
    }
    #设置url
    url = 'https://www.bilibili.com/v/popular/rank/all'
    #爬取主页面的源码文件
    page_text = requests.get(url=url,headers=headers).content.decode('utf-8')
    #使用etree对象进行实例化
    tree = etree.HTML(page_text)
    #爬取各视频的标签所在位置
    li_list = tree.xpath('//ul[@class="rank-list"]/li')
    #对爬取到的内容进行存储
    with open('./bZhanRank.txt', 'w', encoding='utf-8') as fp:
        #记录爬取数据的时间
        fp.write('时间:'+str(datetime.datetime.now())+'\n\n')
        # 使用循环结构,提取各标签中的所需信息
        for li in li_list:
            #读取视频排名
            li_rank=li.xpath('.//div[@class="num"]/text()')
            #[0]使用索引从列表中拿出字符串
            li_rank='视频排行:'+li_rank[0]+'\n'
            #读取视频标题
            li_title = li.xpath('.//a/text()')
            li_title='视频标题:'+li_title[0]+'\n'
            #读取视频播放量
            li_viewCount=li.xpath('.//div[@class="detail"]/span[1]/text()')
            #.strip()去掉字符串中多余的空格
            li_viewCount='视频播放量:'+li_viewCount[0].strip()+'\n'
            #读取视频弹幕数量
            li_barrageCount = li.xpath('.//div[@class="detail"]/span[2]/text()')
            li_barrageCount='视频弹幕数量:'+li_barrageCount[0].strip()+'\n'
            #读取视频up主昵称
            li_upName=li.xpath('.//span[@class="data-box up-name"]//text()')
            li_upName='视频up主:'+li_upName[0].strip()+'\n'
            #读取视频的综合评分
            li_score=li.xpath('.//div[@class="pts"]/div/text()')
            li_score='视频综合评分:'+li_score[0]+'\n\n'
            #存储文件
            fp.write(li_rank+li_title+li_viewCount+li_barrageCount+li_upName+li_score)
            print(li_rank+'爬取成功!!!!')

爬取结果如下:

Python爬虫之爬取哔哩哔哩热门视频排行榜

三、xpath解析(二值化处理后展示图片)

#----------第三方库导入----------
import requests#爬取网页源代码
from lxml import etree#使用xpath进行数据解析
import datetime#添加爬取数据的时刻
from PIL import Image#用于打开和重加载图片
from cv2 import cv2#对图片进行二值化处理
from io import BytesIO#对图片进行格式转换
import re#对源代码进行正则处理
#----------函数----------
def dJpg(url,title):
    """
    输入url 然后对b站webp格式的图片 进行格式转换为jpeg后 进行保存
    :param url:(url)
    :return:(null+保存图片文件)
    """
    headers = {
            //设置自己浏览器的请求头
        }
    resp = requests.get(url, headers=headers)
    byte_stream = BytesIO(resp.content)
    im = Image.open(byte_stream)
    if im.mode == "RGBA":
        im.load()
        background = Image.new("RGB", im.size, (255, 255, 255))
        background.paste(im, mask=im.split()[3])
    im.save(title+'.jpg', 'JPEG')
def handle_image(img_path):
    """
    对RGB三通道图片进行二值化处理
    :param img_path:(图片路径)
    :return:(返回处理后的图片)
    """
    # 读取图片
    img = cv2.imread(img_path)
    # 将图片转化成灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    # 将灰度图转化成二值图,像素值超过127的都会被重新赋值成255
    ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    return binary
 
#----------程序主入口----------
if __name__ == "__main__":
    #-----变量存放-----
    list_rank = []  # 存放视频标题的列表
    list_pic_url = []  # 存放图片网址的列表
 
    #-----数据解析(除图片外)-----
 
    #设置请求头
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.2261 SLBChan/10'
    }
    #设置url
    url = 'https://www.bilibili.com/v/popular/rank/all'
    #爬取主页面的源码文件
    page_text = requests.get(url=url,headers=headers).content.decode('utf-8')
    #使用etree对象进行实例化
    tree = etree.HTML(page_text)
    #爬取各视频的标签所在位置
    li_list = tree.xpath('//ul[@class="rank-list"]/li')
 
    #-----数据解析(图片)-----
 
    # 由于无法对图片的网址进行标签定位,现对源代码进行正则处理
    others_ex = r'"others".*?"tid"(.*?)]'
    list_others = re.findall(others_ex, page_text, re.S)
    # 使用循环替换掉源代码中others部分
    for l in list_others:
        page_text = page_text.replace(l, '')
    pic_ex = r'"copyright":.*?,"pic":"(.*?)","title":".*?"'
    list_pic = re.findall(pic_ex, page_text, re.S)
    # 获取图片url组成部分的索引
    index = list_pic[0].rfind('u002F')
    #对爬取到的url关键字进行拼接组成一个完整的url
    for i in list_pic:
        pic_url = 'http://i1.hdslb.com/bfs/archive/' + i[index + 5:] + '@228w_140h_1c.webp'
        list_pic_url.append(pic_url)
 
    #-----数据保存-----
    #对爬取到的内容进行存储
    with open('./bZhanRank2.txt', 'w', encoding='utf-8') as fp:
        #记录爬取数据的时间
        fp.write('b站视频排行榜,'+'时间:'+str(datetime.datetime.now())+'\n')
        fp.write('作者:MB\n')
        fp.write('*'*10+'以下为排行榜内容'+'*'*10+'\n\n')
 
        # 使用循环结构,提取各标签中的所需信息
        for i in range(len(li_list)):
            #读取视频排名
            li_rank=li_list[i].xpath('.//div[@class="num"]/text()')
            pic_title=li_rank#将不含中文的视频排行作为图片名称进行赋值
            #[0]使用索引从列表中拿出字符串
            li_rank='视频排行:'+li_rank[0]+'\n'
            #读取视频标题
            li_title =li_list[i].xpath('.//a/text()')
            li_title='视频标题:'+li_title[0]+'\n'
            #读取视频播放量
            li_viewCount=li_list[i].xpath('.//div[@class="detail"]/span[1]/text()')
            #.strip()去掉字符串中多余的空格
            li_viewCount='视频播放量:'+li_viewCount[0].strip()+'\n'
            #读取视频弹幕数量
            li_barrageCount = li_list[i].xpath('.//div[@class="detail"]/span[2]/text()')
            li_barrageCount='视频弹幕数量:'+li_barrageCount[0].strip()+'\n'
            #读取视频up主昵称
            li_upName=li_list[i].xpath('.//span[@class="data-box up-name"]//text()')
            li_upName='视频up主:'+li_upName[0].strip()+'\n'
            #读取视频的综合评分
            li_score=li_list[i].xpath('.//div[@class="pts"]/div/text()')
            li_score='视频综合评分:'+li_score[0]+'\n\n'
            # 存储视频信息(除图片外)
            fp.write(li_rank + li_title + li_viewCount + li_barrageCount + li_upName + li_score)
 
            #使用函数处理图片的url并且保存为jpeg格式
            dJpg(list_pic_url[i], str(pic_title))
            #使用函数对jpeg格式的饿图片进行二值化处理
            img = handle_image(str(pic_title) + '.jpg')
 
            # 强制设置图片大小(为防止记事本的行列大小溢出)
            img = cv2.resize(img, (120, 40))
            height, width = img.shape
            for row in range(0, height):
                for col in range(0, width):
                    # 像素值为0即黑色,那么将字符‘1'写入到txt文件
                    if img[row][col] == 0:
                        ch = '1'
                        fp.write(ch)
                    # 否则写入空格
                    else:
                        fp.write(' ')
                fp.write('*\n')
            fp.write('\n\n\n')
            print(li_rank + '爬取成功!!!!')

在记事本进行显示结果之前需要对记事本的格式进行下列更改以获得更好的视觉效果:

Python爬虫之爬取哔哩哔哩热门视频排行榜

爬取结果如下:(图片展示,是下载网页中的的封面图片(webp格式),首先对其进行格式转换为jpg格式,然后对其进行二值化处理(对于像素值大于127的像素点直接赋值为0,对于像素值大于127的像素点直接赋值为1)。然后遍历所有的像素点,对于像素值为0的像素点(即为黑色),写入“1”,对于像素值为1的像素点(即为白色),写入“空格”,实现简单的图片模拟显示。)

Python爬虫之爬取哔哩哔哩热门视频排行榜


水平线上和水平线下的图片并非一个时间点进行爬取。

Python爬虫之爬取哔哩哔哩热门视频排行榜

上述图片为了均衡文字显示与图像显示之间的关系,所以图片大小强制设定为较小的尺寸,图片显示并不清晰。要让图片显示清晰,可以不考虑文字显现效果,将图片的尺寸设置较大并且更改记事本中的字体大小(以防串行),可以进行图片较为清晰的展示,如下图所示。

Python爬虫之爬取哔哩哔哩热门视频排行榜

四、分析过程

(1)获取url——获取b站视频排行榜的网址

Python爬虫之爬取哔哩哔哩热门视频排行榜

(2)获取请求头——(右击—检查),打开开发者工具,点击Network,随便选择一个数据包,复制其中的请求头即可

Python爬虫之爬取哔哩哔哩热门视频排行榜

Python爬虫之爬取哔哩哔哩热门视频排行榜

(3)网页分析——点击开发者工具左上角的抓手工具,选中页面中视频,发现每个不同的视频都存放在不同的li标签中

Python爬虫之爬取哔哩哔哩热门视频排行榜

(4)网页分析——选中页面中视频的标题,发现标题内容存放在一个a标签的文本内容中,剩下的视频信息寻找方式同上述。

Python爬虫之爬取哔哩哔哩热门视频排行榜

(5)网页分析——在查看到视频播放量信息时,发现其存放在span标签下,含有空格,在编写代码时,使用strip()方法进行去除空格

Python爬虫之爬取哔哩哔哩热门视频排行榜

 (6)调试代码——调试代码时,爬取的图片url的列表为空

Python爬虫之爬取哔哩哔哩热门视频排行榜

(7)排错——检查图片url存放标签位置,发现位置正确

Python爬虫之爬取哔哩哔哩热门视频排行榜

(8)排错——爬取信息为空,可能网页为减轻加载负担,使用的是JavaScript异步加载,在开发者工具中,点击XHR,在数据包中寻找存放图片url的数据包,发现并不存在

Python爬虫之爬取哔哩哔哩热门视频排行榜

(9)排错——(右键—查看网页源代码),在源代码中搜索图片的url,发现所有图片的url全部存放在网页源代码的最后面,可以考虑使用正则表达式进行解析

Python爬虫之爬取哔哩哔哩热门视频排行榜

(10)排错——使用正则解析的过程中,返现others列表,此列表为部分视频下方的视频推荐,需进行删除,否则影响正则表达式进行解析

Python爬虫之爬取哔哩哔哩热门视频排行榜

Python爬虫之爬取哔哩哔哩热门视频排行榜

到此这篇关于Python爬虫之爬取哔哩哔哩热门视频排行榜的文章就介绍到这了,更多相关Python爬取B站排行榜内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python学习笔记之常用函数及说明
May 23 Python
python基于xml parse实现解析cdatasection数据
Sep 30 Python
浅谈插入排序算法在Python程序中的实现及简单改进
May 04 Python
Python爬虫框架scrapy实现的文件下载功能示例
Aug 04 Python
python单例模式获取IP代理的方法详解
Sep 13 Python
Django 静态文件配置过程详解
Jul 23 Python
Python绘制三角函数图(sin\cos\tan)并标注特定范围的例子
Dec 04 Python
Python彻底删除文件夹及其子文件方式
Dec 23 Python
Python3标准库glob文件名模式匹配的问题
Mar 13 Python
使用python+poco+夜神模拟器进行自动化测试实例
Apr 23 Python
Python格式化输出--%s,%d,%f的代码解析
Apr 29 Python
python如何从键盘获取输入实例
Jun 18 Python
k-means & DBSCAN 总结
秀!学妹看见都惊呆的Python小招数!【详细语言特性使用技巧】
Apr 27 #Python
Python代码,能玩30多款童年游戏!这些有几个是你玩过的
python实现腾讯滑块验证码识别
Apr 27 #Python
python实现调用摄像头并拍照发邮箱
Apr 27 #Python
django如何自定义manage.py管理命令
Apr 27 #Python
Python爬虫之爬取二手房信息
You might like
php通过sort()函数给数组排序的方法
2015/03/18 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
laravel 5.4中实现无限级分类的方法示例
2017/07/27 PHP
jquery中输入验证中一个不错的效果
2010/08/21 Javascript
Jquery跨域获得Json时invalid label错误的解决办法
2011/01/11 Javascript
js实现的map方法示例代码
2014/01/13 Javascript
JavaScript解八皇后问题的方法总结
2016/06/12 Javascript
一次$.getJSON不执行的简单记录
2016/07/19 Javascript
websocket+node.js实现实时聊天系统问题咨询
2017/05/17 Javascript
Ionic项目中Native Camera的使用方法
2017/06/07 Javascript
详解微信第三方小程序代开发
2017/06/23 Javascript
Angular.js前台传list数组由后台spring MVC接收数组示例代码
2017/07/31 Javascript
JS异步处理的进化史深入讲解
2019/08/25 Javascript
微信小程序 下拉刷新及上拉加载原理解析
2019/11/06 Javascript
精确查找PHP WEBSHELL木马的方法(1)
2011/04/12 Python
详解Python3.1版本带来的核心变化
2015/04/07 Python
Python中输出ASCII大文字、艺术字、字符字小技巧
2015/04/28 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
Django代码性能优化与Pycharm Profile使用详解
2018/08/26 Python
在Python中给Nan值更改为0的方法
2018/10/30 Python
浅谈python新式类和旧式类区别
2019/04/26 Python
pandas中DataFrame修改index、columns名的方法示例
2019/08/02 Python
pytorch实现MNIST手写体识别
2020/02/14 Python
Python读取表格类型文件代码实例
2020/02/17 Python
python异步Web框架sanic的实现
2020/04/27 Python
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
Gtech官方网站:地毯清洁器、吸尘器及园艺设备
2018/05/23 全球购物
英国办公家具网站:Furniture At Work
2019/10/07 全球购物
幼师专业求职推荐信
2013/11/08 职场文书
创业计划书如何吸引他人眼球
2014/01/10 职场文书
物业管理委托协议(2篇)
2014/09/23 职场文书
办护照工作证明
2014/10/01 职场文书
网上祭英烈活动总结
2015/02/04 职场文书
休假证明书
2015/06/24 职场文书
Redis持久化与主从复制的实践
2021/04/27 Redis
python Django框架快速入门教程(后台管理)
2021/07/21 Python