好久不更新博文了,最近确实有点忙,论文、presentation两头忙,家里又各种事,自己身体健康也没跟上。别说是计量经济学了,我连Python都搁了很久啦!

正好这周有三门必修结课,空了一点时间,先水一篇再说!

#其实是我的学习笔记。

思路:

1 先打开Chrome的调试模式,看下番剧列表是怎么加载的

Chrome截图

显然,番剧列表是由这个result?……请求完成的,而且返回的还是json格式,那么这也太简单了,连页面解析都不需要。

2 点一下Headers可以看到这次请求的详细信息

2.1 General

1Request URL: https://api.bilibili.com/pgc/season/index/result?season_version=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&order=3&st=1&sort=0&page=1&season_type=1&pagesize=20&type=1
2Request Method: GET
3Status Code: 200 
4Remote Address: 127.0.0.1:7890
5Referrer Policy: no-referrer-when-downgrade

2.2 Request headers

 1Accept: application/json, text/plain, */*
2Accept-Encoding: gzip, deflate, br
3Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
4Connection: keep-alive
5Cookie:
6Host: api.bilibili.com
7Origin: https://www.bilibili.com
8Referer: https://www.bilibili.com/anime/index/
9Sec-Fetch-Mode: cors
10Sec-Fetch-Site: same-site
11User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36

2.3 Query String Parameters

 1season_version: -1
2area: -1
3is_finish: -1
4copyright: -1
5season_status: -1
6season_month: -1
7year: -1
8style_id: -1
9order: 3
10st: 1
11sort: 0
12page: 1
13season_type: 1
14pagesize: 20
15type: 1

根据General和Parameters,我们请求的url就很明显有两种写法:

第一种写法:

url = '……&page=' + i + '&season_type=1……'
headers={……}
requests.get(url,headers)

第二种:

url = 'https://api.bilibili.com/pgc/season/index/result?'
headers = {……}
params = {……}
requests.get(url,headers,params)

我这里选择第二种,我自己觉得看起来比较简洁一点。

3 思索一下数据的处理方式

由于数据不多,而且json数据很整齐,加上我本人并不会使用数据库(主要原因),所以我决定直接放到一个Excel当中。

嘛,反正挺简单,只要把返回的json中的data['list']里面的元素抽出来,添加到一个新列表就行啦!

完整代码:

 1import requests
2import pandas as pd
3
4#也可以写成完整url
5url = 'https://api.bilibili.com/pgc/season/index/result?'
6headers = {
7    'Host''api.bilibili.com',
8    'Origin''https://www.bilibili.com',
9    'Referer''https://www.bilibili.com/anime/index/',
10    'User-Agent''Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
11}
12#headers中的host、Origin、Referer、User-Agent直接负责制Chrome中的即可
13global page
14
15#获取 requests get 到的 json 列表
16def get_json(url,headers,page):
17    params = {
18        'season_version'-1,
19        'area'-1,
20        'is_finish'-1,
21        'copyright'-1,
22        'season_status'-1,
23        'season_month'-1,
24        'year'-1,
25        'style_id'-1,
26        'order'3,
27        'st'1,
28        'sort'0,
29        'page': page,
30        'season_type'1,
31        'pagesize'20,
32        'type'1
33    }
34    try:
35        #其实这里有两种写法,上面有提到
36        r = requests.get(url,headers=headers,params=params)
37        if r.ok:
38            return r.json()['data']['list']
39        else:
40            print('Not OK!')
41    except Exception as err:
42        print(err)
43    return False
44
45
46#把每一页返回的json中的list整合到一个新的列表中
47def json_to_list(json,vlist):
48    for item in json:
49        vlist.append(item)
50    return vlist
51
52if __name__ == '__main__':
53    page = int(input('Input max page:'))
54    vlist = []
55    #遍历每页的视频列表
56    for i in range(1,page+1):
57        json = get_json(url,headers,i)
58        json_to_list(json,vlist)
59        print("Page {} completed!".format(i))
60    print('All done.')
61    #把vlist转换成一个DataFrame对象
62    vframe = pd.DataFrame(vlist)
63    #输出到Excel
64    vframe.to_excel('Bili_list.xls')

最终效果:

虽然我也不知道这样做有什么意义。