数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-3-30 11:09
标题: Python 爬取b站热门视频信息并导入Excel表格
Python 爬取b站热门视频信息并导入Excel表格
9 T7 E- K* U4 n' J# O效果图:7 X  |5 S  C5 N$ k+ S3 G
1.png
5 C6 t; O3 c3 x. h, p1.工先利其事必先利器,首先我们得下载相应的库:
. Z0 k$ R: d- v4 Mpip install requests% [, ?  R) {. E& q( `
pip install lxml: U1 e! |! S' s5 M) o
pip install xlwt" Q% M; R! ]! u& b9 [/ B
+ X( @  a0 ^# S0 C* T; t

7 Z. S7 X6 b2 F& a  lrequests 向网页发送请求0 a% U  D% c6 D7 {# a8 M3 {% C5 x) n
lxml 处理xml文件(xpath)
9 q3 Y, K3 [6 [0 o1 u: Sxlwt 对Excel做写入操作
4 f' d4 T! l- `7 j8 _" ^9 s2.爬取b站热门视频的信息:3 l- p6 T9 p) `
  打开b站热门视频页面:
$ [8 j# B! G% d: x7 c% w  ` 2.png * Z+ m8 A( N; P$ y" m( |3 v8 P6 |
  按f12进入开发者选项,然后点击选中你要获取的页面信息,即可找到该信息在该HTML文件中的什么位置(这对我们用xpath获取元素属性和元素值很重要),例如:6 @# U) @5 P3 ^3 i. u! A' {: [
3.png & O* d& B. \# e, |
代码如下:; G. ]1 w9 u! j! ]0 e+ j1 b
# 爬取b站热门视频信息  @) X' \& E3 y7 }5 ^5 ~
def spider(video_list):
$ y) w; d+ q3 x2 [5 L: `. `    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'7 G6 m8 ]5 A0 {! H! u9 X; z
    html_data = requests.get(url).text
: I6 M& J( k7 l6 L    selector = html.fromstring(html_data)2 M. \0 {! ?! c  A0 W% p! j9 L
    infolist = selector.xpath('//li[@class="rank-item"]')- Y, l  @; x( n5 {# Y: V+ b( t
    for item in infolist:) V) ~/ X* P% b
        rank = "".join(item.xpath('./div[@class="num"]/text()'))
5 Q0 R% p/ k9 I4 I; v" k7 d        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
; r7 ^0 `. P2 r: D- f        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()'))
3 n* M. n5 `+ X# }        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")
1 `  ~% u8 L2 Q/ \- R5 D        play = playinfo[0] + "万"
/ `# F% O2 {- Y        comment = playinfo[1]
1 c) J6 z  f' w8 b3 w1 E5 h        if comment.isdigit() == False:
/ S+ J3 U7 s2 V, w  ?' i6 Y# ^3 C3 O            comment += "万"
+ b; B# o4 u6 R; e* F        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))+ ?- L2 }! @) o
        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))& }: q& K6 g, O8 A* s# o
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))
% R' K( U* D8 L4 G        video_list.append({$ Q; n. I# w/ r
            'rank': rank,
