数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-3-30 11:09
标题: Python 爬取b站热门视频信息并导入Excel表格
Python 爬取b站热门视频信息并导入Excel表格( @( S* n* \6 m: ^( U4 h! \
效果图:
1 u: C2 \5 ]7 P& J3 e( ^ 1.png
( b3 }$ _4 P9 H; ]  [" U1.工先利其事必先利器,首先我们得下载相应的库:
0 R# X( B% O: h4 e3 H' Lpip install requests
, A7 p1 E/ @! w5 f% g' @pip install lxml
6 F* {" X3 J0 Q% m3 }pip install xlwt' {% g( a) l/ s' j! [* G
" w# N6 y# h! x
) D: _  U( s  y; [" L9 k
requests 向网页发送请求7 x2 ]- H7 d6 \3 j3 T6 C. |
lxml 处理xml文件(xpath)9 b5 J$ c! _/ g% m+ }/ [: e
xlwt 对Excel做写入操作& j7 s& A: K+ J2 A3 O, B
2.爬取b站热门视频的信息:
0 @0 ^) e( O! L1 a" v' r; @  打开b站热门视频页面:8 }: |4 v- o. Z$ v# [  b
2.png
4 y2 m: V4 m+ c8 Y& ~% @2 _  按f12进入开发者选项,然后点击选中你要获取的页面信息,即可找到该信息在该HTML文件中的什么位置(这对我们用xpath获取元素属性和元素值很重要),例如:' h: {8 \# k6 X$ v8 W0 f
3.png
$ T! ?3 [' a; G1 v代码如下:6 l* A2 f* |0 V0 ]
# 爬取b站热门视频信息
2 `: [4 F( q' D3 l+ \1 A# S, mdef spider(video_list):7 a, r1 ]: l' A
    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'  l6 M) m% Q4 g6 \& H8 R) s+ K
    html_data = requests.get(url).text
1 b8 {: N1 ~9 B9 c6 ~- [+ p# W. J    selector = html.fromstring(html_data)1 M) [. E( V/ z, }! b. l
    infolist = selector.xpath('//li[@class="rank-item"]')
$ @/ F9 Y: g7 x4 n) d    for item in infolist:6 @2 O6 g" q; X# a5 A1 p1 h" Y, L
        rank = "".join(item.xpath('./div[@class="num"]/text()'))
: f* }2 g% q0 m0 i9 o        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href')), x" P: z; t- ?- U6 Z3 ]/ }
        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()'))8 o5 g% v- u6 @
        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")' y$ Q! `0 o" M8 F5 b" ~
        play = playinfo[0] + "万"
7 d3 r+ C4 @) [5 m7 {! _7 f        comment = playinfo[1]; j$ }' A2 [9 z* w; p1 Y. d' D
        if comment.isdigit() == False:: E; }* K: |4 a% c/ ?  T3 C
            comment += "万"1 s$ j' \5 U$ |. p2 N1 w: o5 _
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))6 m/ ^5 c' y8 Z( Y
        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))
