数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-3-30 11:09
标题: Python 爬取b站热门视频信息并导入Excel表格
Python 爬取b站热门视频信息并导入Excel表格0 U# y# u# D3 H  A
效果图:
4 r( N# ]1 O$ c% _1 y' b 1.png
$ v% a$ C" d& L" p3 g, l1.工先利其事必先利器,首先我们得下载相应的库:
% E; \5 w8 v2 P0 s8 p1 \# K2 Mpip install requests
! @7 s5 Q2 d7 Cpip install lxml
5 G. P. R6 T1 C! K9 Xpip install xlwt
9 w! A  P( M9 d
  h" Q% j8 r; P5 F0 ?1 l) ]$ O
) K* O  `! W: u  Y# Z- Yrequests 向网页发送请求
, |, ]! @9 J* X8 ~5 N8 P1 v3 \lxml 处理xml文件(xpath)
$ w& h! p- ?# w: `' m& c! @xlwt 对Excel做写入操作- f- r( B- Q2 h1 \
2.爬取b站热门视频的信息:0 Q1 a6 t4 n4 j% Z
  打开b站热门视频页面:' _4 Q! n0 p4 b* B& k- Y
2.png 4 |; G5 z& `5 |8 m
  按f12进入开发者选项,然后点击选中你要获取的页面信息,即可找到该信息在该HTML文件中的什么位置(这对我们用xpath获取元素属性和元素值很重要),例如:/ k9 A: Z5 x3 E3 M* i
3.png
, W- u1 n2 H4 A. P* k代码如下:& Q7 p. y) b% J2 W$ a& S% W
# 爬取b站热门视频信息- H+ F% n9 l" L' C2 @. k( b$ q
def spider(video_list):
& `6 ^. }- k$ \& i    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'
& A0 J$ Z* f. s* v/ D3 L    html_data = requests.get(url).text
  o$ q( ~* Y2 V% }  ^    selector = html.fromstring(html_data): d& h: X2 E* H, c( Q
    infolist = selector.xpath('//li[@class="rank-item"]')& P6 f5 o! H8 h9 L) j; Q
    for item in infolist:
' d' p. X' T& ]        rank = "".join(item.xpath('./div[@class="num"]/text()')); a- q* N) T8 ~8 C5 A5 j% r
        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
! T8 e) h) ]9 K( U5 z/ o        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()'))2 q! S6 A6 k* \8 ?
        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")  i4 ^0 r: ]1 R# X2 c; r% E" c
        play = playinfo[0] + "万"
0 J( j: L3 E. T2 B8 w# \% k        comment = playinfo[1]/ N! r0 w8 G# O' @* o# \# i: c
        if comment.isdigit() == False:) C8 {7 D/ b* i6 b0 Q2 ^6 N
            comment += "万"9 ^, V6 g  z: H" v: c2 x
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))
  o$ a' h4 U, o9 g' d9 T        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))0 a7 h9 i' Q: ~; B4 i
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))
0 h1 M* l' w7 t! t) D7 p9 |+ l7 \        video_list.append({
; u- S0 Z* e' o& X            'rank': rank,
; q: S$ f6 X0 l. x  r            'videolink': videolink,( `4 R: V" \% ^  ]" H8 d# v1 \( E
            'title': title,2 F3 N5 f( N$ I3 ~% V
            'play': play,
) }- Z, K% r- F6 }- A7 H6 D            'comment': comment,1 g: y1 L4 N! v: m# ?, y- A
            'upname': upname,
' |  W8 c8 ]  ]1 b8 I            'uplink': uplink,
4 p6 _5 [6 v( h% F; H! q             'hot': hot
( d1 s/ u1 E! o1 K% Y9 D( I0 L        })+ m8 B* b- a! Y" k6 i
    return video_list
" i" m; ~7 U2 {0 M
( ]+ d) S! W- ~+ p% }) G8 v/ `3 K6 X
, K" q$ U9 }0 J. b7 G8 v
3.将我们拿到的信息集合(video_list)写入到Excel表格中:: Z% Z8 g; ?, E
  xlwt的基本使用方法:: C/ w/ Z% t( h! m# K3 Q
import xlwt
/ J' U% a% j9 B% @" [# `7 L# 创建一个workbook (并设置编码)
* V- B  |) N- K( S3 Z1 U/ ]workbook = xlwt.Workbook(encoding = 'utf-8')% q2 c: L) a* f% a. j6 O. f
# 创建一个worksheet* b2 x# W7 k6 B; z. P( e6 [
worksheet = workbook.add_sheet('My Worksheet'); U# S* V8 K0 y9 y3 V5 I
1 o1 k' v# d9 n6 P; A4 o6 h# b& A: p6 }) A
# 写入excel9 S- Y% f" K2 w8 a
# 参数对应 行, 列, 值,(格式)
; P* M2 }6 y4 S/ c, Aworksheet.write(1,0, label = 'this is test')
: L" c8 h/ N% C# Z$ V, [# 保存
" m# ?* t: _  g' s% s+ _& c#参数为你保存该Excel文件的路径2 u7 b. x  j# S% l" o
workbook.save('Excel_test.xls')2 H1 R7 N7 z/ i

