数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-3-30 11:09
标题: Python 爬取b站热门视频信息并导入Excel表格
Python 爬取b站热门视频信息并导入Excel表格
2 `2 [' Y1 W6 }4 @# N效果图:, M% q) h- N* s
1.png 8 _% U; I0 Z' k7 {. L$ j6 D) I7 q
1.工先利其事必先利器,首先我们得下载相应的库:+ d" H: L; I/ K) _2 i
pip install requests/ j9 l, t3 |" a) U. S
pip install lxml. Q: G) g9 F! F5 t4 y4 P2 w
pip install xlwt2 k" \) k" p2 |

& O9 H- ]4 l8 |( I2 B# B& a2 y$ C. p" f+ Q
requests 向网页发送请求
2 N8 k) m0 t8 J4 \: i+ J9 C6 Rlxml 处理xml文件(xpath)
  q6 [( I1 o1 y  `# S2 q1 l; ^xlwt 对Excel做写入操作4 C4 h4 d3 ~3 G& o
2.爬取b站热门视频的信息:- r6 B( A+ a4 C/ [7 }
  打开b站热门视频页面:
8 P3 [( s9 k' _ 2.png 3 Q9 X% h6 h/ ~5 ^  N* }
  按f12进入开发者选项,然后点击选中你要获取的页面信息,即可找到该信息在该HTML文件中的什么位置(这对我们用xpath获取元素属性和元素值很重要),例如:
* K8 p) w5 T6 J! L% \ 3.png 8 X3 L; x1 N' O
代码如下:
% }, }) X- m5 u& `9 `# I# 爬取b站热门视频信息) z8 L- O0 o7 Q; T- _- W0 d
def spider(video_list):; b* r3 x" p  j; a- D9 ]
    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'* D6 a$ b; x2 a+ l  i9 F
    html_data = requests.get(url).text
8 X7 X) j3 J, q. I1 [+ }    selector = html.fromstring(html_data); G$ |8 x% M9 X; j0 `
    infolist = selector.xpath('//li[@class="rank-item"]')
; Q& @* h$ r% T# G% u    for item in infolist:
+ S9 T6 a- }) l# O3 ^        rank = "".join(item.xpath('./div[@class="num"]/text()'))
, Q" [) G+ t1 y/ e, _, B        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
/ z% `1 ~; W! n$ B        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()'))
$ S2 u7 `; a3 Q1 h7 |: v1 Y/ U        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")' n" U7 n1 \" s7 P: V) l, M7 W
        play = playinfo[0] + "万"
5 Z$ L7 C( z6 X6 ^$ L4 y# c; H1 v- T+ V        comment = playinfo[1]4 Q. ]1 {$ D- n5 d6 x+ I( s4 r. P* k
        if comment.isdigit() == False:
5 A* z: T+ }9 S: [  Y7 ~) Y9 l            comment += "万"
  J7 o# T0 j8 G8 S1 ]) B- e+ A" ^7 B        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))7 P/ ^) e& ]* n, l9 ?. z% j
        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href')): {/ |8 z4 N6 q5 |; U' x- f/ P( ?. }
        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))
/ l, d& T  s. X& k9 [; Y        video_list.append({
8 f9 w& W, a& W            'rank': rank,
! s1 r3 D0 G0 t, e3 N0 K1 x: ]2 |            'videolink': videolink,: R8 N2 H% |1 t; p+ g! L- J  T
            'title': title,
  B/ K: W0 D/ P9 j* V            'play': play,
" {0 z2 X% b3 r% J$ B8 |7 h" C            'comment': comment,
, \* M  U0 P! c/ g: ^' @1 x; w            'upname': upname,; F! _5 X; N( v" X, H6 z% N$ C
            'uplink': uplink,
9 t& j( t- _" ?+ c4 p             'hot': hot
. |: y: v" i& G: v, N        })7 X6 m5 l% C6 P9 K$ ~. V4 A% J
    return video_list# w8 u2 Q" z3 s9 l; ]& D6 h* H- x" c

8 M: v/ p, C" L! O& [

" p2 _& o: S2 C3.将我们拿到的信息集合(video_list)写入到Excel表格中:
2 I/ A' M+ |; b& S7 f# \; _  xlwt的基本使用方法:9 x, @0 S" |4 F# H) w1 A
import xlwt
/ ?+ O7 W; o+ M# 创建一个workbook (并设置编码)
/ D: j* r6 x- O% d2 `$ x- I2 W* dworkbook = xlwt.Workbook(encoding = 'utf-8')
& X+ Q( p8 m; _9 }6 n# 创建一个worksheet/ I  c) g7 ^/ R6 M) t* L
worksheet = workbook.add_sheet('My Worksheet'): a9 W' Y8 G; C; E+ q
, W5 G: u1 \, m: E' l9 j3 A5 F
# 写入excel2 V  N; U7 S# w( W& f+ {3 M4 n* @
# 参数对应 行, 列, 值,(格式)) z6 Q7 C9 x& I6 d6 E. M
worksheet.write(1,0, label = 'this is test')
6 c# g  ?- b* V) \( B# 保存
5 c( v! A2 Q8 g3 H# G' G* r#参数为你保存该Excel文件的路径
2 }" J# Y- ^1 z3 v# J9 c* tworkbook.save('Excel_test.xls')
. f& ]" k- {9 |" h: G$ P2 T8 l9 A' C5 O' R7 L
* b7 ?+ a/ p- J$ a$ d  ?. P! S
  如果我们想要点击视频名或者up的名字可以跳转,那么我们就要使用Excel表格的HYPERLINK方法:
