人生苦短耐朴,我用python
碰到喜歡的人該怎么辦?
??:樓主樓主盹憎,最近碰到一個喜歡的人筛峭,我該怎么辦?
LZ:什么人芭忝俊影晓?
??:一個up主。
LZ:當(dāng)然是爬他鴨檩禾!(??)
這次我們就來爬一爬up主的視頻數(shù)據(jù)
第一步:導(dǎo)入對應(yīng)的模塊
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
import re
import pymongo
import time
import datetime as dt
import random
import pandas as pd
import warnings
warnings.filterwarnings('ignore')#忽略警告
print('導(dǎo)入成功!')
這里我們用的模塊主要有:
requests —— 用于訪問網(wǎng)頁
BeautifulSoup —— 用于解析網(wǎng)頁
selenium —— 測試網(wǎng)頁的工具包挂签,模擬人操作網(wǎng)頁
re —— 通過正則表達式,提取內(nèi)容
pymongo —— Python操作Mongo數(shù)據(jù)庫的工具包
本文涉及的模塊較多盼产,后面寫其他文章將補充其用法
第二步:獲取頁面的url
我們進入UP主的首頁看看
我們要爬取的目標(biāo)是視頻的相關(guān)信息饵婆,這里我們選擇投稿這個標(biāo)簽,這是我們會發(fā)現(xiàn)網(wǎng)址發(fā)生了變化辆飘,當(dāng)切換翻頁時啦辐,網(wǎng)頁也發(fā)生了變化谓传,而這個變化是有規(guī)律可循的蜈项。
第一頁的網(wǎng)址://space.bilibili.com/82366241/video?tid=0&page=1&keyword=&order=pubdate”
第二頁的網(wǎng)址://space.bilibili.com/82366241/video?tid=0&page=2&keyword=&order=pubdate”
......(自行修改網(wǎng)址)
這里可以寫一個循環(huán)函數(shù)就可獲取所有視頻列表的網(wǎng)址。
def get_urls(n):
#【分頁網(wǎng)頁url采集】函數(shù)
#n:頁數(shù)參數(shù)
lst = []
for i in range(n):
lst.append('https://space.bilibili.com/82366241/video?tid=0&page=%i&keyword=&order=pubdate' %(i+1))
return lst
urllst = get_urls(14)#這里up的視頻投稿一共有14頁
獲取了所有的視頻網(wǎng)頁后我們就需要爬取每個投稿頁面下視頻對應(yīng)的鏈接续挟,再進一步去或者視頻頁面的一些信息紧卒。
這里requests + BeautifulSoup的方式?jīng)]辦法直接解析up主的頁面,我們就用selenium去獲取相關(guān)信息诗祸。
通過Chrome瀏覽器直接檢查網(wǎng)頁的元素(這里建議使用Chrome瀏覽器)
根據(jù)網(wǎng)頁標(biāo)簽我們就可以直接定位我們要爬取的內(nèi)容了跑芳。
lilst = []
brower = webdriver.Chrome()
for u in urllst:
brower.get(u)
time.sleep(1)#休息1秒等待網(wǎng)頁緩沖
ul = brower.find_element_by_class_name('list-list')
lis = ul.find_elements_by_tag_name('a')
for li in lis:
lilst.append(li.get_attribute('href'))
lilst = list(set(lilst))#這里由于存在圖片和文字標(biāo)題兩個鏈接,這里做一個去重的操作
這里我嘗試過不運用睡眠1秒這個操作直颅,但是有時因為網(wǎng)速不穩(wěn)定可能會導(dǎo)致數(shù)據(jù)查找失敗博个,所以這里做了一個休息1秒的設(shè)定。同時功偿,這里去重還用了一個“小技巧”朽缴,因為在python里集合是不能用重復(fù)項的捡需,所以這里將列表變?yōu)榧显僮優(yōu)榱斜韥砣コ貜?fù)項。這樣我們就獲取了所有視頻的網(wǎng)址信息了。接下來就可以爬數(shù)據(jù)了掌敬。o( ̄ ̄)ブ
第三步:解析網(wǎng)頁獲取數(shù)據(jù)
解析網(wǎng)頁之前要做兩項鋪墊,要獲取網(wǎng)頁的User-Agent和Cookie仪芒,這里要登陸B(tài)站蛮粮,然后打開剛剛采集的網(wǎng)址(這里只用一個網(wǎng)頁講解,后面用循環(huán)就可以操作就可以獲取全部網(wǎng)頁的)
當(dāng)然這里檢查的時候要重新刷新一下颤诀,否則看不到這些信息字旭。
然后將cookie存成字典形式对湃。
dic_c1 = {}
cookies1 = '''buvid3=03FCB17B-8E7D-46F0-8156-838D7D5A2B9940786infoc; LIVE_BUVID=AUTO4615631674934688; sid=cjdl8sqy; DedeUserID=15107370; DedeUserID__ckMd5=051111d6cb7f72d5; SESSDATA=19a2f18d%2C1565759681%2C31bec571; bili_jct=fa019ab71d9655efbcc14a1cb272c4ab; _uuid=5137E4C3-A530-CCC3-493F-5D34E4758B0B92699infoc; UM_distinctid=16bf40e1ab957c-0f454459c38526-e343166-1fa400-16bf40e1aba774; CNZZDATA2724999=cnzz_eid%3D1822973876-1563165600-https%253A%252F%252Fwww.bilibili.com%252F%26ntime%3D1563165600; bp_t_offset_15107370=276288717802840143; Hm_lvt_8a6e55dbd2870f0f5bc9194cddf32a02=1563167705,1563167765; Hm_lpvt_8a6e55dbd2870f0f5bc9194cddf32a02=1563167765; innermark=1; CURRENT_FNVAL=16; rpdid=|(umRu)YJJ~~0J'ulYJuY)|R|; stardustvideo=1'''
for i in cookies1.split('; '):
dic_c1[i.split('=')[0]] = i.split('=')[1]
嘗試打開網(wǎng)址
開始解析網(wǎng)頁,這個頁面里我們主要獲取3個信息(標(biāo)題谐算,UP主熟尉,上線的時間)還有個aid這是視頻在B站唯一值,這個數(shù)據(jù)可以直接網(wǎng)址里利用正則獲戎拗(.../av53742321這串?dāng)?shù)字就是)斤儿。
ui = 'https://www.bilibili.com/video/av53742321'
r1 = requests.get(url = ui,headers = dic_h,cookies = dic_c1)
soup1 = BeautifulSoup(r1.text,'lxml')
title = soup1.h1['title']
time = re.search(r'(\d*-\d*-\d* \d*:\d*:\d*)',soup1.find('div',class_="video-data").text).group(1)
aid = re.search(r'av(\d*).*',ui).group(1)
up = soup1.find('div',class_="name").a.text
通過aid我們可以打開對應(yīng)的(網(wǎng)址查看代碼)獲取視頻的播放量,投幣恐锦,點贊往果,收藏等數(shù)據(jù)。這個網(wǎng)址我們要重新獲取cookie信息一铅,這里我就不重復(fù)了陕贮。
r2 = requests.get(url = 'https://api.bilibili.com/x/web-interface/archive/stat?aid=53742321',
headers = d_h,cookies = d_c2)#修改“aid=”就可以獲取對應(yīng)視頻信息了
soup2 = BeautifulSoup(r2.text,'lxml')
name = soup1.find('div',class_="info open").text
info = re.search(r'"view.*(\d*),"now_rank"',soup2.text).group().split(',')[:-2]
date = str(dt.date.today())
dic = {}
dic['標(biāo)題'] = title
dic['介紹'] = name
dic['aid'] = aid
dic['上線時間'] = time
dic['up主'] = up
dic['采集時間'] = date
for i in info:
dic[i.split(':')[0].replace('"','')] = i.split(':')[1]
第四步:保存數(shù)據(jù)
如果電腦安裝好了Mongo存數(shù)據(jù)就很簡單了
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
db = myclient['看電影了沒']
datatable = db['視頻信息']
第五步:循環(huán)采集
把剛剛采集過程轉(zhuǎn)換成函數(shù),然后循環(huán)執(zhí)行函數(shù)潘飘,就可以完成爬取up主的所有數(shù)據(jù)了肮之。
def get_data(ui,d_h,d_c1,d_c2,table):
#【視頻網(wǎng)頁url采集】函數(shù)
#u:起始網(wǎng)址
#d_h:user-agent信息
#d_c1,d_c2:cookies信息(兩個網(wǎng)址)
#table:要存入mongo的collection名稱
r1 = requests.get(url = ui,headers = d_h,cookies = d_c1)
soup1 = BeautifulSoup(r1.text,'lxml')
title = soup1.h1['title']
time = re.search(r'(\d*-\d*-\d* \d*:\d*:\d*)',soup1.find('div',class_="video-data").text).group(1)
#long =
aid = re.search(r'av(\d*).*',ui).group(1)
up = soup1.find('div',class_="name").a.text
r2 = requests.get(url = 'https://api.bilibili.com/x/web-interface/archive/stat?aid=%s' %aid,
headers = d_h,cookies = d_c2)
soup2 = BeautifulSoup(r2.text,'lxml')
name = soup1.find('div',class_="info open").text
info = re.search(r'"view.*(\d*),"now_rank"',soup2.text).group().split(',')[:-2]
date = str(dt.date.today())
dic = {}
dic['標(biāo)題'] = title
dic['介紹'] = name
dic['aid'] = aid
dic['上線時間'] = time
dic['up主'] = up
dic['采集時間'] = date
for i in info:
dic[i.split(':')[0].replace('"','')] = i.split(':')[1]
table.insert_one(dic)
return len(dic)
進行循環(huán)采集
errorlst = []
datalst = []
for ui in lilst:
try:
datalst.append(get_data(ui,dic_h,dic_c1,dic_c2,datatable))
print('數(shù)據(jù)采集成功,總共采集%i條數(shù)據(jù)' % len(datalst))
except:
errorlst.append(ui)
print('數(shù)據(jù)采集失敗卜录,數(shù)據(jù)網(wǎng)址為:',ui)
#time.sleep(random.randint(1,3))
最后我們用Robo 3T查看一下采集的數(shù)據(jù)??
樓主去擁抱up主了戈擒,下次見??
ps:點擊查看全部代碼