def query_live_status(uid=None): if uid is None: return uid = str(uid) query_url = 'https://api.bilibili.com/x/space/acc/info?mid={}&my_ts={}'.format( uid, int(time.time())) response = util.requests_get(query_url, '查询直播状态') if util.check_response_is_ok(response): result = json.loads(str(response.content, 'utf-8')) if result['code'] != 0: logger.error( '【查询直播状态】请求返回数据code错误:{code}'.format(code=result['code'])) else: name = result['data']['name'] live_status = result['data']['live_room']['liveStatus'] if LIVING_STATUS_DICT.get(uid, None) is None: LIVING_STATUS_DICT[uid] = live_status logger.info('【查询直播状态】【{uname}】初始化'.format(uname=name)) return if LIVING_STATUS_DICT.get(uid, None) != live_status: LIVING_STATUS_DICT[uid] = live_status room_id = result['data']['live_room']['roomid'] room_title = result['data']['live_room']['title'] room_cover_url = result['data']['live_room']['cover'] if live_status == 1: logger.info('【查询直播状态】【{name}】开播了,准备推送:{room_title}'.format( name=name, room_title=room_title)) push.push_for_bili_live(name, room_id, room_title, room_cover_url)
def _get_wechat_access_token(self): access_token = None url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={corpsecret}'.format( corpid=self.wechat_corp_id, corpsecret=self.wechat_corp_secret) response = util.requests_get(url, '推送_wechat_获取access_tokon') if util.check_response_is_ok(response): result = json.loads(str(response.content, 'utf-8')) access_token = result['access_token'] return access_token
def query_live_status(room_id=None): if room_id is None: return query_url = 'https://webcast.amemv.com/webcast/reflow/{}?my_ts={}`'.format( room_id, int(time.time())) headers = get_headers_for_live() response = util.requests_get(query_url, '查询直播状态', headers=headers, use_proxy=True) if util.check_response_is_ok(response): html_text = response.text soup = BeautifulSoup(html_text, "html.parser") result = None scripts = soup.findAll('script') for script in scripts: script_string = script.string if script_string is None: continue if 'window.__INIT_PROPS__ = ' in script_string: result_str = script.string.replace('window.__INIT_PROPS__ = ', '') try: result = json.loads(result_str).get( '/webcast/reflow/:id', None) except TypeError: logger.error('【查询直播状态】json解析错误,room_id:{}'.format(room_id)) return None break if result is None: logger.error('【查询直播状态】请求返回数据为空,room_id:{}'.format(room_id)) else: if result.get('room', None) is None: logger.error( '【查询直播状态】请求返回数据中room为空,room_id:{}'.format(room_id)) return name = result['room']['owner']['nickname'] live_status = result['room']['status'] if LIVING_STATUS_DICT.get(room_id, None) is None: LIVING_STATUS_DICT[room_id] = live_status logger.info('【查询直播状态】【{uname}】初始化'.format(uname=name)) return if LIVING_STATUS_DICT.get(room_id, None) != live_status: LIVING_STATUS_DICT[room_id] = live_status room_title = result['room']['title'] room_cover_url = result['room']['cover']['url_list'][0] room_stream_url = result['room']['stream_url']['hls_pull_url'] if live_status == 2: logger.info('【查询直播状态】【{name}】开播了,准备推送:{room_title}'.format( name=name, room_title=room_title)) push.push_for_douyin_live(name, room_stream_url, room_title, room_cover_url)
def _wechat_push(self, access_token, title, content, url=None, pic_url=None): """ 推送(wechat) :param access_token: 调用接口凭证 :param title: 标题 :param content: 内容 :param url: 跳转url :param pic_url: 图片url """ push_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send' params = {"access_token": access_token} body = { "touser": "******", "agentid": self.wechat_agent_id, "safe": 0, "enable_id_trans": 0, "enable_duplicate_check": 0, "duplicate_check_interval": 1800 } if pic_url is None: body["msgtype"] = "textcard" body["textcard"] = { "title": title, "description": content, "url": url, "btntxt": "打开详情" } else: body["msgtype"] = "news" body["news"] = { "articles": [{ "title": title, "description": content, "url": url, "picurl": pic_url }] } response = util.requests_post(push_url, '推送_wechat', params=params, data=json.dumps(body)) logger.info('【推送_wechat】{msg}'.format( msg='成功' if util.check_response_is_ok(response) else '失败'))
def _server_chan_turbo_push(self, title, content, url=None): """ 推送(serverChan_Turbo) :param title: 标题 :param content: 内容 :param url: 跳转地址 """ content = '`' + content + '`[点我直达]({url})'.format(url=url) push_url = 'https://sctapi.ftqq.com/{key}.send'.format( key=self.serverChan_turbo_SendKey) response = util.requests_post(push_url, '推送_serverChan_Turbo', params={ "title": title, "desp": content }) logger.info('【推送_serverChan_Turbo】{msg}'.format( msg='成功' if util.check_response_is_ok(response) else '失败'))
def query_dynamic(uid=None): if uid is None: return uid = str(uid) query_url = 'http://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history' \ '?host_uid={uid}&offset_dynamic_id=0&need_top=0&platform=web&my_ts={my_ts}'.format(uid=uid, my_ts=int(time.time())) headers = get_headers(uid) response = util.requests_get(query_url, '查询动态状态', headers=headers, use_proxy=True) if util.check_response_is_ok(response): result = json.loads(str(response.content, 'utf-8')) if result['code'] != 0: logger.error( '【查询动态状态】请求返回数据code错误:{code}'.format(code=result['code'])) else: data = result['data'] if len(data['cards']) == 0: logger.info('【查询动态状态】【{uid}】动态列表为空'.format(uid=uid)) return item = data['cards'][0] dynamic_id = item['desc']['dynamic_id'] try: uname = item['desc']['user_profile']['info']['uname'] except KeyError: logger.error('【查询动态状态】【{uid}】获取不到uname'.format(uid=uid)) return if DYNAMIC_DICT.get(uid, None) is None: DYNAMIC_DICT[uid] = deque(maxlen=LEN_OF_DEQUE) cards = data['cards'] for index in range(LEN_OF_DEQUE): if index < len(cards): DYNAMIC_DICT[uid].appendleft( cards[index]['desc']['dynamic_id']) logger.info('【查询动态状态】【{uname}】动态初始化:{queue}'.format( uname=uname, queue=DYNAMIC_DICT[uid])) return if dynamic_id not in DYNAMIC_DICT[uid]: previous_dynamic_id = DYNAMIC_DICT[uid].pop() DYNAMIC_DICT[uid].append(previous_dynamic_id) logger.info('【查询动态状态】【{}】上一条动态id[{}],本条动态id[{}]'.format( uname, previous_dynamic_id, dynamic_id)) DYNAMIC_DICT[uid].append(dynamic_id) logger.info(DYNAMIC_DICT[uid]) dynamic_type = item['desc']['type'] if dynamic_type not in [2, 4, 8, 64]: logger.info( '【查询动态状态】【{uname}】动态有更新,但不在需要推送的动态类型列表中'.format( uname=uname)) return timestamp = item['desc']['timestamp'] dynamic_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp)) card_str = item['card'] card = json.loads(card_str) content = None pic_url = None if dynamic_type == 1: # 转发动态 content = card['item']['content'] elif dynamic_type == 2: # 图文动态 content = card['item']['description'] pic_url = card['item']['pictures'][0]['img_src'] elif dynamic_type == 4: # 文字动态 content = card['item']['content'] elif dynamic_type == 8: # 投稿动态 content = card['title'] pic_url = card['pic'] elif dynamic_type == 64: # 专栏动态 content = card['title'] pic_url = card['image_urls'][0] logger.info('【查询动态状态】【{uname}】动态有更新,准备推送:{content}'.format( uname=uname, content=content[:30])) push.push_for_bili_dynamic(uname, dynamic_id, content, pic_url, dynamic_type, dynamic_time)
def query_dynamic(uid=None, sec_uid=None): if uid is None or sec_uid is None: return signature = sign.get_signature() query_url = 'http://www.iesdouyin.com/web/api/v2/aweme/post?sec_uid={}&count=21&max_cursor=0&aid=1128&_signature={}'.format( sec_uid, signature) headers = get_headers(uid, sec_uid) response = util.requests_get(query_url, '查询动态状态', headers=headers, use_proxy=True) if util.check_response_is_ok(response): result = json.loads(str(response.content, 'utf-8')) if result['status_code'] != 0: logger.error('【查询动态状态】请求返回数据code错误:{code}'.format( code=result['status_code'])) else: aweme_list = result['aweme_list'] if len(aweme_list) == 0: logger.info( '【查询动态状态】【{sec_uid}】动态列表为空'.format(sec_uid=sec_uid)) return aweme = aweme_list[0] aweme_id = aweme['aweme_id'] uid = aweme['author']['uid'] nickname = aweme['author']['nickname'] if DYNAMIC_DICT.get(uid, None) is None: DYNAMIC_DICT[uid] = deque(maxlen=LEN_OF_DEQUE) for index in range(LEN_OF_DEQUE): if index < len(aweme_list): DYNAMIC_DICT[uid].appendleft( aweme_list[index]['aweme_id']) logger.info('【查询动态状态】【{nickname}】动态初始化:{queue}'.format( nickname=nickname, queue=DYNAMIC_DICT[uid])) return if aweme_id not in DYNAMIC_DICT[uid]: previous_aweme_id = DYNAMIC_DICT[uid].pop() DYNAMIC_DICT[uid].append(previous_aweme_id) logger.info('【查询动态状态】【{}】上一条动态id[{}],本条动态id[{}]'.format( nickname, previous_aweme_id, aweme_id)) DYNAMIC_DICT[uid].append(aweme_id) logger.info(DYNAMIC_DICT[uid]) aweme_type = aweme['aweme_type'] if aweme_type not in [4]: logger.info( '【查询动态状态】【{nickname}】动态有更新,但不在需要推送的动态类型列表中'.format( nickname=nickname)) return content = None pic_url = None video_url = None if aweme_type == 4: content = aweme['desc'] pic_url = aweme['video']['origin_cover']['url_list'][0] video_url_list = aweme['video']['play_addr']['url_list'] for temp in video_url_list: if 'ixigua.com' in temp or 'api.amemv.com' in temp: continue if 'aweme.snssdk.com' in temp or 'douyinvod.com' in temp: video_url = temp break logger.info('【查询动态状态】【{nickname}】动态有更新,准备推送:{content}'.format( nickname=nickname, content=content[:30])) push.push_for_douyin_dynamic(nickname, aweme_id, content, pic_url, video_url)