目录

前言

需求

方案分析

方案一

方案二

接口分析

请求流程

抓包演示

请求接口

接口说明

接口测试

代码


前言

想看接口分析和代码的,可跳过前言。

更新,最核心的代码已删除,思路和其他代码保留。

需求

我参加了一些up主的动态抽奖,转赞评那种的,如图1。

图1 - 动态抽奖

开奖周期一般在两周到四周,如果粉丝数多的话,会被大量评论,而且他就没及时开过奖(指说几号开奖就几号开奖),实际都是比说的日期再晚几天才开奖。

开奖后我想删除我的转赞评。转发在自己动态里就能删,点赞只要在up主原动态再点一下点赞按钮就能取消,评论却只能翻到自己的那条评论,才能删除。

问了B站客服,他说只有以下方法能删除自己的评论:

  1. 手动翻到自己的那条评论
  2. 别人回复你的评论,你收到提醒,在提醒里点击对方回复的内容,可跳转到你的评论

方案分析

按热度排序,我不确定我到底在哪,反正不在靠前的位置,应该是中间或后面。

按时间排序,B站是把距离当前时间最近的评论,放在第一个(置顶除外),把从时间上真正第一个发的评论,放在最后一个。我认为这是降序,可我参加时一般都是up主发动态的当天,降序的话几乎得翻完全部评论才能找到我的评论,也就是说升序可以很快地找到我的评论,但B站不支持,我反馈了,客服说会给研发提。

由于参与评论的人太多,手动翻是翻不到的;可是也没人回复我的评论,那怎么办?

方案一

首先我想到让程序自动翻页,我知道的有两类:

  • 按键精灵之类的软件,录制好键鼠动作,然后自动执行动作
  • 用代码操作浏览器,实现自动翻页

第一类

我用的不是按键精灵,是别人自己写的软件,功能类似。一开始翻页时,新数据加载得挺快;随着时间的推移,新数据加载得越来越慢。例如最开始时,只要页面滚动的位置到了,下一页的数据马上就能加载出来;一段时间后,虽然页面滚动的位置到了,也出现了正在加载的提示,但需要几秒甚至十几秒甚至几分钟才能显示出下一页的数据,这个加载时间越来越长。

时间长点没事,只要能加载出来,我就能点删除。按热度排序的话,我得隔一会儿就搜下有没有加载出我的评论,且翻页次数非常非常多后,页面搜索很慢(我试了),也没搜到我。所以后来我又选了按时间排序,花了好几个小时,当加载到我发评论的前一天时,页面崩溃了,只能刷新,刷新后之前已加载的那么多评论全没了,又试了次依然这样。

针对以上加载速度慢、页面崩溃,我能想到的原因有:

  • B站限制了数据返回的速率或频率
  • 我的网络原因(这个可能性最低)
  • 浏览器性能不够,我用的Edge
  • 电脑硬件性能瓶颈,如CPU和内存,我是I7-6700HQ,12G内存,三星860EVO

实际是什么原因就不知道了,总之这个方法不行。

第二类

一开始,我用selenium打开那条动态,让selenium执行js代码,使页面滚动,但实际滚动的效果和手动用鼠标滚动不一样,好像是滚动几次就不行了,就加载不出新数据了,我忘了,总之这个方法不行。

后来,我在浏览器Console里手动执行同样的js代码,效果和selenium一样,可能是代码原因,有知道的可以告诉我,或者其他写法也行。我试了以下几种,当然不是一起运行,一次运行一种:

//第一种
document.body.scrollTop=10000 // PhantomJS使用,headless不支持//第二种
document.documentElement.scrollTop=10000 // 页面向下滚动指定的像素,数值很大时肯定能滚动到底部。这是页面滚动,不是模拟鼠标滚轮滚动//第三种
var q=document.documentElement.scrollTop=10000 // 或这种写法 from https://www.cnblogs.com/landhu/p/5761794.html//第四种
window.scrollTo(0,document.body.scrollHeight) // 滚动条回到底部。连续滚动时,有时上面两种js代码滚动一会儿就失效了,可以用这种 from https://www.cnblogs.com/xyztank/articles/14259330.html
// window.scrollTo(0,0) // 滚动条回到顶部

方案二

方案一中的方法都不行,我不准备删了,突然有人回复我在某视频下的评论,如图2。

图2 - 别人回复我的评论

