python數(shù)據(jù)分析|B站視頻搜索結(jié)果爬蟲(chóng)入庫(kù)

要求:在B站搜索多個(gè)關(guān)鍵字,并將搜索到的視頻結(jié)果(包括視頻名流强,視頻連接,點(diǎn)擊量呻待,收藏量打月,彈幕數(shù)和長(zhǎng)傳時(shí)間)錄入數(shù)據(jù)庫(kù)

了解網(wǎng)頁(yè)

爬取數(shù)據(jù)前,我們需要先了解網(wǎng)頁(yè)結(jié)構(gòu)带污,以B站首頁(yè)為例https://www.bilibili.com/
僵控,按快捷鍵【Ctrl+U】打開(kāi)源碼頁(yè)面

認(rèn)識(shí)網(wǎng)頁(yè)結(jié)構(gòu)

網(wǎng)頁(yè)一般由三部分組成,分別是 HTML(超文本標(biāo)記語(yǔ)言)鱼冀、CSS(層疊樣式表)和 JScript(活動(dòng)腳本語(yǔ)言)报破。
HTML
HTML 是整個(gè)網(wǎng)頁(yè)的結(jié)構(gòu),相當(dāng)于整個(gè)網(wǎng)站的框架千绪。帶“<”充易、“>”符號(hào)的都是屬于 HTML 的標(biāo)簽,并且標(biāo)簽都是成對(duì)出現(xiàn)的荸型。

標(biāo)簽
<head>..</head> 包含了所有的頭部標(biāo)簽元素盹靴。在 <head>元素中可以插入腳本(scripts), 樣式文件(CSS),及各種 meta 信息瑞妇「寰玻可以添加的元素標(biāo)簽為: <title>, <style>, <meta>, <link>, <script>, <noscript> 和 <base>。
<html>..</html> 表示標(biāo)記中間的元素是網(wǎng)頁(yè)
<body>..</body> 表示用戶(hù)可見(jiàn)的內(nèi)容
<div>..</div> 表示框架
<p>..</p> 表示段落
<li>..</li> 表示列表
<img>..</img> 表示圖片
<h1>..</h1> 表示標(biāo)題
<a href="">..</a> 表示超鏈接

CSS
CSS 表示樣式辕狰,表示下面引用一個(gè) CSS改备,在 CSS 中定義了外觀(guān)。


JScript
JScript 表示功能蔓倍。交互的內(nèi)容和各種特效都在 JScript 中悬钳,JScript 描述了網(wǎng)站中的各種功能盐捷。

如果用人體來(lái)比喻,HTML 是人的骨架默勾,并且定義了人的嘴巴碉渡、眼睛、耳朵等要長(zhǎng)在哪里母剥。CSS 是人的外觀(guān)細(xì)節(jié)滞诺,如嘴巴長(zhǎng)什么樣子,眼睛是雙眼皮還是單眼皮环疼,是大眼睛還是小眼睛铭段,皮膚是黑色的還是白色的等。JScript 表示人的技能秦爆,例如跳舞、唱歌或者演奏樂(lè)器等憔披。

寫(xiě)一個(gè)簡(jiǎn)單的 HTML

打開(kāi)一個(gè)記事本等限,輸入下面的內(nèi)容:

<head>
 <title> 這里是標(biāo)題</title>
</head>
<body>
 <div style="color:#0000FF">
  <h1>這是被第一個(gè)div定義的標(biāo)題1</h1>
  <p>這里是被第一個(gè)div定義第一個(gè)段落</p>
 </div>
 <div style="color:#00FF00">
   <ul>
   <li><a >列表內(nèi)容1 百度鏈接</a></li>
   <li>列表內(nèi)容2</li>
   </ul>
 </div>
</body>

輸入代碼后,保存記事本芬膝,然后修改文件名和后綴名為"HTML.html"望门,運(yùn)行該文件后的效果,如圖锰霜。

使用 requests 庫(kù)請(qǐng)求網(wǎng)站

若未安裝 requests 庫(kù)筹误,可在終端中使用pip安裝庫(kù):

pip install requests

爬蟲(chóng)的基本原理