' y" I' r: J! r- }6 v; r
3 `, X! i' X( s7 i& [  如果我们想要点击视频名或者up的名字可以跳转,那么我们就要使用Excel表格的HYPERLINK方法:4 Z, z0 [5 p; `' O
HYPERLINK(“http://www.baidu.com” ; “百度”)# \& h/ j" H2 Y; H( G
百度为显示在单元格的信息,而前面的链接为跳转链接。
9 Y2 Z2 j8 z! Nxlwt.Formula()方法需要传入一个字符串s,s=‘HYPERLINK(“http://www.baidu.com” ; “百度”)’。7 l+ g1 ^' w5 N5 b7 b1 i4 D+ e, k
代码如下:
" z6 ]9 |0 d9 t0 [: Q# 将爬取到的数据写入Excel表格
1 u% o0 D1 _. O: odef write_Excel(video_list):
  ^" m" v* @# S& c9 i    print("将b站热门视频信息导入到Excel表格:")
; C* {! F1 f: b: e0 Z    workbook = xlwt.Workbook()  # 定义workbook% f/ ]/ w; l: b3 B* _
    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet
0 b# u8 ^- a. C1 i" G9 S    xstyle = xlwt.XFStyle()  # 实例化表格样式对象
) u9 y* n. P$ c" [+ C6 F    xstyle.alignment.horz = 0x02  # 字体居中! Q( S0 R: @9 o6 M9 y. B& S7 x
    xstyle.alignment.vert = 0x01  # 字体居中
7 T6 n$ u2 M) N/ r% C    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头0 l6 S4 t( l4 e
    for h in range(len(head)):2 f) [( ~5 }. C2 ], S6 ^
        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去- @/ L% r: ^3 C  t9 I
    i = 1
* m6 X. Y$ X8 U; b1 }    for item in video_list:
+ u7 P) L) w2 b9 T        # 向单元格(视频名)添加(该视频的)超链接. x( K4 a' @# H: h
        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接) e& m" O. M8 f0 G
        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽
+ _+ h7 t: Z% s+ U        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)( y9 v2 R1 K' ~5 R. M# X2 ~* c0 [
        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接
! K$ F; c, `2 f3 `        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)
9 c6 N, K8 e8 l: w- I& ^$ Y& S1 B        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)7 L7 R& j- U$ J, P. ?4 U# s- j
        sheet.write(i, 2, item['rank'], xstyle)
5 l0 [) S  e7 L' j        sheet.write(i, 3, item['hot'], xstyle)
) ~1 w5 H" |7 C; z" k; Y8 n9 j        sheet.write(i, 4, item['play'], xstyle)" ]5 P/ z/ B! M6 H
        sheet.write(i, 5, item['comment'], xstyle)
, Y- F% l6 e2 h8 @9 L6 [3 h        i += 1
% D% Z/ @1 s* x. {+ o- Q' o; [    # 如果文件存在,则将其删除
( X) ?1 i+ a$ E* E, U* o2 G    if os.path.exists('D:/Test/b站热门视频信息.xls'):
/ F# C# g" a$ R& F- e        os.remove('D:/Test/b站热门视频信息.xls')1 ?, }: ]! l) Q) D+ z( s
    workbook.save('D:/Test/b站热门视频信息.xls')' {" T  L- p% |  ], Z  o* X6 g
    print('写入excel成功')4 N7 ~( W# v  Q0 i2 J
    print("文件位置:D:/Test/b站热门视频信息.xls")
4 k5 L0 Q# W1 q3 [* b- d0 P+ L
9 R' Y; p' S1 M& N1 i8 n
7 \; b1 d( \" G- R4 u; S1 s6 E4.在入口main中调用上面两个函数9 q8 [  H) W3 v
完整代码如下:
8 K) b4 H# t3 G" Gimport requests
3 ~2 V$ f/ w% i" S! vfrom lxml import html
( S' `& `# }0 a; |3 L3 F. V1 P4 u, w6 J. himport xlwt, x6 w; ?, r. P: B' u2 ?
import os! Z- K* E5 b/ B1 C) F1 ^  U9 G

1 Y2 n8 G1 m$ P3 @# 爬取b站热门视频信息4 z" z% h% W' K2 I  X
def spider(video_list):
% A, R. T8 R  h3 y) e$ j6 x# H    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'
. G9 q) t# ]$ z7 O    html_data = requests.get(url).text3 N- ~1 ?: h8 w
    selector = html.fromstring(html_data)" A" M5 G/ |- @2 D
    infolist = selector.xpath('//li[@class="rank-item"]')
: B$ \* F% ~" N    for item in infolist:
' `" U1 H( B. b' F$ D        rank = "".join(item.xpath('./div[@class="num"]/text()'))
4 L# C* k# I- n        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
. b& ^. t9 t+ n7 Q" D        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()'))
# |0 U+ Y/ w4 @) S' G9 J. `) j1 _. x        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")
4 Q" U8 ~+ i  _        play = playinfo[0] + "万"$ L8 O( K& j" s$ I
        comment = playinfo[1]) N" b3 n# _  i6 u
        if comment.isdigit() == False:
# D9 m8 r$ h7 _* i            comment += "万"$ \4 i; u3 H0 k0 i8 Z
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))7 b6 {* j6 u& ?" P/ S
        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href')): y9 _) m% U( ?: O/ u% X" {
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()')); ^9 r4 d; Q9 i! [$ \
        video_list.append({- ?2 `# P! Z; ?+ Q; ~5 D$ h- e
            'rank': rank,# c) w# G; y' L; w
            'videolink': videolink,
* |8 @+ T9 l3 i5 c. T+ g3 W            'title': title,
* P% {* a) b% L) Y" i7 a# h( I( `            'play': play,# J4 O( d: @1 d
            'comment': comment,
; F/ s. N1 H# _" |, t# z            'upname': upname,  d, H9 I4 y) U/ \& Z( [
            'uplink': uplink,1 H- w; {# i$ |* z3 A$ x% ~! p
             'hot': hot
. W5 R9 [( T, D# {- i) {        })
, B; K  h: e6 n' m    return video_list
8 K6 l& r8 w2 d* `: a
8 S% Z! }* s. j# 将爬取到的数据写入Excel表格
4 T1 A: y6 `1 O% Q; V7 o& U& Q& |def write_Excel(video_list):
, z4 [2 q( ~( ^- }1 h    print("将b站热门视频信息导入到Excel表格:")
! O& v$ s+ e* K$ y, ]! M    workbook = xlwt.Workbook()  # 定义workbook. S: e2 k4 _+ z: S  c# g, ~
    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet) r  F7 j$ X' J6 |8 i' f) r% [( t. p
    xstyle = xlwt.XFStyle()  # 实例化表格样式对象
% N9 F$ m& P  Y9 a- u    xstyle.alignment.horz = 0x02  # 字体居中
# O/ I6 m6 Y8 I( T: H    xstyle.alignment.vert = 0x01  # 字体居中
" Z7 @- ~: m4 B# O6 s    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头4 q* H% M; U' E/ f
    for h in range(len(head)):, a3 j' i7 m: d5 Z$ \3 I( c
        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去
) w# Q2 `3 }- Z2 u( o$ P2 X* \( Q4 c! j    i = 1
$ j% x* H6 ]& O' G! u8 u; P' D    for item in video_list:
  ]2 i$ H$ t+ I8 I4 X& U% w        # 向单元格(视频名)添加(该视频的)超链接
6 \  I8 ]. ?$ B  m        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接5 w. W$ b" h3 \
        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽* ^. E* ~# A% G% A( }
        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)) i: _" {6 A; _$ O/ L/ ?
        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接
& q% e- U0 }9 I        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)* Z% F8 p" A# c& [9 b# Q% t1 z
        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)
- v* R4 M: T, T: T# S        sheet.write(i, 2, item['rank'], xstyle)* w' G! v2 W. U1 s7 j. D
        sheet.write(i, 3, item['hot'], xstyle)
6 i/ J3 D0 s5 l+ }2 f2 R& h        sheet.write(i, 4, item['play'], xstyle)
( o3 ?4 q, B5 r0 z        sheet.write(i, 5, item['comment'], xstyle)1 `* m; a# ^2 r* B
        i += 1
8 y' O- P5 G4 v: \, ?7 h' C    # 如果文件存在,则将其删除! q, L8 F/ h$ d" \; @
    if os.path.exists('D:/Test/b站热门视频信息.xls'):! d: Y% x: Z: ]1 ~4 G0 k
        os.remove('D:/Test/b站热门视频信息.xls'): Y) |4 I9 A! E# Y3 G( [
    workbook.save('D:/Test/b站热门视频信息.xls')
8 c9 k. P% D& h5 Q" }3 j( B( s) S    print('写入excel成功')
' i+ x! \& h' e0 I; @/ X    print("文件位置:D:/Test/b站热门视频信息.xls")
1 }- u3 M# W# n% ^* v* F: X3 c, ^$ C& B; V2 |2 R
if __name__ == '__main__':
6 T( M3 I- X: M0 g    video_list = []
( ~# n) V, y4 s# N3 }    write_Excel(spider(video_list))
1 t$ F+ j# T( q& U( e! T7 E0 S2 b  q% s. e. a; c1 w

: e' L0 @- M5 F
1 q' Y; b, `0 A/ [( `' R2 P' ?" p, k! _) E
4 N& f) p" l4 p# w; }' s





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