5 N4 _5 \) ?) K6 u& d        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))
7 H2 i* ]2 C3 G/ [+ a        video_list.append({
$ \) h# u$ I1 k/ v/ R+ i            'rank': rank,
5 e0 N8 w  U7 H4 R' [+ r  t            'videolink': videolink,5 U2 M% S$ B6 Y) L
            'title': title,- e  t4 @& _8 I8 {& b3 m* N! D4 _2 L4 l
            'play': play,
# n) n$ A/ H- r! `/ X' F' M            'comment': comment,* o8 A4 W) Y3 k8 E  ^6 s; ?! |% B
            'upname': upname,
& w3 j* _9 x% w            'uplink': uplink,
3 W: N! C3 e2 a             'hot': hot
3 k0 K) `! E! m, \: e        })- K) L: v; g) W8 I* ^% K) ^' j5 Q4 y
    return video_list- b' J  h0 e0 V' v
/ ?; N7 U" S# \3 D
7 ]9 P: ~$ r( B* O" k
3.将我们拿到的信息集合(video_list)写入到Excel表格中:) p" W) P* a& u9 c
  xlwt的基本使用方法:/ @& R; X" w7 G6 N, B; q
import xlwt" D. k& C+ c6 q9 v6 h, F* J
# 创建一个workbook (并设置编码)
$ `9 P  P. s* E7 [. Eworkbook = xlwt.Workbook(encoding = 'utf-8')
8 R5 y. [; z7 Q9 C# _: \# 创建一个worksheet: B4 b/ H4 h. Y+ R
worksheet = workbook.add_sheet('My Worksheet')
4 f; e. u) Q% K( Z6 j, ^. d8 b
/ Z3 n! H0 A+ w0 U' |3 m# 写入excel
$ {3 \: e& N$ k- v# Y! d# 参数对应 行, 列, 值,(格式): m; g# N$ o5 Y) q; _
worksheet.write(1,0, label = 'this is test')
! M' a/ D$ {; ?2 P5 {$ f" q# 保存
# u( @$ r8 k! u/ ~# l#参数为你保存该Excel文件的路径3 m/ L2 `3 X+ e3 [5 _; ?
workbook.save('Excel_test.xls')
2 s1 R2 s, u+ F# H( a7 a8 }) B; u+ F3 Z$ Y/ }

& z+ \4 E* g# h/ h% ~  如果我们想要点击视频名或者up的名字可以跳转,那么我们就要使用Excel表格的HYPERLINK方法:/ c; ^; O: Y* m5 t$ k- R
HYPERLINK(“http://www.baidu.com” ; “百度”)1 l) t: V! h. X4 z6 D# J9 L! C
百度为显示在单元格的信息,而前面的链接为跳转链接。
4 [" ]* G. q5 _- S3 {xlwt.Formula()方法需要传入一个字符串s,s=‘HYPERLINK(“http://www.baidu.com” ; “百度”)’。
( y4 ^8 v$ A$ s% O6 ]7 R" l代码如下:' @/ r" u( E4 [
# 将爬取到的数据写入Excel表格
* o: W. R6 [: w" f$ I4 ddef write_Excel(video_list):
5 `. L- E* W4 K+ X9 T- V8 ~    print("将b站热门视频信息导入到Excel表格:")
' b' X+ `/ T7 o: o3 y5 V5 N+ _7 n. X    workbook = xlwt.Workbook()  # 定义workbook& {7 `$ z" N3 R9 a+ J$ W
    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet
7 I$ W- G- V4 S3 v% `: c    xstyle = xlwt.XFStyle()  # 实例化表格样式对象  y& v9 @9 ^" M; c: V7 g& Q) x
    xstyle.alignment.horz = 0x02  # 字体居中( F3 |9 X9 b- f4 F
    xstyle.alignment.vert = 0x01  # 字体居中7 P3 y" N& n( a6 c5 m" |
    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头' v8 C) o3 l4 t$ n
    for h in range(len(head)):
2 e5 r) N3 M6 v# }3 S- d        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去
+ e; R9 t. b. @    i = 1
) b3 E. N* w! R    for item in video_list:0 k4 u* c6 Y$ q. J( X
        # 向单元格(视频名)添加(该视频的)超链接
6 V! O+ T6 E6 C& m7 J2 i        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接
' U3 f) Z4 ^' X$ {# I7 ?        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽
0 G1 i2 @. B5 B; F. @$ ^        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)
. Z: E" g2 Y  S, ?+ U; E  u        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接1 l3 G# b9 H+ e8 H  b- g
        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)
! S+ O+ h& Z! g: n0 z2 A        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)7 E% G2 `* Y. a6 D3 s0 ^
        sheet.write(i, 2, item['rank'], xstyle)
7 S; V) b0 n0 W- d        sheet.write(i, 3, item['hot'], xstyle)
. J9 u# r( R. z1 k' Q        sheet.write(i, 4, item['play'], xstyle)
2 I- c4 b5 ], X: Q& f        sheet.write(i, 5, item['comment'], xstyle)* I  e$ O( r3 }* Z+ ^, i' O
        i += 1% c& F. k: x- l
    # 如果文件存在,则将其删除1 w: q1 B- z$ D4 ?  ]6 T& ~+ c
    if os.path.exists('D:/Test/b站热门视频信息.xls'):) T- U  @9 D* l3 d6 D6 R
        os.remove('D:/Test/b站热门视频信息.xls')
7 J3 ], ~. \  Y+ s' x+ P2 c4 M    workbook.save('D:/Test/b站热门视频信息.xls')- e' p/ Y5 l% c
    print('写入excel成功')2 |7 C: x$ P% s! _
    print("文件位置:D:/Test/b站热门视频信息.xls")
" E  B& h( L8 K- J# z( k
. ^5 t* P2 ?% M& c$ V
; W6 p0 a2 a6 Q# [; H* S4.在入口main中调用上面两个函数
1 m2 g+ B9 V2 |* T& i3 I完整代码如下:2 c6 E& A' g/ N0 u
import requests5 Q, E) C- d8 l  Q" \7 H" A
from lxml import html( r% c! r- g9 p' {$ I9 |: J
import xlwt
, ?1 L' x* @$ R5 X8 _( Kimport os( P6 ?" d- }8 o' T$ D3 d
- |" G0 T/ P& o2 w% D4 v
# 爬取b站热门视频信息7 ?8 P* I+ M+ b0 f- P
def spider(video_list):
1 O2 J. n" ?2 i  \* ~* E, P1 F    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'
  w' u* Z1 z) |0 l    html_data = requests.get(url).text
9 F7 d3 W! x4 |# i- ]6 h    selector = html.fromstring(html_data)+ `7 \5 M9 z- V: }9 y, i, O
    infolist = selector.xpath('//li[@class="rank-item"]')5 C( ?- q8 M  S5 T# n3 @
    for item in infolist:
  V8 M3 `* c( j) l$ |& _! K        rank = "".join(item.xpath('./div[@class="num"]/text()'))
) x( @0 C- Z0 P! y7 m4 K        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))# |" k$ h0 k8 I* |3 q+ X
        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()')); |, r! X% a# g! X2 w0 f' |
        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")
/ L4 E; H# j6 ]0 a6 o# s6 k        play = playinfo[0] + "万"
4 W8 N# E4 |7 z8 R" x: {: A$ i, g        comment = playinfo[1]# q; {- k* p" `& b9 Z7 R
        if comment.isdigit() == False:
; n) @$ l- A5 h5 ^& x            comment += "万"+ n: D1 U7 }/ e9 H
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))
+ T; h" M" j/ W% |% }. N% r, b        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))& o. Z" N3 p( ~# y) y1 n; T
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))1 {$ @% H& I$ I1 q( L
        video_list.append({
# [' p; O, w* w- u7 Y; g/ V            'rank': rank,% @' }. F  {* R9 M* x% i3 K9 L
            'videolink': videolink,% K: w7 g* L0 c- M& D/ R
            'title': title,7 F/ l. D- T3 l
            'play': play,9 a+ `+ A" [% o( b( V8 t9 h$ L* g
            'comment': comment,9 t" D5 ^/ T/ W0 L$ J" `3 s
            'upname': upname,
) e8 p6 N. `9 E# V            'uplink': uplink,
# D) ~) _, V2 f1 c1 b             'hot': hot
% @$ A' E' F0 z- \$ @$ R/ `        })
8 E% ~' C6 r) V! z5 j/ L    return video_list. [$ ~& q  I( R; i8 Q4 x9 s

1 k# M3 w9 J7 j# 将爬取到的数据写入Excel表格
" s* X1 T( l. n) y8 Idef write_Excel(video_list):# _% F+ V2 m+ }9 @
    print("将b站热门视频信息导入到Excel表格:")
5 s1 H+ Y/ H. d# W    workbook = xlwt.Workbook()  # 定义workbook
2 K( Y% {; V& e1 {) U    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet5 b/ D4 G2 n9 m! a! }8 r, v# \
    xstyle = xlwt.XFStyle()  # 实例化表格样式对象
# S) s. f/ w& I2 r2 g    xstyle.alignment.horz = 0x02  # 字体居中
4 f* @: i" [" [    xstyle.alignment.vert = 0x01  # 字体居中) a) Z& O1 G( @2 |; o& ^3 v
    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头, S- D) ^: O" Z4 R  b6 Y
    for h in range(len(head)):
8 ~9 J3 H3 J, y+ m/ S; }        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去
2 I( y' F1 g  |5 _# E    i = 1
2 X5 l  g1 C2 P2 W/ K! D0 Q    for item in video_list:
+ A  [0 Y+ U8 z+ u6 R, N& y        # 向单元格(视频名)添加(该视频的)超链接& v$ |  M0 C4 @$ B, F  @
        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接
1 A' Z5 I; n. r4 ]8 W. f        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽
! j3 N: J" h: g, ?; C$ ^  ]        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)- a* [7 L* B5 K
        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接0 N6 F  ?7 s" K6 R! q" [) t: W
        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)* s% u/ x8 M! R2 O, H( H
        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)
2 p% v% b" z  D! u        sheet.write(i, 2, item['rank'], xstyle)
& Y. w' ?/ f3 x4 B        sheet.write(i, 3, item['hot'], xstyle)
. c4 O8 q7 E( S0 }8 I. v( k. Y, D) {        sheet.write(i, 4, item['play'], xstyle)
# R2 n' a  f! L3 j$ n+ I        sheet.write(i, 5, item['comment'], xstyle)
& w/ q" L0 K0 n        i += 15 n* J% F. i8 |) o
    # 如果文件存在,则将其删除) T8 e* k2 s( s2 p# d' V8 P
    if os.path.exists('D:/Test/b站热门视频信息.xls'):
: p! i* P' M. G1 m: u0 O        os.remove('D:/Test/b站热门视频信息.xls')
- E& W6 P  W. Q! L5 H    workbook.save('D:/Test/b站热门视频信息.xls')
" }6 S$ D3 Y5 L* w% J9 c7 S5 ~    print('写入excel成功'); r: `( M2 x8 z/ ~, l1 P2 o
    print("文件位置:D:/Test/b站热门视频信息.xls")
2 H2 A: J* S& G# U# u; Z
" D0 V( H1 u) }( `2 x1 X0 B4 Mif __name__ == '__main__':
0 M8 ^: V6 V2 P8 L    video_list = []2 N. U9 W8 s* {* E# J0 I: a( m  E* E
    write_Excel(spider(video_list))* J& F* g' L) o4 Y, Q

( {6 S; L( i4 i+ b$ i- M" \  x* m! `+ L( J2 z# ^
( o/ Y" T% ~, S. _
) s, V- v% {3 H6 L3 |- B# q5 Y5 S
6 W* E9 B, S& G





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