数学建模社区-数学中国

标题: Python 爬取b站热门视频信息并导入Excel表格 [打印本页]

作者: 杨利霞    时间: 2020-3-30 11:09
标题: Python 爬取b站热门视频信息并导入Excel表格
Python 爬取b站热门视频信息并导入Excel表格8 o9 Y9 C- y0 d. Y7 V2 {3 X
效果图:
5 h7 L, B) h5 C! ]( ~, N 1.png / s, s4 U4 i7 r/ N! E
1.工先利其事必先利器,首先我们得下载相应的库:
' j5 k& S8 ?2 M8 Gpip install requests
0 u5 F0 M/ Q# [' Vpip install lxml1 a  {% d/ Q# z/ d6 O) p
pip install xlwt" a- `# b. }, n  G
! x" [6 M7 [" p/ B5 Q

6 p6 K" ]. A6 `1 i: Arequests 向网页发送请求5 D+ H4 d. m8 \& [
lxml 处理xml文件(xpath)
3 z8 P" q; U  y  i( ~7 exlwt 对Excel做写入操作' o1 n; R( \( ]! `: o
2.爬取b站热门视频的信息:  J2 s" I  n& A. m* A1 \3 z
  打开b站热门视频页面:
4 A, k: {2 X- v  X" s: x% X 2.png
4 |! ^% q7 j" ^2 U  S0 K3 T  按f12进入开发者选项,然后点击选中你要获取的页面信息,即可找到该信息在该HTML文件中的什么位置(这对我们用xpath获取元素属性和元素值很重要),例如:% M9 a& c' [* q  ~& N& Q+ F
3.png & d. L$ l0 s" F/ n7 Y8 L
代码如下:
; D5 {# O/ C% K. @& z* p, s# 爬取b站热门视频信息
% O4 n% c: C0 B! w6 r# pdef spider(video_list):
' f  a* K' C. s/ S    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'
9 f( Y: e' Q" i1 a    html_data = requests.get(url).text
6 R( A, l9 @) R* O: x. |/ L    selector = html.fromstring(html_data)  [$ ~/ L6 w2 o6 Y9 e/ k4 b" W
    infolist = selector.xpath('//li[@class="rank-item"]')) n/ P) V9 N. R4 v+ @2 m/ H7 J
    for item in infolist:- E( ]' v$ K* U2 K( B5 N& C
        rank = "".join(item.xpath('./div[@class="num"]/text()'))
! ^$ b# _7 K7 P" g        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
; l+ T9 T* Q( o' b/ N' k9 r, P4 X, u        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()'))  Y1 J! {6 Y- a
        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")
. b3 \8 L* t4 p2 B1 T0 Q3 n2 _        play = playinfo[0] + "万"1 o. c, _+ ]/ b! _' `9 p
        comment = playinfo[1]0 q/ t. i% C' i8 U5 s9 ^
        if comment.isdigit() == False:) L4 n4 H; v' e3 W
            comment += "万": ]9 G' E% ^/ v
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))
; N5 N  }8 [: C/ y, C        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))7 R5 K8 T$ z6 Q* Z
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))
6 P5 i2 b1 q  M        video_list.append({" P: E$ y; O% O
            'rank': rank,1 G8 b* I  G+ t' s- M, Z+ H
            'videolink': videolink,$ m4 q3 \% ^9 x+ A% I2 m
            'title': title,* m8 _6 V  U9 S# q
            'play': play,
+ N: U1 U' e5 ^, x1 n7 P( n            'comment': comment,
. P2 E# x# S5 S9 T            'upname': upname,$ j1 ^( v! n" s; c& p
            'uplink': uplink,7 B8 x3 U& s4 p
             'hot': hot
8 Z; q3 J0 Z4 a3 h% g6 @& b& H: [: K        })
. s! Y  Q- r) x$ Z    return video_list
0 u" W# {: l5 Y9 L% Z6 _  f2 |1 d' [& Y( I0 x4 a. x2 V
! y/ V% ^# o  B5 `( D( l. [8 P
3.将我们拿到的信息集合(video_list)写入到Excel表格中:$ P; ?+ O5 }% A$ Y5 H
  xlwt的基本使用方法:/ D8 O  w- d- u+ i4 |3 @1 n