3 j% ?/ h, x3 G( Y# nHYPERLINK(“http://www.baidu.com” ; “百度”)
# E0 b: s% P. W% T" Q百度为显示在单元格的信息,而前面的链接为跳转链接。
& x0 s+ e# V% L2 u& _" x% l) o. rxlwt.Formula()方法需要传入一个字符串s,s=‘HYPERLINK(“http://www.baidu.com” ; “百度”)’。
# F/ n' N6 C! l  C/ o代码如下:7 ^: B6 Z% D. m" r
# 将爬取到的数据写入Excel表格
# z$ `  k# b; r4 odef write_Excel(video_list):
6 ]9 P4 s7 ?8 |5 w! Z3 @% I    print("将b站热门视频信息导入到Excel表格:")
9 O$ m/ T: q% W/ g8 N    workbook = xlwt.Workbook()  # 定义workbook
. ?: z- ]# L8 B3 w    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet
+ E" Z! g% [7 j    xstyle = xlwt.XFStyle()  # 实例化表格样式对象4 B. f* Q+ r2 V% d( S; i" G. X
    xstyle.alignment.horz = 0x02  # 字体居中
/ t$ X8 \8 S6 k    xstyle.alignment.vert = 0x01  # 字体居中
! g; S9 e$ [7 q/ f" `    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头
5 \( V* J- Q. I    for h in range(len(head)):
/ n0 P8 J# M$ E+ V" h6 S/ d. s* F& ?        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去/ z1 R# R. y5 X& B( H9 G
    i = 1
. Z1 h$ B( z7 d1 D    for item in video_list:
( i, ?1 Z% Z+ x/ D+ f        # 向单元格(视频名)添加(该视频的)超链接" P* R7 J8 [1 A
        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接
8 D4 L4 H  y! y" s6 u        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽& X  d/ E2 m2 t3 @- f6 R- t# k+ ?
        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)7 }4 n  Z5 O4 s# K, g) ~  {
        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接
1 u, c; \6 Z- @9 U8 o% d  ?7 l% T6 L        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)
& J0 p1 F0 v: o, e6 c  \        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)' k% {) t4 _" v  F9 R3 ]# v& ?
        sheet.write(i, 2, item['rank'], xstyle)