網(wǎng)頁(yè)請(qǐng)求的過(guò)程分為兩個(gè)環(huán)節(jié):
Request (請(qǐng)求):也就是向服務(wù)器發(fā)送訪(fǎng)問(wèn)請(qǐng)求。
Response(響應(yīng)):服務(wù)器在接收到用戶(hù)的請(qǐng)求后癣缅,會(huì)驗(yàn)證請(qǐng)求的有效性厨剪,然后向用戶(hù)(客戶(hù)端)發(fā)送響應(yīng)的內(nèi)容,客戶(hù)端接收服務(wù)器響應(yīng)的內(nèi)容友存,將內(nèi)容展示出來(lái)祷膳,就是我們所熟悉的網(wǎng)頁(yè)請(qǐng)求

網(wǎng)頁(yè)請(qǐng)求的方式也分為兩種:
GET:最常見(jiàn)的方式,一般用于獲取或者查詢(xún)資源信息屡立,也是大多數(shù)網(wǎng)站使用的方式直晨,響應(yīng)速度快。
POST:相比 GET 方式膨俐,多了以表單形式上傳參數(shù)的功能勇皇,因此除查詢(xún)信息外,還可以修改信息焚刺。

所以敛摘,在寫(xiě)爬蟲(chóng)前要先確定向誰(shuí)發(fā)送請(qǐng)求,用什么方式發(fā)送檩坚。B站是使用get請(qǐng)求的着撩,所以我們使用get方式抓取數(shù)據(jù)

獲取B站視頻搜索結(jié)果url列表

demand參數(shù):表示搜索視頻排序方式(watch:按播放量排序诅福,dm:按彈幕量排序,time:按上傳時(shí)間排序拖叙,collect:按收藏量排序)
kw參數(shù):表示搜索的視頻關(guān)鍵字列表

def bilibili_url (demand,kw):
    if demand == 'watch':
        url = 'https://search.bilibili.com/all?keyword={}&order=click&duration=0&tids_1=0'
    elif  demand == 'dm':
        url = 'https://search.bilibili.com/all?keyword={}&order=dm&duration=0&tids_1=0'
    elif demand == 'time':
        url = 'https://search.bilibili.com/all?keyword={}&order=pubdate&duration=0&tids_1=0'
    elif demand == 'collect':
        url = 'https://search.bilibili.com/all?keyword={}&order=stow&duration=0&tids_1=0'
    else :
        url = 'https://search.bilibili.com/all?keyword={}'
    url_list = []
    for i in kw:
        list_view = url.format(i)
        url_list.append(list_view)
    return url_list

信息爬取

def get_bilibili_play_info(url_list):
    info = []  #建立一個(gè)空列表存放信息
    seen = set()  #建立一個(gè)空集合氓润,去除重復(fù)字典
    for j in url_list:
        for i in range(50):
            t=random.randint(0,9)  
            time.sleep(t)  #隨機(jī)sleep0到9秒防反爬
            url=j + ('&page=%d' %(i+1))  #跳轉(zhuǎn)頁(yè)數(shù),B站支持顯示50頁(yè)搜索信息
            print (url)
            headers = {'Accept': 'text/html, application/xhtml+xml, image/jxr, */*',
                       'Accept - Encoding':'gzip, deflate',
                       'Accept-Language':'zh-Hans-CN, zh-Hans; q=0.5',
                       'Connection':'Keep-Alive',
                       'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063'}
            bz_data = requests.get(url,headers=headers) 
            #添加headers參數(shù)偽裝瀏覽器反爬
            soup = BeautifulSoup(bz_data.text,'lxml')  #解析網(wǎng)頁(yè)信息
            for link in soup.find_all(name='li',class_="video-item matrix"):
                #對(duì)每一個(gè)視頻信息循環(huán)處理薯鳍,link的信息如下圖
                info_dic = {}
                for temp in link.find_all(name='a',class_="img-anchor"):
                    #提取a標(biāo)簽咖气,temp信息如下圖
                    info_dic['title'] = temp.get('title')  #視頻名信息
                    info_dic['url'] = "http:%str" %temp.get('href') #視頻url信息
                a = str(link.find('span',class_='so-icon watch-num'))  
                #a= '<span class="so-icon watch-num" title="觀(guān)看"><i class="icon-playtime"></i>\n        1230.1萬(wàn)\n      </span>'
                if '萬(wàn)' in a:
                    watch_num=re.findall(r"\d+\.\d+", a)
                    watch_num[0]=(float(watch_num[0]))*10000
                    info_dic['watch_num']=int(watch_num[0])
                else :
                    watch_num=re.findall(r"\d+", a)
                    watch_num[0]=float(watch_num[0])
                    info_dic['watch_num']=int(watch_num[0])
                a = str(link.find('span',class_='so-icon hide'))  
                #'<span class="so-icon hide" title="彈幕"><i class="icon-subtitle"></i>\n        5.8萬(wàn)\n      </span>'
                if '萬(wàn)' in a:
                    hide=re.findall(r"\d+\.\d+", a)
                    hide[0]=(float(hide[0]))*10000
                    info_dic['dm']=int(hide[0])
                else :
                    hide=re.findall(r"\d+", a)
                    hide[0]=int(hide[0])
                    info_dic['dm']=int(hide[0])
                a = str(link.find('span',class_='so-icon time'))  
                #'<span class="so-icon time" title="上傳時(shí)間"><i class="icon-date"></i>\n        2020-02-01\n      </span>'
                info_dic['upload_time']=re.findall(r"(\d{4}-\d{1,2}-\d{1,2})", a)[0]
                #如果需要提取為datatime格式,可以用下面這條
                #info_dic['上傳時(shí)間']=datetime.date(*map(int, time_list[0].split('-')))
                t = tuple(info_dic.items())
                if t not in seen:
                    #篩選是否有重復(fù)的視頻信息
                    seen.add(t)
                    info.append(info_dic)
    return info