$ ?# t8 N" b4 ~3 V% g$ P            'videolink': videolink,
; }9 w9 y( l3 u! R" h: d# _, i            'title': title,
! A' l7 N0 r2 R  s4 l7 M            'play': play,
7 [% e, w/ \( E' s            'comment': comment,
0 Z9 w5 d* w# x, m            'upname': upname,4 X" F  ~5 M& m4 D- W
            'uplink': uplink,
: ?& P, E  {( Y9 U$ f6 _             'hot': hot9 F0 X0 w3 R% W4 N
        })& H& X6 C7 ^+ X* O; ^
    return video_list
1 O: _, c6 k) B0 G, I! N. Y6 l; ?

! t9 z+ v( Y) K: d+ v6 b3.将我们拿到的信息集合(video_list)写入到Excel表格中:7 V# |3 V4 u9 c
  xlwt的基本使用方法:# L& x; {3 h  s( C2 H( ^
import xlwt
9 x1 g  n9 Z7 g7 h0 e# 创建一个workbook (并设置编码)
  x, {* O% a$ cworkbook = xlwt.Workbook(encoding = 'utf-8')
/ M6 o( ^; Y0 f5 X) g# 创建一个worksheet/ S( ?: H  _& X- B9 S1 g
worksheet = workbook.add_sheet('My Worksheet')
- v; F8 b# ?- I! W2 z
  G0 v1 H* u! {+ ?% f2 k# 写入excel
2 [0 C; g% X" b# 参数对应 行, 列, 值,(格式)$ D8 k& J  h2 ?# s) }' ~- J
worksheet.write(1,0, label = 'this is test'): K  w! y4 v+ Q, Y
# 保存
! R0 N- L* S7 `& W+ ^4 `: K#参数为你保存该Excel文件的路径( O5 h* J+ W6 E9 T& C( B
workbook.save('Excel_test.xls'), L8 b0 K, v! \

' T, W, M. `* L% q7 a! s, E* l  L/ @4 |
  如果我们想要点击视频名或者up的名字可以跳转,那么我们就要使用Excel表格的HYPERLINK方法:
& I* R, j. R5 l5 ]$ J% ZHYPERLINK(“http://www.baidu.com” ; “百度”)/ n* T) E' ?) k9 R" E' [. s: P9 B
百度为显示在单元格的信息,而前面的链接为跳转链接。5 x0 @5 m, o' h1 h4 c
xlwt.Formula()方法需要传入一个字符串s,s=‘HYPERLINK(“http://www.baidu.com” ; “百度”)’。) T3 M4 B- h5 y2 l) V  J1 L4 K
代码如下:
# a- t' r& I7 ~9 w# 将爬取到的数据写入Excel表格: A, u3 {" k% `
def write_Excel(video_list):
: @, }* a, R( s" U% L2 u    print("将b站热门视频信息导入到Excel表格:")8 g4 A& T' D5 f& m
    workbook = xlwt.Workbook()  # 定义workbook0 H- P! ]1 C3 x  ]* w; w6 q" a7 G
    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet
3 K" q- H  d" Q    xstyle = xlwt.XFStyle()  # 实例化表格样式对象- V6 a3 `  X) k9 J
    xstyle.alignment.horz = 0x02  # 字体居中
( T( t  s0 T' H& C2 T- H    xstyle.alignment.vert = 0x01  # 字体居中
% j) ?/ t' ]0 R. c8 H9 h    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头( T& ]2 W. b  `" F8 }7 |5 R
    for h in range(len(head)):
3 R- _9 O2 D- [0 [        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去
. R8 V# g2 n) l+ Y/ X    i = 1
6 j, Q6 @3 C, C) e" ?$ G    for item in video_list:4 A, y- a% S# q, R, p3 c
        # 向单元格(视频名)添加(该视频的)超链接. n; X5 g. L( X" y; c
        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接% B: c% ~! M1 `- [3 r' C. {: q3 N# k1 l. p
        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽4 [, [, n' x' g5 i4 p
        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)
5 Y( r; H8 L6 A# e- z, n# [( W/ U: k) v1 U) a        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接+ M6 x4 @& A7 K) H2 n+ v
        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)
" R" Z5 ]3 O8 w5 N; C1 }        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)
1 G/ o5 D8 s- p        sheet.write(i, 2, item['rank'], xstyle)/ C" X: R1 a% A" R9 w
        sheet.write(i, 3, item['hot'], xstyle)
: p$ O9 }6 b6 s# R        sheet.write(i, 4, item['play'], xstyle), q2 F6 n( l5 ~4 G( L
        sheet.write(i, 5, item['comment'], xstyle)
' t6 ?- |9 N0 ?$ d; p        i += 1
# Y( F4 G; S% [$ I2 \. [    # 如果文件存在,则将其删除
5 j* \9 {0 [* q8 j' N4 s/ \0 g    if os.path.exists('D:/Test/b站热门视频信息.xls'):
4 D/ T- X$ e1 M6 D. n# c! h" [        os.remove('D:/Test/b站热门视频信息.xls')0 D3 K& j& V9 K( N$ s5 i0 ~
    workbook.save('D:/Test/b站热门视频信息.xls')& G0 U6 @% V& O2 |! C8 B4 S1 a
    print('写入excel成功'): P& v( l1 V) z$ z+ ]% H
    print("文件位置:D:/Test/b站热门视频信息.xls")
& E; C4 N8 J2 ?6 J6 \2 M0 ]/ l6 `
+ L. g) k# J4 b5 ~4 m) P
4.在入口main中调用上面两个函数
) t, n+ m  R5 m7 J: A! B/ M完整代码如下:
- b  i2 D5 B$ K- F- _9 l8 ximport requests
, ?8 U  J% R% V* i6 k# l0 vfrom lxml import html3 m' t5 c& }" `1 z( i* K5 |, r$ i
import xlwt, d8 S6 a* x! k( B3 n8 L. m
import os
+ c0 P$ a* e; }$ F5 D9 _$ i& z1 Y+ N6 t2 _* ~) T
# 爬取b站热门视频信息8 i4 ^- L3 ^* p9 K$ m7 c
def spider(video_list):
1 a  y! G2 E& _    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'# H- Z; L* w9 K6 y1 o3 h6 v
    html_data = requests.get(url).text
8 Q+ a: B; o7 D9 a, t6 a    selector = html.fromstring(html_data)1 R, b: t$ n0 R% T2 ], a) b8 g
    infolist = selector.xpath('//li[@class="rank-item"]'); c) `+ P! W; {/ N
    for item in infolist:
* k' y, k) C1 m/ S        rank = "".join(item.xpath('./div[@class="num"]/text()'))
" w# ?; k& o2 `' \        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
+ ]" w$ _9 w8 C& [        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()')). Y7 g* {5 V# R9 T7 o
        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")  K+ y! g0 m: Z; X
        play = playinfo[0] + "万"
$ N  @6 ^- X, N# h. }9 {" _        comment = playinfo[1]
1 p! H  f& T8 A$ x& h  m        if comment.isdigit() == False:
5 N. q+ _( L; b) z& X6 {9 b- b" L            comment += "万"- |. ^5 j9 g; x0 b8 r
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))- F( e" e8 B  g' i3 N- m5 m
        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))& g3 m4 r8 j' A0 j6 B4 U, x
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))
; z* w0 K8 l6 ~5 M+ O& [3 W4 m0 `        video_list.append({/ k& {0 L: {- B. a, ^: j  @
            'rank': rank,
6 s3 {9 Z" v$ e% o# E, n# \            'videolink': videolink,
' W0 A5 Y6 j% W/ k5 d( C            'title': title,
3 R/ \2 [2 z$ H# t% i            'play': play,
7 _, n$ O( }/ B! U6 n) _$ m3 r- S! N            'comment': comment,5 G. N8 L6 [: Y: p
            'upname': upname,0 y, l. p; Q5 s, U' C( w9 `
            'uplink': uplink,
( U; ^1 p( @8 J) B3 _! m             'hot': hot
* n$ Q! {5 D1 |7 f% B        })$ @1 c7 \: c$ P7 f+ D
    return video_list
8 G+ \% y4 M: T8 d" ]% @: n
. w7 k, l$ C: ?# j# 将爬取到的数据写入Excel表格6 u0 ~4 D' [1 R1 w" ^; }! E7 P
def write_Excel(video_list):  f) V0 G" S2 k5 O1 }4 w
    print("将b站热门视频信息导入到Excel表格:")4 z2 i4 b' \* s/ K" g
    workbook = xlwt.Workbook()  # 定义workbook* Q. h8 R3 l/ ?8 B7 q
    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet
