Python项目实战哔哩哔哩用户抓取及源码
Posted 日常分享Python
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python项目实战哔哩哔哩用户抓取及源码相关的知识,希望对你有一定的参考价值。
目录
本文所使用的数据可视化为infogr.am
该爬虫仅供学习使用
文件介绍
bilibili_user.py
:爬虫文件bilibili_user_info.sql
:数据库文件get_face.py
:用户头像下载器
用户数据初步分析
基本概况
- 总数据数:20119918
- 抓取用户的顺序为其注册时间顺序:2009-06-24 14:06:54 至 2016-02-18 21:04:52
- 预估遗漏数据:不超过2%
- 抓取字段:用户id,昵称,性别,头像,等级,经验值,粉丝数,生日,地址,注册时间,签名,等级与经验值等。
性别
- 有效数据:14643019
- 保密:11621898
- 男:1674196
- 女:1346925
这个男女比例是有点出乎个人预料的,接近1:1。其实之前初步抓了2013年暑假之前的数据,男女比例当时还在3:1这样。
可见明确性别的群体还是比较少的,只占了总数据的 15% 左右。
更多的分析日后再做。
年龄
- 统计范围:1970-2010(1980年除外)
- 总数据:3800767
具体数据不放了,简单看一下统计结果吧。
主要用户分布在93-00年的用户(大概16-23周岁),其中97年(19岁)用户占了绝对的主导地位。
事实证明,B站小学生并不多,而是高中生、大学生比较多。
90后用户占主体,但是用户年龄段正在不断后移。毕竟,是一个年轻人的网站。
地区
- 分析范围:国内34个省市及地区。
- 有效数据:863541
主要用户分布在:广东、江苏、北京、上海、浙江等地区。都是一些经济很发达的沿海地区。
注册时间
- 统计时间:2009-06-24 14:06:54 至 2016-02-18 21:04:52
- 总数据:20119823
由于16年才过去2个多月,所以少一点,不过可以预见其发展必将远超2015年。自2009年开站以来,每年用户几乎都是以指数级增长。
活跃度统计
- 等级范围:0 - 6
- 总数据:20119918
- 截止时间:2016-02-18
由于B站有经验等级规则,用户的活跃度可以依据等级判断。
等级为0,就是只注册未登陆过的用户。等级为1或2,为非活跃用户。等级为3以上,就是活跃用户。其中等级为5或6的,为投稿数特别特别多、视频特别火爆的用户,为B站的主干用户(约5000人)。
关于留存率等数据,日后再统计分析。
粉丝统计
- 有效数据:2011918
- 范围:0 - 988323
- 截止时间:2016-02-18 21:04:52
哎- -,我也是有2个粉丝的人!
以下是B站TOP20用户。很多人都非常的眼熟哈。
源码:
# -*-coding:utf8-*-
import requests
import json
import random
import pymysql
import sys
import datetime
import time
from imp import reload
from multiprocessing.dummy import Pool as ThreadPool
def datetime_to_timestamp_in_milliseconds(d):
def current_milli_time(): return int(round(time.time() * 1000))
return current_milli_time()
reload(sys)
def LoadUserAgents(uafile):
uas = []
with open(uafile, 'rb') as uaf:
for ua in uaf.readlines():
if ua:
uas.append(ua.strip()[:-1])
random.shuffle(uas)
return uas
uas = LoadUserAgents("user_agents.txt")
head = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/52.0.2743.116 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
'Referer': 'http://space.bilibili.com/45388',
'Origin': 'http://space.bilibili.com',
'Host': 'space.bilibili.com',
'AlexaToolbar-ALX_NS_PH': 'AlexaToolbar/alx-4.0',
'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4',
'Accept': 'application/json, text/javascript, */*; q=0.01',
}
# Please replace your own proxies.
proxies = {
'http': 'http://120.26.110.59:8080',
'http': 'http://120.52.32.46:80',
'http': 'http://218.85.133.62:80',
}
time1 = time.time()
urls = []
# Please change the range data by yourself.
for m in range(5214, 5215):
for i in range(m * 100, (m + 1) * 100):
url = 'https://space.bilibili.com/' + str(i)
urls.append(url)
def getsource(url):
payload = {
'_': datetime_to_timestamp_in_milliseconds(datetime.datetime.now()),
'mid': url.replace('https://space.bilibili.com/', '')
}
ua = random.choice(uas)
head = {
'User-Agent': ua,
'Referer': 'https://space.bilibili.com/' + str(i) + '?from=search&seid=' + str(random.randint(10000, 50000))
}
mid = payload['mid']
#使用post会报错 (2021/5/2)
jscontent = requests \\
.session() \\
.get('https://api.bilibili.com/x/space/acc/info?mid=%s&jsonp=jsonp' % mid,
headers=head,
data=payload
) \\
.text
time2 = time.time()
try:
jsDict = json.loads(jscontent)
status_code = jsDict['code'] if 'code' in jsDict.keys() else False
if status_code == 0:
if 'data' in jsDict.keys():
jsData = jsDict['data']
mid = jsData['mid']
name = jsData['name']
sex = jsData['sex']
rank = jsData['rank']
face = jsData['face']
regtimestamp = jsData['jointime']
regtime_local = time.localtime(regtimestamp)
regtime = time.strftime("%Y-%m-%d %H:%M:%S", regtime_local)
birthday = jsData['birthday'] if 'birthday' in jsData.keys() else 'nobirthday'
sign = jsData['sign']
level = jsData['level']
OfficialVerifyType = jsData['official']['type']
OfficialVerifyDesc = jsData['official']['desc']
vipType = jsData['vip']['type']
vipStatus = jsData['vip']['status']
coins = jsData['coins']
print("Succeed get user info: " + str(mid) + "\\t" + str(time2 - time1))
try:
res = requests.get(
'https://api.bilibili.com/x/relation/stat?vmid=' + str(mid) + '&jsonp=jsonp').text
viewinfo = requests.get(
'https://api.bilibili.com/x/space/upstat?mid=' + str(mid) + '&jsonp=jsonp').text
js_fans_data = json.loads(res)
js_viewdata = json.loads(viewinfo)
following = js_fans_data['data']['following']
fans = js_fans_data['data']['follower']
except:
following = 0
fans = 0
else:
print('no data now')
try:
print(jsDict)
# Please write your MySQL's information.
conn = pymysql.connect(
host='localhost', user='root', passwd='123456', db='bilibili', charset='utf8')
cur = conn.cursor()
cur.execute('INSERT INTO bilibili_user_info(mid, name, sex, rank, face, regtime, \\
birthday, sign, level, OfficialVerifyType, OfficialVerifyDesc, vipType, vipStatus, \\
coins, following, fans) \\
VALUES ("%s","%s","%s","%s","%s","%s","%s","%s",\\
"%s","%s","%s","%s","%s", "%s","%s","%s")'
%
(mid, name, sex, rank, face, regtime, \\
birthday, sign, level, OfficialVerifyType, OfficialVerifyDesc, vipType, vipStatus, \\
coins, following, fans))
conn.commit()
except Exception as e:
print(e)
else:
print("Error: " + url)
except Exception as e:
print(e)
pass
if __name__ == "__main__":
pool = ThreadPool(1)
try:
results = pool.map(getsource, urls)
except Exception as e:
print(e)
pool.close()
pool.join()
源码太多啦,想要获取完整的源码可以戳这里
以上如果想要操作一遍的或者想要代码的可以+关+私
或者+qq群聊 :222020937【既能学习也能接单,而且资料及视频代码也准备好了】 欢迎加入《广告勿加,不然你做啥啥不赚钱》
以上是关于Python项目实战哔哩哔哩用户抓取及源码的主要内容,如果未能解决你的问题,请参考以下文章
好课推荐Flutter高级进阶实战 仿哔哩哔哩APP~7百度网盘分享