import xlwt
0 p; }9 x% I+ q6 z" D3 t# 创建一个workbook (并设置编码)
# O' s  [' P7 H5 w# S1 wworkbook = xlwt.Workbook(encoding = 'utf-8')
$ t- b( [! q. {' `# 创建一个worksheet
- T  K/ R+ [3 d6 P' qworksheet = workbook.add_sheet('My Worksheet')
% B: P+ m$ f6 M6 S' ^& b9 F0 j8 y1 A0 Z: N
# 写入excel
# z0 D* \6 O: R8 s" \! U# 参数对应 行, 列, 值,(格式)
; V  X) ^! |, C% Jworksheet.write(1,0, label = 'this is test')  Z0 I  [- _/ s: R$ z& j; j; y$ P
# 保存/ t0 u; u0 L! m; K3 h3 ~( r
#参数为你保存该Excel文件的路径5 n8 G7 }, }/ |! G7 Y
workbook.save('Excel_test.xls')1 v8 g% q0 _) `% Q5 _* Y" u
6 a& A* L8 I" s+ s
. T4 a% m7 Z% G$ H4 D2 B& o
  如果我们想要点击视频名或者up的名字可以跳转,那么我们就要使用Excel表格的HYPERLINK方法:
5 {. \. h9 G/ A- ^+ _$ GHYPERLINK(“http://www.baidu.com” ; “百度”)
! p; m- I$ ~4 s. q百度为显示在单元格的信息,而前面的链接为跳转链接。
/ l* T& G3 l  |( T- Wxlwt.Formula()方法需要传入一个字符串s,s=‘HYPERLINK(“http://www.baidu.com” ; “百度”)’。* K* ^6 v9 G+ `* H
代码如下:
/ j- v5 p( _1 |1 Z  w  V# 将爬取到的数据写入Excel表格$ B& H: e7 v" W1 ]( F, t; d
def write_Excel(video_list):
$ Y5 |8 h) g0 Q' ^    print("将b站热门视频信息导入到Excel表格:")
& \) B$ D) |4 b7 a# p' @" j9 F* u    workbook = xlwt.Workbook()  # 定义workbook
" E9 s& \& D6 _! g5 a    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet3 x, |0 K6 i5 u1 l* Z; x- l
    xstyle = xlwt.XFStyle()  # 实例化表格样式对象+ A$ P/ }1 e4 b5 J) j( c8 N
    xstyle.alignment.horz = 0x02  # 字体居中6 O! K, n" ^* p  O& }8 ]% F
    xstyle.alignment.vert = 0x01  # 字体居中( K& s& @: K' `( y% q
    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头) ~0 R& W8 D/ F; ?  l- z
    for h in range(len(head)):2 |0 _1 ]6 z8 p
        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去
$ |6 n7 g" T0 M9 `4 B% g    i = 1
9 X$ N. ?  Q3 P9 T9 M" |  `3 q8 i4 }    for item in video_list:
: ~, I# D. y- r4 z" k$ P9 J4 |        # 向单元格(视频名)添加(该视频的)超链接
  k' I" S3 s/ p& o- ]' w        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接* |7 q3 w$ x% x" a. Y2 n
        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽
0 V( ~1 T5 [9 F* f5 ^        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)2 S7 w6 i1 }! O" ^
        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接
# i6 O0 ^6 G) z7 S        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)8 O1 ?' Q2 @# j; v# P9 Y* b  E
        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)- h* Q5 f0 M# E7 Q. _( D
        sheet.write(i, 2, item['rank'], xstyle)
; v; S3 c$ t3 t4 l2 M  C4 S        sheet.write(i, 3, item['hot'], xstyle)0 z8 ^/ P4 k$ g
        sheet.write(i, 4, item['play'], xstyle)
. G( m/ j# y/ U7 H# D7 T9 e4 g        sheet.write(i, 5, item['comment'], xstyle)+ f0 J" t6 \: P( p1 ]2 B  g# F& O8 a4 a
        i += 1* E9 [; N1 T* ?  [) r( ]; P- I
    # 如果文件存在,则将其删除0 R; v  c$ l0 @+ z+ M2 n
    if os.path.exists('D:/Test/b站热门视频信息.xls'):4 i+ }) U7 {* w9 h$ Y" [
        os.remove('D:/Test/b站热门视频信息.xls')
  r0 l/ K! j) j$ ]: {    workbook.save('D:/Test/b站热门视频信息.xls')3 H& f  g. P& ?+ i
    print('写入excel成功')
/ A# i- e4 F0 |, g- u, F  a! l7 o' f    print("文件位置:D:/Test/b站热门视频信息.xls")
+ ~1 B% R" Z- a+ c: W
" W1 U7 C8 C, ?( E! [$ J- ]" p) \
3 Y3 @. W" H( l( ^! C  B4.在入口main中调用上面两个函数
, k! c) L5 L. T7 [  e+ i% `- g完整代码如下:( M- M4 g5 A2 S5 N/ G
import requests
# |# c. b, C( `from lxml import html
5 s" C$ Z% u) o8 U" p  z7 |3 T) Nimport xlwt
( Q6 x( m& G5 F0 D0 Bimport os
5 J  c8 s5 F: b# s7 z+ u
) |. Q; ^3 ]; X- Z0 I/ G/ H# 爬取b站热门视频信息! |/ D; b- n. D
def spider(video_list):; i/ j% @9 K" b) l
    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'