1 U# Z1 `! T7 _1 x5 P* e    xstyle = xlwt.XFStyle()  # 实例化表格样式对象
0 F5 P7 m3 E: S# l% b1 t& f    xstyle.alignment.horz = 0x02  # 字体居中
6 Y; g8 i5 s- A3 p6 L    xstyle.alignment.vert = 0x01  # 字体居中
3 q) X* J4 F* K. N    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头
: J9 v3 S0 D. q) J  V    for h in range(len(head)):8 u0 k% }( ], [, s8 `) J7 G" p5 ?5 U5 b6 X* x
        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去5 [+ Y4 D! k  g
    i = 1
! W- [$ ^" @) y' v( c    for item in video_list:
8 x$ d. M% W1 e! F4 n# g# B        # 向单元格(视频名)添加(该视频的)超链接& ?9 L7 a, _  {% t  }4 c) [2 \* S  z
        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接+ J" b7 J% H4 D
        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽
! W/ _- e/ i* V6 ?1 _        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)
. L1 Y2 G: j( V4 e9 ?        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接* t5 I6 z! E2 C2 E' G
        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)
' b7 ~! u" X- [7 N6 k5 [        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)
/ b5 \1 C! g% N        sheet.write(i, 2, item['rank'], xstyle)
: H9 g( W& b- `+ q+ R$ G* f        sheet.write(i, 3, item['hot'], xstyle)9 ?' w& k6 B+ @! S$ w; U$ T8 u
        sheet.write(i, 4, item['play'], xstyle)
& D* m6 I1 L' i3 @        sheet.write(i, 5, item['comment'], xstyle)
5 ~6 p% N( z8 N6 C0 O% `9 I, F  a        i += 1
2 M9 E/ W' t1 O. H) u    # 如果文件存在,则将其删除
! {0 q+ S& `  S$ ~7 \( H3 P* e    if os.path.exists('D:/Test/b站热门视频信息.xls'):
2 a* E8 Q0 I! T; s2 f        os.remove('D:/Test/b站热门视频信息.xls')% ~$ m; v! r- q0 v3 t+ I) }  G* E
    workbook.save('D:/Test/b站热门视频信息.xls')
1 a: \9 h# U: j    print('写入excel成功')' a. i5 \5 o* f# [% y
    print("文件位置:D:/Test/b站热门视频信息.xls")
# k- r- N8 x. f* k1 M/ w
, b/ ?( j2 ^6 U; Iif __name__ == '__main__':( ^9 H' n! c3 k& ]
    video_list = []
% t/ Y7 j' s7 L$ x' e    write_Excel(spider(video_list))
/ x" q! [& }/ Q! h: y3 ~3 P5 T$ ^7 X7 f. B
% w7 L# j7 {6 D8 w" W5 k, a0 k; C$ ^

1 W* e) @- b4 u) w# Z! a. R2 L( [2 u3 i+ W

: S  U$ N7 I8 S+ H" z2 Y# b




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