鱼C论坛

 找回密码
 立即注册
查看: 2965|回复: 14

[作品展示] 使用多线程1分钟下载腾讯视频20集35万条弹幕并存在数据库中

[复制链接]
发表于 2021-3-9 10:22:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import requests,re,time,random
  2. import pymysql
  3. from fake_useragent import UserAgent
  4. from lxml import etree
  5. import concurrent.futures

  6. def get_danmu(params):#获取弹幕
  7.     url=params['url']#获取弹幕url
  8.     name = params['name']#获取数据库表明
  9.     page=name.split('danmu')[1]#获取集数
  10.     danmus=[]
  11.     #建立代理ip池
  12.     iplist = ['112.195.202.102:4278']#代理ip库,从网上选几个可用的
  13.     ip = random.choice(iplist)
  14.     proxies = {"http": ip, "https": ip}
  15.     headers = {'User-Agent': UserAgent().random}#导入随机文件头库,用于反爬虫
  16.     try:
  17.         res=requests.get(url=url,headers=headers,proxies=proxies,timeout=10)#删除proxies=proxies使用本机ip下载
  18.     except:
  19.         j=0
  20.         while j <10:#如果连接失败,重新进行连接,最多连接10次
  21.             ip = random.choice(iplist)
  22.             proxies = {"http": ip, "https": ip}
  23.             try:
  24.                 res = requests.get(url=url, headers=headers, proxies=proxies, timeout=10)
  25.             except:
  26.                 pass
  27.             print('正在进行第{}次重新连接--------------------------------------------'.format(j))
  28.             j += 1
  29.             time.sleep(2)
  30.     print('正在下载第{}集弹幕,本页弹幕共{}条'.format(page,eval(res.text)['count']))
  31.     if eval(res.text)['count'] != 0 and res.status_code==200:#如果网页请求成功及弹幕数量大于0
  32.         res = eval(res.text)#将网页相应内容变成字典
  33.         for each in res['comments']:
  34.             author = ''.join(re.findall(u"[\u4e00-\u9fa5]+", each['opername'].replace(' ', '')))#作者名字只提取中文
  35.             content = ''.join(re.findall(u"[\u4e00-\u9fa5]+", each['content'].replace('\xa0', '')))#评论内容只提取中文
  36.             danmus.append({
  37.                 '作者': '未知作者' if len(author) == 0 else author,#如果为空值则默认为未知作者
  38.                 '弹幕内容': '未知弹幕' if len(content) == 0 else content,#如果为空值则默认为未知弹幕
  39.                 '点赞数': each['upcount'],
  40.                 '弹幕发送时间': each['timepoint'],
  41.                 '作者等级': each['uservip_degree'],
  42.                 '弹幕id': each['commentid']})
  43.     insert([tuple(each.values()) for each in danmus], name)#将提取的弹幕写入数据库,此处必须要以数组传入



  44. def get_after_param():#获得后缀id
  45.     url = 'https://v.qq.com/x/cover/o8mbrpo92gni5uc/i0036rltvk1.html'#输入任意电视剧某一集的网站
  46.     headers = {'User-Agent': UserAgent().random}
  47.     res = requests.get(url = url,headers=headers)
  48.     html = etree.HTML(res.content)
  49.     afterid = html.xpath("//div[@class='mod_episode']/span[@_stat='videolist:click' and not(i)]/@id")#不包含预告片及vip集数
  50.     jishu = [each.replace(' ','').replace('\n','') for each in html.xpath("//div[@class='mod_episode']/span[@_stat='videolist:click' and not(i)]/a/text()")]
  51.     after_param=dict(zip(jishu,afterid))#压缩成字典,方便数据传递
  52.     return after_param

  53. def get_before_param():#获得前缀id
  54.     after_param=get_after_param()
  55.     url='https://access.video.qq.com/danmu_manage/regist?vappid=97767206&vsecret=c0bdcbae120669fff425d0ef853674614aa659c605a613a4&raw=1'
  56.     headers = {'User-Agent': UserAgent().random}
  57.     for each in after_param:
  58.         data = {"wRegistType": 2, "vecIdList": [after_param[each]], "wSpeSource": 0, "bIsGetUserCfg": 1,
  59.                 "mapExtData": {after_param[each]: {"strCid": "o8mbrpo92gni5uc", "strLid": ""}}}
  60.         res = requests.post(url=url, json=data, headers=headers).json()
  61.         after_param[each]=res['data']['stMap'][after_param[each]]['strDanMuKey'].split('targetid=')[1]
  62.     return after_param

  63. def create_table(name):#创建表
  64.     db = pymysql.connect(host='localhost', user='root', password='mxy', port=3306, db='python',charset='UTF8')
  65.     cursor = db.cursor()
  66.     cursor.execute("DROP TABLE IF EXISTS {}".format(name))
  67.     sql = """CREATE TABLE {}
  68.     (
  69.     作者 varchar(255),
  70.     弹幕内容 varchar(255),
  71.     点赞数 varchar(255),
  72.     弹幕发送时间 varchar(255),
  73.     作者等级 varchar(255),
  74.     弹幕id varchar(255)
  75.     )""".format(name)
  76.     cursor.execute(sql)
  77.     db.close()

  78. def insert(value,name):#插入数据
  79.     db = pymysql.connect(host='localhost', user='root', password='mxy', port=3306, db='python')
  80.     cursor = db.cursor()
  81.     sql = "INSERT INTO {}(作者, 弹幕内容,点赞数, 弹幕发送时间,作者等级,弹幕id) values(%s, %s, %s,%s,%s,%s)".format(name)
  82.     try:
  83.         cursor.executemany(sql,value)
  84.         db.commit()
  85.     except:
  86.         db.rollback()
  87.         print(value)
  88.     db.close()

  89. def thread(after_param,name):
  90.     urls = ['https://mfm.video.qq.com/danmu?target_id={}&timestamp={}'.format(after_param,i) for i in
  91.             range(15, 3000, 30)]
  92.     params=[]
  93.     for url in urls:
  94.         params.append({'url': url, 'name': name,'after_param':after_param})
  95.     with concurrent.futures.ThreadPoolExecutor() as pool:
  96.         htmls = pool.map(get_danmu,params)


  97. def main():
  98.     t1 = time.time()
  99.     after_param = get_before_param()
  100.     for i in range(1,len(after_param)+1):
  101.         print('正在爬取第{}集-----------------------------------------------------------------'.format(i))
  102.         t2=time.time()
  103.         create_table('danmu'+str(i))
  104.         thread(after_param[str(i)], 'danmu'+str(i))
  105.         t3= time.time()
  106.         print('-------------------------累计运行{}秒,本集弹幕爬取共用{}秒----------------------------------'.format(t3-t1,t3-t2))
  107.     print('弹幕已经爬取完成')

  108. main()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 10:35:02 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 10:52:53 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 14:51:54 | 显示全部楼层

回帖奖励 +1 鱼币

哇塞i
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-9 16:14:54 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 16:15:27 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 20:38:42 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 20:58:03 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 21:45:23 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 21:56:49 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 23:13:11 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 23:13:21 | 显示全部楼层

回帖奖励 +1 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

头像被屏蔽
发表于 2021-3-9 23:13:32 | 显示全部楼层

回帖奖励 +1 鱼币

提示: 作者被禁止或删除 内容自动屏蔽
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 23:13:43 | 显示全部楼层
.
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-9 23:13:53 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-26 20:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表