以往回复我的内容,字数很少,直接在图2中的界面就能看完,我就没点过。直到这次的太长了显示不完,我就点击了他回复的内容,然后竟然直接跳转到我的评论了,如图3。

图3 - 点击图2后跳转到我的评论

这正好符合客服说的第二种,并且向下翻,还看到了页码,如图4,不过这张图是后来测试时在某个动态的截图(因为我要删对动态的评论),但页码、跳转到指定页等内容都和当时视频那里一样,注意页面滚动条位于底部,平时B站无论动态还是视频,评论都是动态加载的,滚动条不会一直在底部,会触发加载下一页,除非所有评论真的记载完了,那样页面底部也有提示到底了。

图4 - 图3页面的底部出现页码

既然有页码了,那不是可以直接跳转到靠后的页面(按时间排序,我评论得早,一般都是up主发动态的当天),然后快速找到我的评论?最多就是多翻几页。可我点击页码后,页面内容还是当前页的内容,不能通过点击页码跳转页面,后面那个跳转到指定页也不管用。

然后我看了当前URL,reply后应该是当前评论的ID,即我的评论的ID。

https://www.bilibili.com/video/BV1aQ4xxxxxx#reply5816xxxxxx

于是有了新思路,找到所有我参加过评论的动态,用爬虫爬取它们的所有评论数据,里面就有我的评论的ID,然后将ID拼接到动态的URL的末尾,访问就能跳转到我的评论,然后就能删除。如图5,当然那条不是我发的,我为了验证这个思路随意找了一条测试的。

图5 - 访问构造的URL跳转到我的评论

另外,因为是转赞评,有些抽奖动态我以前直接在我的动态里删除了转发 ,现在怎么找到它们从而删除评论?在up主的动态列表里,只要点赞按钮是蓝色,说明自己已点赞,已参加转赞评,如图6。但是转发和评论不会变蓝,无论自己有没有真的转发和评论。

图6 - 点赞变蓝是已点赞,说明已参加转赞评

点开这条动态,也能看到,如图7。

图7 - 点开图6的动态

接口分析

请求流程

  1. 打开一条动态,如https://t.bilibili.com/56764707xxxxxxxxxx,注意已手动去除末尾的?tab=2
  2. 获取动态本身的信息,如类型、oid等
  3. 根据动态的类型、oid获取评论数据,当然必需的参数还有页码、排序方式

抓包演示

图8 - 步骤2的请求的参数

图9 - 步骤2的请求返回的json数据,得到type

图10 - 步骤3的请求返回的json数据,包含评论

请求接口

接口说明

接口1,步骤2请求的接口

https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=

参数dynamic_id就是步骤1的URL末尾的一长串字符,我称为动态ID。

返回的json数据中有一个键是type,如图9,表示动态类型,它的值有以下几种可能:

  • 1:有转发内容
  • 2:动态有图片
  • 4:纯文字
  • 2048:可能是内容有站内分享(比如装扮推荐)
  • 其他情况有知道的可以补充

接口2,步骤3请求的接口

图10中携带了很多参数,但callback和plat和_都不是必需的,带上了反而可能出错(接口测试部分第三步会说),有人说callback和_是根据某种规则生成的,用于跟踪用户,后来我发现_的值很像当前时间的时间戳,callback的值的后半部分也很像当前时间的时间戳,且比_的值稍微小一点点。

https://api.bilibili.com/x/v2/reply/main?jsonp=jsonp&next=&type=&oid=&mode=
接口2的请求参数的说明
参数名 参数类型 含义
next 字符串 0和1都表示第一页,2表示第二页,3表示第三页...
type 字符串

若接口1返回的type为2,则接口2的参数type的值为11

若接口1返回的type为1、4、2048,则接口2的参数type的值为17
oid 字符串

若接口1返回的type为2,则oid为图9或图12中返回值中的rid的值

若接口1返回的type为1、4、2048,则oid的值和动态ID一样,即dynamic_id
其他情况有知道的可以补充
mode 字符串

3:按热度排序

2:按时间排序

接口测试

为了确定抓包得到的URL、参数、响应之中,哪些参数是必需的,就得进行验证,在真正用代码验证之前,可以先用浏览器或postman测试,我以浏览器为例。

根据请求流程中的三步,这里我省略第一步