/ Z" {5 r  G8 I% s- c; }2 j        sheet.write(i, 3, item['hot'], xstyle)8 o; p3 r+ z! e% n! ]4 ]
        sheet.write(i, 4, item['play'], xstyle)4 g1 P7 p: x7 T9 v4 t( O
        sheet.write(i, 5, item['comment'], xstyle)
' Q6 n/ r  n. U1 P( A        i += 17 O9 A1 s! c  B$ t) B: ^
    # 如果文件存在,则将其删除- k& ~8 @$ W( n3 B
    if os.path.exists('D:/Test/b站热门视频信息.xls'):, I# Q+ L) f! @1 V+ V
        os.remove('D:/Test/b站热门视频信息.xls')
, G% T+ H" I( H: |( L# R    workbook.save('D:/Test/b站热门视频信息.xls')7 D) }% ^% ^  }' M
    print('写入excel成功')
7 h' Q7 m, [( q- h    print("文件位置:D:/Test/b站热门视频信息.xls")
" ^+ ^( b. w, U2 y+ I
9 O$ g! o, c* k" a3 K* {
+ u2 U# g# e5 \$ S; i% }4.在入口main中调用上面两个函数, ^: q; Q1 T5 Q% z) g
完整代码如下:
" W# l: _1 j% {5 H, m5 ?import requests
, `$ [, r+ q4 z, G$ K" F/ G2 Rfrom lxml import html
2 U* `5 n7 N" @; l4 ]# U& }: A9 zimport xlwt3 {, n& b5 Z+ t1 x% A( f, `
import os; n, j2 {9 C8 ]

, g" n% b' L& Q, I  \4 {# 爬取b站热门视频信息
2 S/ b, n, F$ Vdef spider(video_list):& L  T" _6 W6 k9 |3 g
    url = 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3'7 R, }/ o# ]- \* T1 b. ^
    html_data = requests.get(url).text+ y/ ^/ x2 H7 w! _/ c
    selector = html.fromstring(html_data)
; b/ T" ^, \4 J; L. p    infolist = selector.xpath('//li[@class="rank-item"]')
2 _3 ^& |3 A2 W0 e( k+ Z4 {    for item in infolist:- P" a& V, V: B: U* w2 K
        rank = "".join(item.xpath('./div[@class="num"]/text()'))4 U  s! `5 k& C1 u
        videolink = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/@href'))
  \* O. \/ g( X4 A( e# T        title = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/a/text()')); g  `; g9 q2 m. z3 i
        playinfo = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/span/text()')).split("万")  w/ m- [1 Y, G! Y8 V$ h. `
        play = playinfo[0] + "万"
8 _+ j6 K+ b* R- j        comment = playinfo[1]7 a3 p8 h2 b8 n
        if comment.isdigit() == False:: `' Y3 |; b' J. |* Y  a# _; F
            comment += "万"7 p8 `7 F% d- ?- \  }
        upname = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/span/text()'))! V9 H+ ^% C; B
        uplink = "http:" + "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="detail"]/a/@href'))
) ^3 q7 p7 B5 E' V5 g; q        hot = "".join(item.xpath('./div[@class="content"]/div[@class="info"]/div[@class="pts"]/div/text()'))
' b9 n3 K$ M0 T9 w3 }% D        video_list.append({8 a3 g/ F7 a7 G
            'rank': rank,  s9 G- G6 a. e2 v
            'videolink': videolink,
. W4 g  m/ F9 H, t            'title': title,8 F, p: s: r5 Y" b" b
            'play': play,  I+ F8 J  J) O9 _! v3 P
            'comment': comment,
) l9 S0 A/ T3 R% ^2 b7 p# Q            'upname': upname,
  X% _2 m8 o) j, v( U$ \            'uplink': uplink,
. }/ n: l$ d! j% B, ]             'hot': hot
) e% M( T  v: A% y4 K& D1 d        })
' f( p/ q8 \# T/ w, E    return video_list
" I& g8 d( ~1 h! u7 n$ l. U* \% M: l3 A
# 将爬取到的数据写入Excel表格* {0 L3 W, V- K$ m2 N
def write_Excel(video_list):
! g" R; j- `8 J9 I- q7 G0 e    print("将b站热门视频信息导入到Excel表格:")4 K, b4 K: `2 f
    workbook = xlwt.Workbook()  # 定义workbook
  m7 ]. X" e8 |8 ~6 \' [    sheet = workbook.add_sheet('b站热门视频')  # 添加sheet- Q) I" p! @1 D. H3 X; k
    xstyle = xlwt.XFStyle()  # 实例化表格样式对象
