爬取bilibiliTop100条热门视频信息
对于信息的爬取可以分为三个步骤进行处理,分别是获取网页、获取和解析数据最后保存数据。于是我们的主函数的框架如下:
def main():
# 1. 获取网页
baseurl = "https://www.bilibili.com/v/popular/rank/all"
# 2. 获取和解析数据
datalist = getData(baseurl)
# 3. 保存数据
savepath = "./B站热门视频.xls"
saveData(datalist,savepath)
爬虫毕竟是爬虫在它进行网页的访问的时候一般不能够直接进行访问,需要进行一定的伪装,伪装的信息可以通过Fn+F12查看。
以上URL是我们目标爬取网址,访问的方式也可以看到是GET,为了进行伪装,需要得到访问网页的正式信息,我们继续查看信息,可以看到以下:
这里我们选取user-agent和cookies这两条信息(伪装的信息越多越好),user-agent其实是游览器的版本信息,cookies是用户的信息(非常重要,没有会被反扒)。
def askURL(url):
head = {
"user-agent" : "Mozilla / 5.0(Windows NT 10.0;WOW64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 88.0.4324.104 Safari / 537.36",
"referer" : "https: // www.bilibili.com /",
"cookie": "_uuid = DFE59F2A - D16B - 327E - D501 - 9CA14392FF8059467infoc;buvid3 = 0041FC1C - 2C18 - 4DDE - 965F - 9DEF43D88176155809infoc;rpdid = | (YYR~ | uklm0J'ul))u~JRuJ; sid=9n9kd7a4; LIVE_BUVID=AUTO2815885539756041; blackside_state=1; CURRENT_FNVAL=80; PVID=1; CURRENT_QUALITY=80; DedeUserID=434641640; DedeUserID__ckMd5=1b9357ca56a49330; SESSDATA=ab62e58a%2C1619879365%2C80832*b1; bili_jct=01ecd2f4c1f3d0e94aa31b03a7bea6ec; bp_t_offset_434641640=491560557515702800; bp_video_offset_434641640=491834756822300005; finger=1777945899"
}
request = urllib.request.Request(url,headers = head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e,"code")
if hasattr(e,"reason"):
print(e,"reason")
return html
在获取完网页的解析后的html文件之后,然后就是对你需要的信息进行筛选,通过观察信息的结构先进行定位,定位之后在通过正则表达式再次进行信息的筛选。
可以通过以下的方式获取需要的信息的特征,比如我需要得到B站热门视频的每条视屏的信息:
以下就是对应的模块的代码信息:
找寻的方式有很多,比如你可以用li行进寻找,每一个li都对应着一个热门视频信息。但其实发现在所有内容中只有在这个模块中div对应的class是content,于是我们可以用一下的方式进行寻找:
html = askURL(baseurl)
soup = BeautifulSoup(html, "html.parser")
soup.find_all("div",class_="content")
在确定每个视频的位置之后,就只需要在获得的代码中进一步筛选,比如需要在这个模块中找出排名、链接、名字、播放量、评论数、综合得分等等…
那就意味着,我们需要对每一个你需要得到的信息进行特征的提取,然后再是筛选出信息,这里就需要用到正则表达式:
findLink = re.compile(r'<a href="(.*?)" target="_blank">')
findName = re.compile(r'<a class="title" href=".*?" target="_blank">(.*)</a>')
findPlay = re.compile(r'<span class="data-box"><i class="b-icon play"></i>(.*?)</span>',re.S)
findView = re.compile(r'<span class="data-box"><i class="b-icon view"></i>(.*?)</span>',re.S)
findUP = re.compile(r'<span class="data-box up-name"><i class="b-icon author"></i>(.*?)</span>',re.S)
findGrades = re.compile(r'<div class="pts"><div>(.*?)</div>')
以上是通过观察源代码,发现每条信息的特征,然后用正则表达式表示这种特征,于是我们有以下获取信息的代码:
def getData(baseurl):
datalist = []
html = askURL(baseurl)
# print(html)
soup = BeautifulSoup(html, "html.parser") # 形成树形结构对象
for item in soup.find_all("div",class_="content"):
# print(item)
data = []
item = str(item)
# 视频链接
link = re.findall(findLink,item)[0]
data.append(link)
# 视频名字
name = re.findall(findName,item)[0]
data.append(name)
# 播放量
play = re.findall(findPlay,item)[0]
# print(play)
data.append(play)
# 评论数
view = re.findall(findView,item)[0]
# print(view)
data.append(view)
# UP个人空间链接
uplink = re.findall(findLink,item)[1]
# print(uplink)
data.append(uplink)
# UP主
UP = re.findall(findUP,item)[0]
# print(UP)
data.append(UP)
# 综合得分
grades = re.findall(findGrades,item)[0]
# print(grades)
data.append(grades)
datalist.append(data)
return datalist
在获取完数据之后,就需要对数据进行保存,可以直接用表格保存,这样方便,也可以用数据库保存。
def saveData(datalist,savepath):
book = xlwt.Workbook(encoding="utf-8")
sheet = book.add_sheet("B站热门",cell_overwrite_ok=True)
col = ("排名","视频链接","视频名字","播放量","评论数","UP个人空间链接","UP主","综合得分")
for i in range(0,8):
sheet.write(0,i,col[i])
for i in range(0,100):
print("第%d条"%i)
data = datalist[i]
sheet.write(i+1,0,i+1)
# print(data)
for j in range(0,7):
sheet.write(i+1,j+1,data[j])
book.save(savepath) # 保存数据表
那么以上就完成了整个信息爬取的过程,以下贴上全部代码:
from bs4 import BeautifulSoup #网页解析,获取数据
import re #正则表达式,进行文字匹配
import urllib.request,urllib.error #指定URL,获取网页数据
import xlwt #进行excel操作
def main():
# 1. 获取网页
baseurl = "https://www.bilibili.com/v/popular/rank/all"
# 2. 获取和解析数据
datalist = getData(baseurl)
# 3. 保存数据
savepath = "./B站热门视频.xls"
saveData(datalist,savepath)
findLink = re.compile(r'<a href="(.*?)" target="_blank">')
findName = re.compile(r'<a class="title" href=".*?" target="_blank">(.*)</a>')
findPlay = re.compile(r'<span class="data-box"><i class="b-icon play"></i>(.*?)</span>',re.S)
findView = re.compile(r'<span class="data-box"><i class="b-icon view"></i>(.*?)</span>',re.S)
findUP = re.compile(r'<span class="data-box up-name"><i class="b-icon author"></i>(.*?)</span>',re.S)
findGrades = re.compile(r'<div class="pts"><div>(.*?)</div>')
def getData(baseurl):
datalist = []
html = askURL(baseurl)
# print(html)
soup = BeautifulSoup(html, "html.parser") # 形成树形结构对象
for item in soup.find_all("div",class_="content"):
# print(item)
data = []
item = str(item)
# 视频链接
link = re.findall(findLink,item)[0]
data.append(link)
# 视频名字
name = re.findall(findName,item)[0]
data.append(name)
# 播放量
play = re.findall(findPlay,item)[0]
# print(play)
data.append(play)
# 评论数
view = re.findall(findView,item)[0]
# print(view)
data.append(view)
# UP个人空间链接
uplink = re.findall(findLink,item)[1]
# print(uplink)
data.append(uplink)
# UP主
UP = re.findall(findUP,item)[0]
# print(UP)
data.append(UP)
# 综合得分
grades = re.findall(findGrades,item)[0]
# print(grades)
data.append(grades)
datalist.append(data)
return datalist
def saveData(datalist,savepath):
book = xlwt.Workbook(encoding="utf-8")
sheet = book.add_sheet("B站热门",cell_overwrite_ok=True)
col = ("排名","视频链接","视频名字","播放量","评论数","UP个人空间链接","UP主","综合得分")
for i in range(0,8):
sheet.write(0,i,col[i])
for i in range(0,100):
print("第%d条"%i)
data = datalist[i]
sheet.write(i+1,0,i+1)
# print(data)
for j in range(0,7):
sheet.write(i+1,j+1,data[j])
book.save(savepath) # 保存数据表
def askURL(url):
head = {
"user-agent" : "Mozilla / 5.0(Windows NT 10.0;WOW64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 88.0.4324.104 Safari / 537.36",
"referer" : "https: // www.bilibili.com /",
"cookie": "_uuid = DFE59F2A - D16B - 327E - D501 - 9CA14392FF8059467infoc;buvid3 = 0041FC1C - 2C18 - 4DDE - 965F - 9DEF43D88176155809infoc;rpdid = | (YYR~ | uklm0J'ul))u~JRuJ; sid=9n9kd7a4; LIVE_BUVID=AUTO2815885539756041; blackside_state=1; CURRENT_FNVAL=80; PVID=1; CURRENT_QUALITY=80; DedeUserID=434641640; DedeUserID__ckMd5=1b9357ca56a49330; SESSDATA=ab62e58a%2C1619879365%2C80832*b1; bili_jct=01ecd2f4c1f3d0e94aa31b03a7bea6ec; bp_t_offset_434641640=491560557515702800; bp_video_offset_434641640=491834756822300005; finger=1777945899"
}
request = urllib.request.Request(url,headers = head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e,"code")
if hasattr(e,"reason"):
print(e,"reason")
return html
if __name__ == "__main__": #程序执行时
#调用函数
main()
print("爬取完毕!")