第二步,chrome直接访问构造好的带参数的URL(即接口1),成功返回json数据,如图11。另外,火狐可以直接格式化返回的json数据,如图12,这样就不用拿着chrome显示的json数据再去格式化网站上手动格式化,我之前用的格式化网站是JSON在线校验格式化工具(Be JSON),这是新版界面,旧版是在线JSON校验格式化工具(Be JSON),也可以在旧版界面点击新版跳转到新版,如图13。

图11 - chrome访问接口1返回的json数据

图12 - 火狐访问接口1返回的json数据

图13 - 在旧版界面点击新版跳转到新版,也可以直接访问新版URL

第三步,火狐直接访问构造好的带参数的URL(即接口2),成功返回json数据,如图14。另外,接口说明部分接口2处说带上callback和plat和_参数可能出错,如图15。

图14 - 火狐访问接口2返回的json数据

图15 - 火狐访问带上非必需的参数的URL时无法得到json数据

修改接口2中参数的值,如表示页码的next,同样可以得到json数据,这里就不截图了。

测试完成,说明接口URL及参数都是正确的,都能得到正确的json数据。

代码

更新,最核心的代码已删除,思路和其他代码保留。

整体流程就是请求流程部分中的那三步,最终你想爬取什么数据,去接口2返回的json数据中提取就行。页码可以根据for循环生成,即for循环中先生成一个页码,再构造URL,再请求并获取响应数据,再从响应数据中提取需要的数据。

另外,看完代码你可能有疑问,接口2返回的json数据中,已有all_count、is_end字段,如图14,为什么不直接用all_count除以每页的数据量得到页码总数进而得到最后一页的页码,或根据is_end判断是否是最后一页?

针对第一种,我测试时按每页20条数据算的,得到的页码总数与图4中那个样子不一致,而且后来发现有的动态请求一页得到18条数据,总之这种方法不行,起码我测试时不行,也可能我哪里做错了。

针对第二种,我测试时发现即便is_end为true,但依然可以请求下一页,只不过下一页得到的评论数据和本页相同;不过写文章时发现是测试时看错地方了,应该看与is_end的上一级cursor同级的replies,但是我代码里判断本页有没有数据确实是判断的这里的replies是否为空(在has_comment_data()中),所以也可以改成直接判断is_end是否为true,这种方法我写在注释里了 。

已知问题:对同一动态爬取多次,可能每次获得的总数据量不一致,原因是还没到算出来的最后一页时,replies就不返回数据了(具体在get_comment_data()中三引号注释里),所以无法保证一定能获得完整数据。

