基于python的网络爬虫设计.doc
摘要哔哩哔哩视频弹幕网,从一开始的无名小站发展到现在月活跃用户超一亿的巨大规模,不仅引起了行业浪潮,也吸引越来越多人选择成为UP主(Uploader)即视频上传者。Bilibili网为UP主提供了平台和各种功能支持,但还是无法面面俱到。本软件设计旨在提供便捷的刚需功能,为新兴UP主提供功能支持。本毕业设计采用标准的软件开发流程,包含了需求分析、整体设计、模块实现、编码、测试、打包软件等等步骤。该软件算法和轮廓基于python设计,调用了包含requests、random、pickle等等成熟的集成库环境。软件主要针对用户需求颇多的两个主要分支:评论和抽奖进行设计实现。评论区功能包括爬取完整的表单数据,解决复数层评论的获取和存储,实现快速浏览、存储和多种查找功能;抽奖区功能包括实现爬取多种抽奖材料,根据需求分析样本并最终使用随机算法进行随机数获取,实现抽奖功能。关键词:爬虫 bilibili 用户 pythonAbstractBilibili has started as an unfamous acg web at the beginning and now have a huge scale of over 100 million active users each mouth, which is causing a wave and attracted more and more people to choose to become a UPloader.Bilibili provides Uploaders sport and various functions for the users, but it still cannot cover everything. This software is designed to provide convenient and needed functions to users. This graduation design uses a standard software development process, including requirements analysis, overall design, module implementation, coding, testing, packaging and other steps. The software algorithm and outline are designed based on python, and call the mature integrated library environment including requests, random, pickle and so on. The software is mainly designed and implemented to slove two main functions with many user needs: reviews and lotteries.The review function incuding crawling complete form datas, solving the acquisition and storage of multiple layers of reviews, realizing quick browsing, storage and multiple search functions and so on. The lottery function contains crawling multiple datas to analysis and finally finish the random choise.Key words:Web Crawler Bilibili User Python目 录1 绪论11.1 项目背景与意义11.2 国内外研究情况11.3 文献综述12 网络爬虫介绍32.1 网络爬虫原理32.2 网络爬虫框架32.3 网络爬虫工作流程32.3.1 向服务器发起请求32.3.2 获取响应内容42.3.3 解析内容42.3.4 储存分析43 软件整体设计53.1 程序需求分析53.2 系统框架构造54 爬虫程序具体设计流程124.1 环境搭载124.2 模块功能实现154.2.1 实现评论获取与查找154.2.2 实现bv号获取及视频信息总览214.2.3 抽奖实现与粉丝流动部分224.2.4 mid的获取和ab互转功能实现254.2.5 程序框架实现274.2.6 逻辑改善及bug处理294.2.7 编写完成打包程序325 软件演示与测试345.1 测试环境345.2 步骤演示与测试结果346 总结426.1 项目开发总结426.2 不足与展望42参考文献43致谢44广东东软学院本科毕业设计(论文)451 绪论1.1 项目背景与意义近年来随着网络的飞速发展和建设,人们获取信息的途径也从主流的报纸电视,过渡到手机电脑等网络平台。各类别的文化借此逐渐渗透到人们周围的生活中。作为国内起步最早的一批二次元视频网站之一,哔哩哔哩以其独有的弹幕文化逐步发展成现在国内流量第一的视频弹幕网站。哔哩哔哩视频内容的高跨度、高质量、高时效力也为其吸引了巨大的现有用户和潜在用户,2019年5月起月活跃用户数突破1亿,并且还在呈现增长趋势。作为一个互联网公司,哔哩哔哩是成功的。但其拥有的庞大用户数量,注定决定了哔哩哔哩无法做到面面俱到,满足所有用户的需求。哔哩哔哩主要的运作方式为网页,依赖数据的建设和支持为用户提供了很棒的功能。 本课题的主要目的是设计面向用户的网络爬虫程序,提供用户一些官方并未提供的功能,比如类别抽奖和数据获取。1.2 国内外研究情况近年来,国内外程序研究人员提出了许多种类的网络爬虫结构与算法,亦应用在不同的行业与领域,大大提高信息利用率和工作效率。许多大型软件公司也积极地根据自身行业特点与需求,开发出许多类别的网络爬虫系统,比如google,微软的bingbot和yahoo的slirp等等。本课题研究的方向是提供特定网站哔哩哔哩的额外功能实现,在经过网络查询后发现,国内目前并未有人系统地开发过相应软件,可以说是较为新颖的研究课题。并且考虑到哔哩哔哩用户基数大,前景可期,用户需求只会越来越多,本课题的研究实现也具有了现实意义。具备研究价值。在实现预期目标的同时,将一同研究作为功能性的爬虫程序,在面对复杂、多样性的环境下可能出现的问题,合理借鉴前人研究经验,解决和优化。1.3 文献综述对于网络爬虫的研究从上世纪九十年代就已经开始,目前爬虫技术已经趋见成熟,功能描述向高概括性高度模块化靠拢。网络爬虫是搜索引擎的重要组成部分。网络上比较著名的开源爬虫有Nutch,Larbin,Heritrix等等。网络爬虫最重要的是网页搜索策略(广度优先和最佳度优先)和网页分析策略(基于网络拓扑的分析算法和基于网页内容的网页分析算法)。国内外流行的爬虫技术相当多,各个编程语言都有涉及。基于Python、C+、C、java等等。就原理而言,爬虫组件都是差不多的。而无头浏览器是最能够说明爬虫特性的部分,无需提供多余的身份信息即可向服务器请求数据,以适用于自动化测试等领域。此外主流的浏览器如Chrome、Firefox、Safari等都提供了相应的抓取支持,selenium作为一个集成工具,包含了上述的所有组件,以WebDriver的形式,直接在浏览器进行测试,适配各种爬虫组件,方便使用者进行操作。2 网络爬虫介绍2.1 网络爬虫原理网络爬虫行为上就是模拟真人进行流程操作,获取网页返回的数据进行储存分析,等同于浏览器对网页的访问。因这种技术实现很像蜘蛛在蛛网上的往返爬行,也被生动地取名为爬虫。其实质就是一个请求网站并储存数据的自动化程序。2.2 网络爬虫框架下图为一个通用的网络爬虫框架。通过调用URL在队列中进行管理,实现数据获取和保存。已下载网页库种子URL待抓取URL已抓取URL读取解析下载放进队列图2.1网络爬虫框架图2.3 网络爬虫工作流程2.3.1 向服务器发起请求爬虫程序通过request向目标网站的服务器发起请求,服务器会根据request内包含的请求作出处理,返回浏览器结果,这个过程即为response。而Request包含:1、请求方式常用的有GET和POST两种请求类型,另外还有HEAD、PUT、OPTIONS等。2、请求URLURL即(Uniform Resource Locator)统一资源定位符,网页、歌曲、视频、图片都可以用一个唯一URL确定定位。3、请求头发送请求时可选的头部信息,取决于网页的请求要求,常见有Cookies、Host等。4、请求体发送请求时可选的额外数据,比如提交的表单、文本数据。2.3.2 获取响应内容服务器返回的response包含:1、响应状态即状态码,比如200为处理成功,404为未找到请求页面。2、响应头包含返回的内容格式、长度、类型等自然信息,以及服务器信息等。3、响应体即请求的资源内容,爬虫获取最主要的部分。2.3.3 解析内容根据获取的数据类型,比如HTML文档,JSON格式文本,图片,歌曲视频等等,作出相应处理。处理方式有直接处理,正则表达式,json解析,beautifulsoUP等等。2.3.4 储存分析以不同的格式:文本、json、jpg、mp3等等储存数据,作进一步处理分析。广东东软学院本科毕业设计(论文)3 软件整体设计3.1 程序需求分析哔哩哔哩网站作为新类别媒体平台的代表,在近几年以其内容的高跨度、高质量、高影响力吸引了巨大的现有用户和潜在用户,2019年5月起月活跃用户数突破1亿,并且还在呈现增长趋势。UP主,一个哔哩哔哩网站视频创作者的别称,为哔哩哔哩海量视频的产出增添了浓墨重彩的一笔。从起初的小受众网站一步步走向了多元化的媒体平台,这也吸引了越来越多的人成为UP主,加入到创作的浪潮中。本软件面向的对象,就是数量众多的中小规模的新UP主。许多UP主在不断产出高质量视频后,也未必能成为粉丝过万、十万、百万的大UP主。抛去主观因素,通过网上调查等方式,我总结出了他们需要的一些非官方提供功能。一个全面的视频信息汇总功能,让用户看到全部视频的具体数据。一个高效的评论浏览功能,可以使他们了解观众的想法和建议,为新的内容创作蓄力。一个多样化的评论查找功能,有时需要找到特定信息,比如歌名,网站等等,或者查看长度较长的评论,查找功能就能很好地解决问题。这个功能也不局限于UP主,是所有用户都能使用的功能。一个完善的抽奖功能。哔哩哔哩为UP主提供了许多方便的功能,抽奖就是其中之一。但为了防止滥用引发的一系列问题,该功能只提供给粉丝过万或者有一定优质动态、投稿积累的UP主,新人UP主要想在前期积累人气,抽奖功能是必不可少的。一个粉丝流动监视功能。新人UP主最关注的应该就是粉丝增长趋势了。这个功能无疑十分便捷,可以让他们看到一步步的积累。3.2 系统框架构造有了需求后,就可以着手设计软件,即面向对象编程。先根据用户需求,总结出需求框架,方便后续工作流程。下图为具体框架:图3.1需求总结图由需求可对程序进行初步构造,设计成由一个初始界面框内嵌一个多层循环且可随时打破的菜单函数构成的程序。设计目的是高效输出,简便操作,让任何人都可以轻易上手。大致逻辑确定后,开始设计系统主逻辑。下图为构造完毕的主体与子功能循环图: 图3.2主体与子功能循环图如图示,即菜单程序里的功能模块在循环条件成立时不断循环,功能模块也随需求进入循环或者打破,并在用户给出打破条件后返回主体,参与主程序循环。接下来开始设计主菜单的逻辑流程。如下图:初始界面开始选择执行输出结果菜单返回功能列表退出程序是否是否图3.3主菜单的逻辑流程图图示阐述了系统的实现方法,即用户启动程序,选择进入主菜单,依实际需求选择相应功能,执行完毕后,可选择继续操作或者返回主界面,亦或是退出程序。到这里,系统实现的大致方向已经确定,下面开始设计各部分功能的逻辑流程。下图为绘制好的番号互转和评论功能实现逻辑:ab互转a2b获取b2a返回菜单退出查看评论用户+评论评论输入bv查看转换结果是是是否否否图3.4番号互转和评论功能实现逻辑图如图中描绘,获取评论的操作逻辑为输入bv号,程序爬取后输出给用户查看,可继续循环查询功能或者返回主界面。而左半部分的av号与bv号互相转换流程,在后续软件实现会作进一步的补充说明。其逻辑和前部分类似,通过获取用户输入的视频编号(av/bv号)进行转换,输出结果。下图为评论查找的逻辑设计:评论查找关键词查找去重查找长评查找输入关键词结果查询返回菜单V码获取查询结果否否是是图3.5评论查找的逻辑设计图如图中的设计,在获取视频标识符后,对用户的要求分别实现,比如查询功能接收关键词字符,在比对库后输出结果,无论成功与否都可以重复操作或者跳出循环返回菜单。下图为抽奖功能和粉丝流动功能的逻辑实现:抽奖 粉丝流动V码获取mid获取调用多日数据评论抽奖粉丝抽奖粉丝流动新粉抽奖旧粉抽奖结果新增变动取关变动数据储存返回菜单图3.6抽奖功能和粉丝流动功能逻辑图不同于前几个功能的相对独立,抽奖和粉丝流动这两个功能的分支会有共同的数据需求,在设计程序逻辑的时候应该注意,合理利用资源,实现一对多的函数调用,节省代码量,提高效率。即粉丝抽奖和粉丝流动部分是需要用户提供mid而不是bv号,但整体逻辑依旧和前部分的功能模块类似。下图为用户视频信息查询:获取mid用户视频信息浏览合法返回菜单排版打印各评论数视频总量各bv号各标题各播放量获取数据是否图3.7用户视频信息查询该功能提供用户查看所有的视频相关信息,逻辑设计为较精简的交互模式,获取请求后输入mid,程序判断数据合法性后,将内容排版打印输出,相对于前几个功能的多分支,本功能逻辑简单易懂。绘制完成主程序和功能模块的逻辑设计后,可以开始进行爬虫程序设计。4 爬虫程序具体设计流程4.1 环境搭载在有了需求和逻辑框架后,开始进入软件设计环节。首先是环境的搭载。本软件是基于python开发的爬虫程序,自然少不了python的安装和环境构建。第一步是安装python。进入官网下载地址www.python.org/downloads/windows,选择对应的32位或64位安装包进行下载,然后根据提示进行安装,需要注意安装路径的选择和应该勾选将python添加到PATH环境变量。安装完后打开命令提示符CMD输入python -V,若返回具体版本则为安装成功。如下图示:图4.1安装结果安装完python,可以选择直接开始代码编写,原生的python组件虽然好用,但有些简洁,缺少了诸多丰富的功能和调试交互。Python也有许多IDE可供选择,这里选择pycharm作为集成开发环境进行代码编写。PyCharm作为知名度和用户量都很高的python编译器,在界面、交互、调试、管理等都比原生要更精致和易用。进入官网打开pycharm新建project,进入project界面点击file-new-pythonfile创建新的python文件。并手动添加解释器。点击右上角file-settings进入设置如图示:图4.2进入设置在project:项目名称栏目下点击project interpreter,可在右上方添加默认解释器或新建解释器。如图示:图4.3添加解释器至此,基础的环境搭载完成。测试是否成功,输入print('hello world!'),点击run按钮运行,成功打印字符,如图示:图4.4测试pycharm在软件编写时经常会对多行代码进行运行测试,每次都使用run运行的话会比较麻烦,因为之前写好的代码也会跟着运行,若每次都注释掉效率也有所降低。我们可以使用ipython解决这一问题。Ipython是python的一个交互式shell,相比默认的shell功能更强大,也能很好地兼容pycharm,其特有的in-out模式可以支持指定代码行的运行,对功能调试十分有益。安装十分简单,打开cmd输入pip install ipython等待安装完成即可。若报错失败可检查是不是pip工具没有升级到最新版本。使用pip show pip可以查看当前pip的版本信息,若提示You should consider UPgrading via the 'python -m pip install -UPgrade pip' comm,直接复制引号内容输入更新即可。安装成功后打开cmd输入ipython,出现下图In1即为成功。图4.5测试ipython打开pycharm选中任意一行代码,右键选择execute selection in console,下方即会打开shell界面。图4.6在pycharm中启用ipython图4.7启用成功如图,可在shell界面进行代码编写测试。4.2 模块功能实现4.2.1 实现评论获取与查找软件环境搭载好后,开始进行代码编写。首先把目标确定在如何获取评论。使用Chrome浏览器打开哔哩哔哩,随意点开一个视频,这里应该选择评论较少的,因为首要目的是实现获取,之后再解决抓取量的问题。若选择大量评论的视频进行测试很可能被哔哩哔哩网站监测到,这对于爬虫的开展无疑是无益的。点开视频后按F12打开开发者工具调试界面,点击network,按下Ctrl+R刷新网页。可以看到网页的所有网络请求。如图示:图4.8找到请求图中可以看出,请求有很多个,一个个查找肯定可以找到评论相关的数据包,我们也可以使用左方的搜索功能,随意复制一条评论进行搜索,结果如图:图4.9查看请求包可以看到查询到3条请求结果,进一步查看后发现第一条的reply就是我们想要的数据。点击preview查看网页返回的json包数据,结果如图:图4.10返回包数据1图4.11返回包数据2可以看到,data-replies-0下的content即为我们需要的评论数据,此外member里有mid和用户id,后续也会用到。mid为哔哩哔哩为每一位用户编排的身份标识,具有唯一性,后续进行数据处理可以以mid作为标识符,也考虑到用户的id可能会更改,以id为判别标识不够严谨。知道评论的请求名后,右键复制地址,开始找请求的api地址。如图示:图4.12复制链接地址复制后打开网址,提示页面未找到。如图示:图4.13访问失败可以理解成api地址被加工了。没有关系,我们分析一下地址构成。可以发现reply?后皆为“变量名-值”这一格式。一个个删掉使用排除法可以找到正确的组合,但熟悉网页爬虫的可以知道,callback其实为回调函数。当网页运行时,一般经过API调用库里预备好的函数。但有些库函数会请求网页先传回一个函数,以便在合适的时候调用,完成对应指示。这个被传入后又被调用的函数就称为回调函数(callback function)。一般删除就能获得真实api地址,我们把它删掉试试。得到如下结果:图4.14找到正确api地址没错,这就是正确的aip地址,接下来开始分析变量。Api地址后的”&pn=1&type=1&oid=48979270&sort=2&_=1586439751697”,pn可以猜到为页数,后续也证明了准确性。type、sort为状态,这个默认配置即可,最后剩下的“oid”和“_”应为各视频的唯一变量。打开多个视频进行比对后可验证。那“oid”和“_”该如何获取呢?在网上查询哔哩哔哩的开放api接口后,得知“_”可以用“nohot=1”代替,效果是一样的。而oid先不着急,以该视频为例,oid是已知的。先继续实现评论爬取。以api地址请求数据,可以调用requests库,用get函数获取数据包,再调用json库的loads函数把网页返回的已编码的json字符串解码成python对象。如图示:图4.15请求成功Response 200说明成功处理了请求。打印输出的字符串也说明成功获取到数据包。开始获取评论数据。首先评论有多页,应该先写一个遍历来实现循环爬取。如何知道某个视频的评论页数呢?我们回到开发者调试窗口,可以找到page里的count即为主楼评论的数量,哔哩哔哩评论默认显示20条一页,那么总页数即为(count-1)/20+1,取整处理。接着应该注意评论不仅有主楼,还有跟楼回复,副楼时有时无,层数也不固定。副楼的数据是在主楼的replies下面的。可以用if语句判断,存在副楼时遍历,以此下推。存储数据时将用户名和评论分别存放在列表中,方便后续调用查找。为什么不选择字典呢?因为用户名可能会重复,字典在存储重复用户名的评论时新评论会顶掉旧的,最终只保留一个。这也是字典的特性,键值对应,键唯一。起初我是用字典存储的,发现怎么都抓不完整,才恍然大悟,改用列表。部分实现代码如下:total_pages = (data'data''page''count' -1)/ 20 + 1 lou = louid = for page in range(1, total_pages + 1):r = requests.get(url)data = json.loads(r.text)for i in data'data''replies':lou.append(i'content''message')louid.append(i'member''uname')if i'replies' != None:for j in i'replies':lou.append(j'content''message')louid.append(j'member''uname')for x, y in zip(louid, lou):print(x, ":", y)试运行并交叉打印两个列表,返回结果如图:图4.16爬取评论成功获取评论成功,可以看到主楼副楼都可以显示出来,并且相同用户的评论也都在纪录。接下来实现查找部分。排序功能对于大量评论数据的查看有着重要作用,我们使用python内置的sorted函数来实现。需要注意sort的应用对象为list,sorted可对所有可迭代的对象进行排序操作。为了全面我们还是使用sorted。changping = sorted(lou, key=lambda i: len(i), reverse=True)如上一行即可实现正序排列存储到listchangping中。接着是去重操作,评论里不乏有重复的颜文字,顶帖等等相同的回复,我们可以利用for循环将评论列表与空list对比,若空list中没有即加入list中,以此筛选掉重复的评论,代码如下:for i in lou:if i not in quchong:quchong.append(i)实现关键词查找的方法也与其类似,在评论列表中用for循环遍历关键词,存在即存入新list中,代码如下:f = f for f in lou if guanci in f至此获取评论与查询部分编写完成。4.2.2 实现bv号获取及视频信息总览考虑到有的UP主发布视频比较多,有时一个个翻bv号会很麻烦,因此新增一个功能,只需输入mid即可自动获取该UP主所有视频的基本信息,包括bv号、名称、播放量、评论数。在不改变原有程序逻辑的情况下,减少用户操作步骤。首先打开某个用户的视频页面,使用前面获取api的方法,查找到正确的返回数据包,如图:图4.17获取返回包"对地址进行分析可得,ps为pagesize,指一页的容量为30,pn为pagenumber,指页数,我们只需请求ps=30,pn=1和mid即可正确抓到第一页的数据,又因返回包中page-count里有视频总量,如图示:图4.18找到视频量信息即可利用count/ps+1来遍历爬取到全部页数的数据。代码编写和获取评论的思路类似,如下为部分代码:r = requests.get(url)data = json.loads(r.text)total_pages=(data'data''page''count'-1)/30+1for page in range(1,total_pages+1): r = requests.get(url) data = json.loads(r.text) for i in data'data''list''vlist': bid_list.append(i'bvid') title_list.append(i'title') play_list.append(i'play') comment_list.append(i'comment')for w,x,y,z in zip(bid_list, title_list,play_list,comment_list):print(w,":", x, "/播放量:", y,"/评论数:",z)运行测试,成功打印到所有数据,如图:图4.19爬取结果到这里获取bv号及视频信息总览功能编写完成。4.2.3 抽奖实现与粉丝流动部分抽奖功能分为按评论区回复抽奖、按新增关注者抽奖和按原关注者抽奖。按评论区抽奖我们可以继续使用评论部分的api,请求到用户mid和昵称,存入一个字典dict中。需要注意,这里不同于评论获取采用list存储,在同一用户有多次回复时,采用字典存储可以保证其唯一性,不会多次录入。键选择为不变的mid,值则为可能改变的昵称。yonghui'member''mid' = i'member''uname'字典的写入语法如上,其余部分与评论存储相似,不过多说明。按新增关注者抽奖或原关注者抽奖则需要进入用户关注界面,用同样的方法在调试窗口找到api地址:同样的,在发送正确的请求后,我们得到数据包,将data-list里的关注者mid和昵称存入字典中,测试结果如下:图4.20用户信息获取成功这样我们就得到了当日的粉丝数据。但仍需在粉丝变动之后再获取一遍或多遍,来对比筛选出新增的粉丝和一直存在的旧粉丝。使用pychon的file文件功能,open语法可以打开一个文件,调用pickle库函数序列化字典,dump为写入,load为读取。方便以便下次调用。用法如下:file_name = 'day1.data'with open(file_name, 'wb') as f:pickle.dump(follow_dict, f)dict1 = pickle.load(f)实现方法即为将操作分为两个按钮,第一次运行和第n次运行,分别存入day1和day2文件中,day1只写入一次,day2不断覆盖。在有了多日数据后,我们可以定义一个比较函数,使用for循环在day1里面遍历day2的元素,若存在就跳过,不存在的将该元素写入新list中。这个操作是可累计的的,新list(新增list、取关list、旧关list)会根据日数的累计而不断刷新增加。遍历逻辑为:day2存在而day1没有的用户即为新增粉丝;day1存在而day2没有的用户即为取关粉丝;day1排除掉取关粉丝后的用户即为一直存在的旧粉丝。for i in dict1.keys():try:follow_dictiexcept:bijiao1i = dict1i。如上为实现方法,利用try进行元素对比,跳过后在except下将数据存入新list中。3种list都是用同样的框架获取写入的。在多次运行后,新增粉丝列表、取关列表、旧关注列表均获取完毕,可以输出结果给用户查看,即实现了粉丝流动查询。下面为运行结果,打印出新关注列表和取关列表:图4.21打印新增和取关列表得知正确获得后,进行最后的抽奖功能编写。我们可以调用random库,使用其choice函数对3种list列表进行随机数获取,在不同的需求下对相应list进行操作,语法例子如下:xingyun = random.choice(list(yonghu)下面为其中一种抽奖的运行结果:图4.22抽奖功能实现抽奖功能成功实现,至此,多种方式的抽奖功能和粉丝流动查询功能实现完毕。4.2.4 mid的获取和ab互转功能实现完成前面的功能函数后,我们还有oid没有解决。程序的理想操作是用户选择所需功能后,只需键入相关视频bv号即可完成功能。但bv号与oid没有关联,如何通过 bv号获得mid呢?其实结论就是oid即av号。这也是我之前编写代码时发现的。本程序是在3月23日之前就编写完成的,当时的实现方法就是用户输入av号,因av号即mid,替换后即可实现各种功能。av号为哔哩哔哩网站之前为视频编排的编号,用于唯一定位该视频,即身份编号。但从2020年3月23日开始,哔哩哔哩正式启用bv号取代av号,意在维护UP主的隐私等,提高安全性。但原有的av号功能依旧可用,因此本程序不仅要考虑旧视频的适用,也要考虑3月23日后发布的视频也能定位到。现在视频的网页地址里参数已经改成bv号,我们该怎么获取到oid呢?先打开一个3月23日前发布的视频,打开调试窗口:图4.23请求头的oid可以看到header请求头里的类型有个oid,再查看reply里的数据,也有一个oid:图4.24返回表单的oid因为视频是以前发布的,我们知道其av号为av48979270。得出oid即av号。那么新发布的视频是否也适用这一规则呢?打开一个3月23日后发布的视频,查看发现其请求变量依然是oid。图4.25 新发布视频的请求类型可以作出猜测,oid是哔哩哔哩标识视频的真正编号,之前也作为av号提供给用户作为搜索字符,并且在bv号更新后,依旧适用,只是av号不再显示了。开始验证,打开调试窗口,Ctrl+R,不滚动鼠标搜索视频标题,(请求静态页面的数据包),查看结果如下:图4.26新发布视频的请求类型可以看到返回表单里aid与上方的oid相同。也证明了哔哩哔哩在更改bv号后依旧是使用oid进行视频管理的。接下来就简单了,拿到api地址,通过输入bv号请求该返回包下的aid,即可获得mid,实现前面的功能模块。代码如下:bvid = input()r = requests.get(" + bvid)data = json.loads(r.text)aid = data'data''aid'oid = aid由此我们解决了oid的获取问题。在此应当多编写一个av号与bv号互相转换的功能,方便需要的用户。如上我们已经实现bv号转为av号的功能,反过来也一样。在api地址上将bvid改为aid,在用户输入av号后请求该地址拿到data里的bvid,即为bv号。测试结果如下:图4.27实现转换功能成功实现转换功能,功能模块基本完成,开始编写程序框架。4.2.5 程序框架实现依据前面绘制的程序逻辑流程图,程序将被设计成运行-进入初始界面-进入菜单-实现功能-返回菜单-继续执行或者退出。每一步操作中途都可退出返回菜单页或者直接退出程序。初始界面主要由print函数构成,内容包含软件标题,用途,制作者信息,操作须知等等文本提示信息。待用户确认完成后,输入指令进入功能菜单。因功能菜单分支较多,要梳理好各分支的逻辑走向,我决定用while函数来构造菜单,实现多分支的循环和打破。具体框架如下示例程序:while a:do sthif b = 1:do sth if c = 1: while d: do sth if e = 1: continue if e != 0: breakbreakelse:if b != 1break最外层的while充当菜单,第一层if判断语句实现一级菜单,第二层if判断语句实现二级菜单以此类推以实现多级菜单。合理套用continue和break即可实现简单的多级菜单。而有一些分支需要在不跳出当前层级菜单的情况下实现重复循环,比如对评论的关键词查找,用户通常会进行多次查询,我们应当提供合适的逻辑构架,以实现对象需求。可以在次级if判断下嵌套多个while,比