其中挖滤,每個(gè)視頻的網(wǎng)頁(yè)解析信息link結(jié)果如圖:

temp信息如圖:

數(shù)據(jù)入庫(kù)

參數(shù):host崩溪,user,password斩松,db為連接數(shù)據(jù)庫(kù)的參數(shù)

def rq(host,user,password,db,table,info):
    cols = ", ".join('`{}`'.format(k) for k in info[0].keys())
    #提取列表中字典的鍵伶唯,格式為`key1`,`key2`.....
    val_list = []
    for i in info:
        #僅保留列表中所有字典的值,以元組格式重新存入新列表
        val_tup = tuple(i.values())
        val_list.append(val_tup)
    cols_val = '%s'
    for j in range(len(list(info[0].keys()))-1):
        #根據(jù)鍵個(gè)數(shù)添加%s
        cols_val = cols_val + ",%s" 
    sql="insert into %s(%s) value(%s)"
    res_sql = sql % (table,cols,cols_val)
    #res_sql ="insert into table(`key1`,`key2`...) value(%s,%s...)"
    db=pymysql.connect(host=host,user=user,password=password,db=db,charset='utf8')
    #連接數(shù)據(jù)庫(kù)
    cursor = db.cursor()
    cursor.executemany(res_sql,val_list)  
    #對(duì)數(shù)據(jù)庫(kù)進(jìn)行批量操作惧盹,其中val_list必須為以元組組成的列表格式
    db.commit()  # 提交更新的數(shù)據(jù)到數(shù)據(jù)庫(kù)
    cursor.fetchall() #查詢(xún)處理后數(shù)據(jù)結(jié)果
    print ('入庫(kù)完成乳幸!')
    # 關(guān)閉cursor游標(biāo)
    cursor.close()
    #關(guān)閉服務(wù)器
    db.close()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钧椰,隨后出現(xiàn)的幾起案子粹断,更是在濱河造成了極大的恐慌,老刑警劉巖嫡霞,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓶埋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡诊沪,警方通過(guò)查閱死者的電腦和手機(jī)养筒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)娄徊,“玉大人闽颇,你說(shuō)我怎么就攤上這事〖娜瘢” “怎么了兵多?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)橄仆。 經(jīng)常有香客問(wèn)我剩膘,道長(zhǎng),這世上最難降的妖魔是什么盆顾? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任怠褐,我火速辦了婚禮,結(jié)果婚禮上您宪,老公的妹妹穿的比我還像新娘奈懒。我一直安慰自己奠涌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布磷杏。 她就那樣靜靜地躺著溜畅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪极祸。 梳的紋絲不亂的頭發(fā)上慈格,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音遥金,去河邊找鬼浴捆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛稿械,可吹牛的內(nèi)容都是我干的选泻。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼美莫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼滔金!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起茂嗓,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎科阎,沒(méi)想到半個(gè)月后述吸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锣笨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年蝌矛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片错英。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡入撒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出椭岩,到底是詐尸還是另有隱情茅逮,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布判哥,位于F島的核電站献雅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏塌计。R本人自食惡果不足惜挺身,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锌仅。 院中可真熱鬧章钾,春花似錦墙贱、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至窍箍,卻和暖如春串纺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背椰棘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工纺棺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邪狞。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓祷蝌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親帆卓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巨朦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348