# -*- coding: utf-8 -*-
# 上一行设置编码的代码不能删,否则有一句注释会报编码错误
import requests
import json
import math
import time
import os
import csvheaders1={ # 获取oid时使用'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34',
}
headers2={ # 获取评论内容时使用'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34','Referer':'https://t.bilibili.com/'
}# url_for_get_oid='https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=567647071398441903' # 打开一条具体的动态时fiddler抓的原始URL。需从返回的信息中获取oid,dynamic_id是浏览器打开一条具体的动态时,地址栏末尾的一长串字符
url_for_get_oid='https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id={}'# url_for_get_comment='https://api.bilibili.com/x/v2/reply/main?callback=jQuery3310715507182874241_1637852200168&jsonp=jsonp&next=0&type=11&oid=164467640&mode=3&plat=1&_=1637852200169' # 在一条具体的动态页,页面滚动到底部第一次触发"正在加载..."时fiddler抓的原始URL。浏览器地址栏直接访问这个链接显示B站自定义的404页面,但去掉开头的callback参数和末尾的_参数后,浏览器地址栏可直接访问,返回json数据,另外测试发现plat参数也可去掉
# https://api.bilibili.com/x/v2/reply/main?callback=jQuery3310715507182874241_1637852200168&jsonp=jsonp&next=2&type=11&oid=164467640&mode=3&plat=1&_=1637852200171 在一条具体的动态页,页面滚动到底部第二次触发"正在加载..."时fiddler抓的原始URL。除了末尾的_参数,就只有next参数变了,说明next参数和页码有关,因_参数不是必需的
url_for_get_comment='https://api.bilibili.com/x/v2/reply/main?jsonp=jsonp&next={next}&type={type}&oid={oid}&mode={mode}'comment_detail_list=[] # 所有评论的详情,列表中每一条评论是一个字典def check_json_data(r): # 检查返回的数据是否是json格式try:json_data=r.json()except json.decoder.JSONDecodeError as e:raise Exception('发生了异常,可能因返回的数据不是json格式,或检查传入的url_for_get_oid及参数是否有误,具体异常为:'+'json.decoder.JSONDecodeError: '+str(e)) # raise json.decoder.JSONDecodeError()需三个参数,所以直接raise Exception();而Exception()中异常提示只能是字符串类型,这里的e是JSONDecodeError类型,所以强制转换;另外,这种写法输出异常提示时没有异常类型,所以以字符串形式手动加上except:raise Exception('发生了未捕获的异常')else:return json_datadef get_oid_and_type_and_total_page_number(url_for_get_oid, dynamic_id): # 获取url_for_get_comment中用的oid和type的值,和页码总数r=requests.get(url=url_for_get_oid,headers=headers1)json_data=check_json_data(r)try:type=json_data['data']['card']['desc']['type']total_comment_number=json_data['data']['card']['desc']['comment']except KeyError: # 返回的数据中没有指定的键,导致获取不到对应的值,说明当前URL中没有需要的json数据,即URL有误raise KeyError('无效的dynamic_id,请重新运行输入')except:raise Exception('发生了未捕获的异常')if type==2:oid=json_data['data']['card']['desc']['rid']type_in_url_for_get_comment=11elif type in [1,4,2048]:oid=dynamic_idtype_in_url_for_get_comment=17else:print(f'当前type变量的值{type}未被if捕获,需重新分析URL中type参数的值的所有可能')exit()total_page_number=math.ceil(total_comment_number/20)+19 # math.ceil(x)返回大于等于x的最小整数。每页20条数据,手动加19页防止页码总数由于各种原因计算错误,导致获取的数据不完整,且多出的页码由于没有数据会直接终止for循环return oid, type_in_url_for_get_comment, total_page_numberdef get_mode(): # 获取url_for_get_comment中用的modewhile True:sort_by=input('请输入评论的排序方式,3表示按热度排序,2表示按时间排序,最好不按时间排序,原因在save_data()的except语句的注释中:')if (sort_by=='3') or (sort_by=='2'):return sort_byelse:print('无效的排序方式,请重新输入')def has_comment_data(json_data): # 判断本页是否有评论,没有就直接终止for循环try:comment=json_data['data']['replies']except:raise Exception('发生了未捕获的异常')else:if comment:return Trueelse:print('本页无数据,爬取结束')return False'''也可以这样判断,需配合get_comment_data()中三引号注释中写法使用try:isEnd=json_data['data']['cursor']['is_end']except:raise Exception('发生了未捕获的异常')else:if str(isEnd) in ['False','false']:return Trueelse:print('这是最后一页,下一页无数据,爬完这一页就爬取结束')return False'''def get_comment_data(json_data): # 获取评论内容,不含对评论的回复try:replies_list=json_data # 自行从字典json_data中提取需要的数据except:raise Exception('发生了未捕获的异常')else:pass # 最核心的代码已删除'''has_comment_data()中若用判断is_end的方法,则get_comment_data()中try语句的else语句内,for循环遍历replies_list前,应加一句if判断,使整个for循环在这个if内if isinstance(replies_list,list) and len(replies_list)>0: # 有时当前页码返回的json数据中is_end是False,说明不是最后一页(即便是,最后一页也有数据),但此时replies中无数据,返回的replies可能是null(火狐浏览器访问接口看的,不是字符串,对应python中的NoneType类型)也可能是空列表,为确保后面页码的数据也能获取到(如果真的有数据),所以这里判断replies_list的类型和长度,只有它是列表且长度大于0时才说明本页有评论数据'''def save_data(dynamic_id,oid,type): # 保存所有评论的详情dir_path=os.path.abspath(os.path.dirname(__file__))file_name=f'B站动态ID{dynamic_id},oid{oid},type{type}的评论.csv' # 用代码自动删除评论时需动态的oid和type,写在文件名中方便读取file_path=dir_path+'/'+file_nametry:header=comment_detail_list[0].keys()except IndexError: # 按时间排序时由于部分页码(目前我发现的是页码为1和页码为2)返回的评论为空导致直接终止for循环,然后执行save_data(),若刚好这些页码是开始爬取的页码,则comment_detail_list中无数据,执行save_data()中try语句触发IndexError异常raise IndexError('comment_detail_list中无数据,数据保存失败')except:raise Exception('发生了未捕获的异常')else:# 不同保存方式的注释在bs4爬取招聘.py中with open(file_path,'w',newline='',encoding='utf-8') as f:writer=csv.DictWriter(f,fieldnames=header)writer.writeheader()writer.writerows(comment_detail_list)print('数据已保存到本地')'''string=json.dumps(comment_detail_list,ensure_ascii=False) # 将数据以json格式保存。ensure_ascii=False使json中的中文正常显示with open(dir_path+'/'+f'B站动态ID{dynamic_id},oid{oid},type{type}的评论.txt','w',encoding='utf-8') as fp:fp.write(string)print('数据已保存到本地')''''''with open(dir_path+'/'+f'B站动态ID{dynamic_id},oid{oid},type{type}的评论.txt','w',encoding='utf-8') as f:f.write(str(comment_detail_list)) # 将列表直接转为字符串写入文件print('数据已保存到本地')'''if __name__=='__main__':dynamic_id=input('请输入dynamic_id的值,它是浏览器打开一条具体的动态时,地址栏末尾的一长串字符:')url_for_get_oid=url_for_get_oid.format(dynamic_id)oid, type, total_page_number=get_oid_and_type_and_total_page_number(url_for_get_oid, dynamic_id)mode=get_mode()print(f'共有{total_page_number}页,这个数字已加入冗余,防止由于各种原因计算错误,导致获取的数据不完整,且多出的页码由于没有数据会直接终止for循环')start_page_number=int(input('请输入开始爬取的页码:')) # for循环中需是int类型end_page_number=int(input('请输入结束爬取的页码:'))if start_page_number==0: # next为0或1都返回第一页的数据start_page_number=1loop_count=0 # 记录循环执行次数for page_number in range(start_page_number,end_page_number+1):print(f'第{page_number}页开始爬取')comment_url=url_for_get_comment.format(next=page_number,type=type,oid=oid,mode=mode) # 注意等号左面不能写url_for_get_comment,会覆盖全局变量,导致next的值永远为第一轮循环中page_number的值,即start_page_number的值r=requests.get(url=comment_url,headers=headers2)json_data=check_json_data(r)if not has_comment_data(json_data): # 函数内若用三引号注释中写法,则这里要调整调用位置,调整到get_comment_data()之后,sleep()之前(最好紧挨sleep()),因若当前页是最后一页,则需先执行get_comment_data()获取当前页数据,再执行break终止循环breakget_comment_data(json_data)loop_count=loop_count+1print(f'第{page_number}页结束爬取')print() # 打印空行time.sleep(3)save_data(dynamic_id,oid,type)print(f'获取数据共执行了{loop_count}次循环,每页20条数据(有时18条),假设最后一页不足20条,则去重后的数据量应大于({loop_count}-1)*20={(loop_count-1)*20}条,请打开文件核对数据量是否正确。若数据量不足,根据需求决定是否重新爬取,如针对有些需求,比完整数据稍微少一些也不影响。')