6 Q$ t' ?' D9 T" w    html_data = requests.get(url).text1 h* Z3 _6 ?6 E  x
    selector = html.fromstring(html_data)8 E. O( g$ p2 s3 c/ ~  Y0 ~
    infolist = selector.xpath('//li[@class="rank-item"]')
9 k/ u8 T( X1 X    for item in infolist:
+ N: P, L! S; _( b6 |        rank = "".join(item.xpath('./div[@class="num"]/text()'))
* V' p# r: o) u$ X" \" Q        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
+ K! N- |8 e7 x3 A- o  ]  Z3 ?; T3 [' ]        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()')), [! j" g: K" t& [; N
        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")
! M0 W3 P4 K* r8 D  b4 s1 }: V        play = playinfo[0] + "万"* G$ Z5 ]+ F+ @
        comment = playinfo[1]
( R0 `% U) Q4 n/ y$ K4 _        if comment.isdigit() == False:
/ M8 _1 @0 W/ J3 t4 f. c7 q$ o            comment += "万"7 ~, n5 C: F( \% f
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))7 a; F" W" a& H! F( w  z* J2 \( {# K
        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))7 Q! q" @8 b0 z" Q2 O
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))8 N! U' _# A6 a4 b7 R. `1 L
        video_list.append({7 T6 n4 S( E& z( L
            'rank': rank,- ^4 [& n- w" I% P! }# O$ B( X
            'videolink': videolink,
9 K% i2 e8 v$ k) v            'title': title,
9 Q6 A7 v0 r, ^! v9 a6 P            'play': play,5 L4 E5 |; w" q/ i
            'comment': comment,; @  h1 ^; B0 Z8 E  g# ?- H
            'upname': upname,. v* t) `; d6 o2 V
            'uplink': uplink,! t: I$ W- E; n6 T7 l' K3 `$ `/ V
             'hot': hot9 H9 d8 M* x$ ]8 ^3 c0 W5 V
        })9 i$ i0 e9 z& h& G/ X- v
    return video_list
( J& ^+ U& e0 S  Q# U7 e$ C' e1 z" b2 I' {3 V& K: e6 I0 ?3 Y
# 将爬取到的数据写入Excel表格3 `) R: b9 d1 B' A, P
def write_Excel(video_list):
, @: k) h) H8 L* U1 C# @( k8 k+ |0 s    print("将b站热门视频信息导入到Excel表格:")- {2 I; [* h4 T- q8 \8 N' \
    workbook = xlwt.Workbook()  # 定义workbook
! ]5 P& r8 P+ u& \6 W. R    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet. {# j5 M6 }  c+ W! s# D0 K
    xstyle = xlwt.XFStyle()  # 实例化表格样式对象
9 B/ M% U3 A! G2 ^    xstyle.alignment.horz = 0x02  # 字体居中
! I, d' n9 ]  z  F9 ]6 j: s    xstyle.alignment.vert = 0x01  # 字体居中
2 r) Z* u( S( b8 J+ l7 @0 T    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头. J$ a; L9 X( U0 J* b* r; q
    for h in range(len(head)):
( q# z+ Z1 a* z. Q: n2 \6 J( I        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去: N% O! G6 F! a2 u1 i
    i = 1
; z2 ~1 U6 A6 F# I9 y' U* B    for item in video_list:
8 w& ^/ G/ f: t3 g1 _0 ?' g. v        # 向单元格(视频名)添加(该视频的)超链接: Q6 m+ H' @) ]) h0 \% ?% R4 u7 P
        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接
9 k4 `5 Q' Z6 U: P& h        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽
) ]# T* c* [2 s3 Q        sheet.write(i, 0, xlwt.Formula(title_data), xstyle): s: [! G9 J& `
        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接4 B; K' u  u$ X% o
        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)
4 ]0 z1 X9 c) |+ ?4 N4 @/ i8 J        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)
  w! M  G% Y; L8 {! e        sheet.write(i, 2, item['rank'], xstyle)
7 X. T5 P* p, L        sheet.write(i, 3, item['hot'], xstyle)9 S6 O& p" H- i: J2 Z: x0 f
        sheet.write(i, 4, item['play'], xstyle)
- _, ]+ j5 D/ S( q2 T4 M        sheet.write(i, 5, item['comment'], xstyle)
* B" f5 d( ~& Y( }) h7 p2 {        i += 1
% z  B" f' t( V1 }    # 如果文件存在,则将其删除! o. T/ C- h6 G: |( C
    if os.path.exists('D:/Test/b站热门视频信息.xls'):
+ l) g1 ^; g4 R. G/ Q6 t1 W( n6 I        os.remove('D:/Test/b站热门视频信息.xls')
& G4 d! R( f2 w! k# |, C. z    workbook.save('D:/Test/b站热门视频信息.xls')3 d1 a" \$ y8 @
    print('写入excel成功')
5 y; f# P* M" M0 i    print("文件位置:D:/Test/b站热门视频信息.xls")$ ~) \; y2 Z! V8 b/ A& X
4 `% u& c/ B$ F5 h
if __name__ == '__main__':8 O$ {, e8 f1 j) |( V: r" u4 T
    video_list = []4 Z0 K% K2 R! n1 o
    write_Excel(spider(video_list))+ d5 ]* ]& @4 J" G% w

0 t. K& \4 y& F* y/ f$ S. W+ R8 ^
1 O! X) {' k0 o( x: W0 {7 u% e' H( B7 E6 e5 L7 E% z% d# o

+ |* o2 {2 h" Y& M7 |" Z( \. t
& l7 S! m1 Z" c




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5