$ m: @. J% y5 \! E% \2 K    xstyle.alignment.horz = 0x02  # 字体居中& c+ t# U2 j8 \3 }8 A2 t
    xstyle.alignment.vert = 0x01  # 字体居中  n6 F% x4 ?4 `) \
    head = ['视频名', 'up主','排名', '热度','播放量','评论数']  # 表头4 B, f( }0 x! ~0 |
    for h in range(len(head)):( w0 e& H& x; F' ?
        sheet.write(0, h, head[h],xstyle)  # 把表头写到Excel里面去! P6 r8 W$ @6 \9 W# N) C. D
    i = 1- Q! E3 q) c1 o
    for item in video_list:
! q) l+ C. H1 ^+ q        # 向单元格(视频名)添加(该视频的)超链接6 L5 r) |: }6 t; ?9 y3 Q
        title_data = 'HYPERLINK("'+item["videolink"]+'";"'+item["title"]+'")'  # 设置超链接
0 p8 B# {* c  Q        sheet.col(0).width = int(256 * len(title_data) * 3/5)   # 设置列宽2 W# J0 Q& K" v
        sheet.write(i, 0, xlwt.Formula(title_data), xstyle)8 g4 y# s: s4 n. N) l2 G' ?, m( S7 u
        name_data = 'HYPERLINK("' + item["uplink"] + '";"' + item["upname"] + '")'  # 设置超链接
- x5 [; U: l! f9 r        sheet.col(1).width = int(256 * len(title_data) * 3 / 10)
& F# \; |0 Q0 g7 g" H        sheet.write(i, 1, xlwt.Formula(name_data), xstyle)
# C2 w) w" ~- f# E3 c- }' g        sheet.write(i, 2, item['rank'], xstyle)
3 o+ j. ?* \( z        sheet.write(i, 3, item['hot'], xstyle)
& @7 F; t" c* |9 _: Z        sheet.write(i, 4, item['play'], xstyle)) h% P& }# e8 a0 [* S" i
        sheet.write(i, 5, item['comment'], xstyle)! ?! Y  Y# y5 f
        i += 1/ o! f# b( N$ l- p0 F7 A
    # 如果文件存在,则将其删除
# ]; \) b/ H! t6 r7 B$ ~" _. q    if os.path.exists('D:/Test/b站热门视频信息.xls'):
/ R" ^7 d" E7 e! a        os.remove('D:/Test/b站热门视频信息.xls'); w$ l6 A, w& e0 K9 n' V' G: Q  ^
    workbook.save('D:/Test/b站热门视频信息.xls')
* o0 a: `4 t, `1 b: K$ F    print('写入excel成功')' Y1 ~3 d8 [/ i, C0 x7 r; ^
    print("文件位置:D:/Test/b站热门视频信息.xls")5 {: D1 E9 ^) ^

/ @# g* l# Q0 ?( t7 j6 v2 G+ Y% pif __name__ == '__main__':9 G( P& ]: C% B1 Y% z+ f' Q
    video_list = []8 v" m, q: D5 D
    write_Excel(spider(video_list))
+ c/ g. h; v$ z  h! u
- E3 U  w; ?- k/ o4 B( b
5 }% ]) T& r- \. a/ Y8 s
& S+ m# f& ^7 q0 I5 [- A- e0 S/ G0 C

: G: Y2 z' `5 [3 p




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