参考链接:

手把手教你爬取B站动态下的评论(看了必会,2个字简单) - 哔哩哔哩

爬虫实战 - 如何爬取B站视频评论? - phyger - 博客园

【python爬虫】爬取bilibili动态下面的评论 - 哔哩哔哩

bilibili动态评论的爬取: 通过b站开放的APL接口进行一个评论的爬取,只爬取的评论本身内容,发布评论的网友信息没有进行一个爬取

第四个与第三个内容一样,但可读性更好

我在get_comment_data()末尾,只是简单判断新爬到的数据是否在已有数据中已存在,关于数据去重,可看以下参考链接:

Python数据去重_夜空下的凝视-CSDN博客_python 去重

Python判断列表里是否有重复元素的三种方法_宁宁Fingerstyle的博客-CSDN博客_python重复元素判定
python常用的去重方式 - 星牧 - 博客园

左手用R右手Python系列8——数据去重与缺失值处理 - 云+社区 - 腾讯云

python数据去重(pandas)_Oliver、He的博客-CSDN博客_python数据去重

python爬取B站动态的评论总数(不含用户评论内容详情)相关推荐

  1. 利用Python爬取基于AES对称加密算法的网易云音乐用户评论数据

    本文利用Python2.7根据网易云音乐歌曲ID爬取了该歌曲的所有用户评论数据.以id是28875120的歌曲<小岁月太着急>为示例,通过Chrome的DevTools工具获取已加密评论数 ...

  2. python爬取b站评论_学习笔记(1):写了个python爬取B站视频评论的程序

    学习笔记(1):写了个python爬取B站视频评论的程序 import requests import json import os table='fZodR9XQDSUm21yCkr6zBqiveY ...

  3. python爬取B站评论制作词云

    python爬取B站评论制作词云 江山代有才人出,B站评论占一半 废话不多说,咱们直接上代码` import imageio import jieba import wordcloud import ...

  4. python爬b站评论_学习笔记(1):写了个python爬取B站视频评论的程序

    学习笔记(1):写了个python爬取B站视频评论的程序 import requests import json import os table='fZodR9XQDSUm21yCkr6zBqiveY ...

  5. Python爬取B站弹幕方法介绍

    Python爬取B站弹幕方法介绍 文章目录 Python爬取B站弹幕方法介绍 前言 寻找弹幕数据 编写爬虫 B站弹幕数量 新技术介绍 参考文章 前言 最近同学要做东西,需要用 B 站的视频对应的弹幕数 ...

  6. python接收弹幕_闲着没事,尝试一下用Python爬取B站弹幕呀~

    原标题:闲着没事,尝试一下用Python爬取B站弹幕呀~ 前言 最近同学要做东西,需要用 B 站的视频对应的弹幕数据做分析,于是请我帮忙爬取 B 站视频的弹幕数据. 对于爬虫而言,我们需要找到对应数据 ...

  7. python为啥爬取数据会有重复_使用python爬取B站千万级数据

    Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...

  8. python爬取bilibili弹幕_用Python爬取B站视频弹幕

    原标题:用Python爬取B站视频弹幕 via:菜J学Python 众所周知,弹幕,即在网络上观看视频时弹出的评论性字幕.不知道大家看视频的时候会不会点开弹幕,于我而言,弹幕是视频内容的良好补充,是一 ...

  9. 用Python爬取B站、腾讯视频、芒果TV和爱奇艺视频弹幕

    众所周知,弹幕,即在网络上观看视频时弹出的评论性字幕.不知道大家看视频的时候会不会点开弹幕,于我而言,弹幕是视频内容的良好补充,是一个组织良好的评论序列.通过分析弹幕,我们可以快速洞察广大观众对于视频 ...

最新文章

  1. Easyui 让Window弹出居中与最大化后居中
  2. keras cnn注意力机制_TensorFlow、PyTorch、Keras:NLP框架哪家强
  3. 你应该更新的Java知识之常用程序库
  4. 分布式锁和mysql事物扣库存_浅谈库存扣减和锁
  5. flymcu无法打开串口_西门子1200与其他PLC/组态软件无线串口通讯(自由口)
  6. 00600 ora 关闭oracle_Oracle集群高可用故障切换
  7. 随想录(单片机和步进电机学习笔记)
  8. php mysql link_php与mysql连接
  9. linux Load average负载详细解释
  10. Java本地缓存技术选型(Guava Cache、Caffeine、Encache)
  11. 一级计算机office选择题题库及答案,计算机一级msoffice选择题题库40套含答案
  12. opencv半透明填充不规则区域
  13. 当下的力量实践手册读书笔记(1.30)
  14. B05 - 008、什么是大数据
  15. alios things开发板_AliOS Things开发:让你的开发板支持AliOS Studio调试-阿里云开发者社区...
  16. 2022年武汉专精特新小巨人企业奖励补贴以及申报条件汇总
  17. 第七章租赁法律与合同
  18. 参数估计:最大似然估计MLE
  19. 使用breakpad收集native奔溃日志及dump解析
  20. 给中国学生的第三封信:成功、自信、快乐

热门文章

  1. gdal 实现 热点分析 (Getis-Ord Gi*)
  2. 如何卸载avast free antivirus软件?
  3. ORACLE数据库日期更新到时分秒格式
  4. java-php-python-ssm基于移动端的选课系统的设计与实现服务器端计算机毕业设计
  5. 触摸屏中应用的电容式触摸芯片
  6. 南京大学量子计算机陈教授,南京大学于扬教授应邀访问武汉物数所
  7. 揭秘:游戏开发的薪资情况和发展前景!
  8. 《Photoshop修色圣典(第5版)》—第1章1.10节何时两种效果最佳
  9. c语言hypot函数,hypot ( )【C语言库函数源代码】
  10. 根据出行月份(1~12)和仓位(头等舱1,经济舱2)输出实际机票价格。