使用Python来爬取短视频链接,目前只分析了抖音的,用Flask生成了api接口,项目地址:ShortVideoSpider。配套客户端详见short_video_spider_client
二、需要安装的库:- Flask~=2.1.2
- requests
- pyOpenSSL
import requests
from flask import Flask, request
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/94.0.4606.71 Safari/537.36 "}
def single_video_douyin(url='', is_origin=0):
try:
url = analyse_url(url)
# 参考 https://blog.csdn.net/m0_46521785/article/details/109684811
resp = requests.get(url).url # 获取url的重定向地址
item_ids = remove_url_before(resp, "https://www.douyin.com/video/")
real_url = f'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={item_ids}'
response = requests.get(real_url, headers=headers)
json_response = response.json()
if json_response['status_code'] != 0:
json_error = {'code': 500, 'des': f'地址解析失败,复制地址重试'}
return json_error
if is_origin != 0:
json_response['code'] = 200
return json_response
else:
video_url = json_response['item_list'][0]['video']['play_addr']['url_list'][0]
origin_cover_imager_url = json_response['item_list'][0]['video']['dynamic_cover']['url_list'][0]
return {'video_url': str(video_url).replace('playwm', 'play'), 'code': 200,
'cover_image_url': origin_cover_imager_url}
except Exception as result:
json_error = {'code': 500, 'des': f'系统内部出现异常,{result}'}
return json_error
def douyin_user_info(url=''):
try:
# 获取抖音用户信息 (sec_uid就是重定向地址后面的值)
# https://www.iesdouyin.com/web/api/v2/user/info/?sec_uid
url = analyse_url(url)
resp = requests.get(url).url # 获取url的重定向地址
sec_uid = remove_url_before(resp)
real_url = f'https://www.iesdouyin.com/web/api/v2/user/info/?sec_uid={sec_uid}'
response = requests.get(real_url, headers=headers)
json_response = response.json()
if json_response['status_code'] != 0:
json_error = {'code': 500, 'des': f'地址解析失败,复制地址重试'}
return json_error
json_response['code'] = 200
return json_response
except Exception as result:
json_error = {'code': 500, 'des': f'系统内部出现异常,{result}'}
return json_error
def list_video_douyin(url='', max_cursor=0, is_origin=0):
try:
url = analyse_url(url)
resp = requests.get(url).url # 获取url的重定向地址
sec_uid = remove_url_before(resp)
# 获取抖音用户下的所有视频 (max_cursor 是否可以滑动,_signature难分析)
# https://www.iesdouyin.com/web/api/v2/aweme/post/?sec_uid=MS4wLjABAAAAsRIQ9howZwtPIsFFZhkMS6q2KIc4wLs5q7LlExJqUNA&count=21&max_cursor=0&_signature=5ifCTAAAhPBHTuX.S4ev0uYnwl
real_url = f'https://www.iesdouyin.com/web/api/v2/aweme/post/?sec_uid={sec_uid}&count=21&max_cursor={max_cursor}'
print(real_url)
response = requests.get(real_url, headers=headers)
json_response = response.json()
if json_response['status_code'] != 0:
json_error = {'code': 500, 'des': f'地址解析失败,复制地址重试'}
return json_error
if is_origin != 0:
json_response['code'] = 200
return json_response
else:
video_url_list = []
cover_image_url_list = []
aweme_list = json_response['aweme_list']
max_cursor = json_response['max_cursor']
has_more = json_response['has_more']
for key in aweme_list:
# 这边除了是视频还可能是音频,音频只有两项
if len(key['video']['play_addr']['url_list']) == 2:
video_url = key['video']['play_addr']['url_list'][0]
cover_image_url_list.append(key['video']['cover']['url_list'][0])
else:
video_url = key['video']['play_addr']['url_list'][2]
cover_image_url_list.append(key['video']['dynamic_cover']['url_list'][0])
video_url_list.append(video_url.replace('watermark=1', 'watermark=0'))
return {'code': 200, 'max_cursor': max_cursor, 'has_more': has_more, 'video_url_list': video_url_list,
'cover_image_url_list': cover_image_url_list, 'des': ''}
except Exception as result:
json_error = {'code': 500, 'des': f'系统内部出现异常,{result}'}
return json_error
def remove_url_before(resp, value='https://www.douyin.com/user/'):
return resp.replace(
value, "")
def analyse_url(url=''):
if not url.startswith('https'):
text_list = url.split(" ")
for i in range(len(text_list)):
if text_list[i].startswith("https") & text_list[i].__contains__("douyin.com"):
return text_list[i]
return url
app = Flask(__name__)
dy_video_number = 0
dy_user_info_number = 0
dy_user_video_list_number = 0
# 获取单个抖音的真实下载地址
@app.route('/douyin/single', methods=['GET'])
def dy_video_url():
global dy_video_number
dy_video_number = dy_video_number + 1
print(f"dy_video_url:{dy_video_number}")
url = request.args.get('url')
is_origin = request.args.get('is_origin')
if is_origin is None:
is_origin = 0
return single_video_douyin(url=url, is_origin=int(is_origin))
# 获取用户信息
@app.route('/douyin/user', methods=['GET'])
def dy_user_info():
global dy_user_info_number
dy_user_info_number = dy_user_info_number + 1
print(f"dy_user_info:{dy_user_info_number}")
url = request.args.get('url')
return douyin_user_info(url=url)
# 获取当前用户下的抖音列表
@app.route('/douyin/list', methods=['GET'])
def dy_user_video_list():
global dy_user_video_list_number
dy_user_video_list_number = dy_user_video_list_number + 1
print(f"dy_user_video_list:{dy_user_video_list_number}")
url = request.args.get('url')
max_cursor = request.args.get('max_cursor')
is_origin = request.args.get('is_origin')
if max_cursor is None:
max_cursor = 0
if is_origin is None:
is_origin = 0
return list_video_douyin(url=url, max_cursor=int(max_cursor), is_origin=int(is_origin))
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=8080)
四、返回说明:
1、单个视频信息:
参数说明:
url:分享的短视频链接,可以直接使用复制内容,会解析里面的链接
is_origin: 是否需要原始返回数据(0为需要,1为不需要)
返回数据(is_origin为0):
{
"code": 200,
//cover_image_url 视频封面的图片地址
"cover_image_url": "https://p3-sign.douyinpic.com/obj/tos-cn-i-dy/b3cc0713ff7c4ad58e989ad4b8fde693?x-expires=1659412800&x-signature=SxHpFcL6X9HpvAS005QMN%2BhPh2Q%3D&from=4257465056_large",
//video_url 视频无水印地址
"video_url": "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200fg10000cb6l3ojc77u09nmstov0&ratio=720p&line=0"
}
返回数据(is_origin为1):
抖音的详细数据,返回的数据太多,自己进行测试。
2、多个视频信息:
参数说明:(一次最多返回20条数据)
url:分享的用户主页链接,可以直接使用复制内容,会解析里面的链接
is_origin: 是否需要原始返回数据(0为需要,1为不需要)
max_cursor:第一次为0,返回会有hasmore来确定是否有更多数据,设置返回的max_cursor到下次的请求参数来请求下次的数据
返回数据(is_origin为0):
{
"code": 200,
//视频封面图片地址的列表
"cover_image_url_list": [
.....
],
//描述信息
"des": "",
//是否有更多数据
"has_more": true,
//下次最大滑动距离
"max_cursor": 1643624245000,
//视频无水印地址列表
"video_url_list": [
.....
]
}
请求的数据太多,自己进行测试。
3、用户信息:
参数说明:
url:分享的用户主页链接,可以直接使用复制内容,会解析里面的链接
返回数据:
{ "code": 200,
"extra": {
"logid": "20220715151907010209168157440162C9",
"now": 1657869547000 },
"status_code": 0,
"user_info": {
"avatar_larger": {
"uri": "aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9",
"url_list": [
"https://p3.douyinpic.com/aweme/1080x1080/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662",
"https://p11.douyinpic.com/aweme/1080x1080/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662",
"https://p26.douyinpic.com/aweme/1080x1080/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662"
]
},
"avatar_medium": {
"uri": "aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9",
"url_list": [
"https://p3.douyinpic.com/aweme/720x720/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662",
"https://p11.douyinpic.com/aweme/720x720/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662",
"https://p26.douyinpic.com/aweme/720x720/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662"
]
},
"avatar_thumb": {
"uri": "aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9",
"url_list": [
"https://p3.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662",
"https://p11.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662",
"https://p26.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-i-0813_8b7da88366bc40bba58e2f8bce0255c9.jpeg?from=2956013662"
]
},
"aweme_count": 6,
"card_entries": [],
"custom_verify": "",
"enterprise_verify_reason": "",
"favoriting_count": 0,
"follow_status": 0,
"follower_count": 101,
"followers_detail": null,
"following_count": 239,
"geofencing": null,
"is_gov_media_vip": false,
"is_mix_user": false,
"mix_count": 0,
"mix_info": null,
"mplatform_followers_count": 101,
"nickname": "十七",
"original_musician": {
"digg_count": 0,
"music_count": 0,
"music_used_count": 0
},
"platform_sync_info": [],
"policy_version": null,
"sec_uid": "MS4wLjABAAAAsRIQ9howZwtPIsFFZhkMS6q2KIc4wLs5q7LlExJqUNA",
"secret": 0,
"short_id": "0",
"show_favorite_list": false,
"signature": "互关咯n#中二病 #熬夜冠军 #俄语废物",
"total_favorited": "263",
"type_label": null,
"uid": "405060254438335",
"unique_id": "xsy897256134",
"verification_type": 0
}}



