但其实直接分析不带水印的百度抖音已经有很多结果了。 网上有很多解析网站。 粘贴分享链接,点击解析即可获取无水印的短视频链接。 通过该链接,您可以直接将抖音中的无水印短视频保存到本地。 每一款都相当好用,所以如果你只是想方便地下载无水印的抖音短视频,可以直接使用百度在线网站。
如果你和我一样喜欢盲目研究,那就和我一起来看看吧。 本文主要以抖音无水印短视频的分析和下载为例,介绍爬虫思维的转变:遇到难啃的骨头,没必要硬碰硬。 换个角度可能会更容易! (我们都是程序员,何必为难同行[捂脸])当然,如果你走的是软件逆向路线,就当我什么也没说,直接看抖音反混淆逆向分析的文章文章:
本文涉及的代码(版本)和接口不保证是最新的,但保持不变,思路依然没问题。 不过,我也会有时间更新最新的代码,请大家继续关注!
1.抖音基础无水印解析版
虽然我平时很喜欢研究,但有时候也挺懒的[捂脸]。 第一步,遇到问题就上网搜索(遇到问题就先网上搜索一下,啥都行),就会找到可用的版本。 这个版本是一个巧妙的方式,但是对于我们平时写代码的时候来说,快速完成业务才是最好的方式,虽然这有点不负责任,哈哈哈。 原理是直接请求抖音短视频分享链接,获取html内容。
<script>
$(function(){
require('web:component/reflow_video/index').create({
hasData: 1,
videoWidth: 720,
videoHeight: 1280,
playAddr: "https://aweme.snssdk.com/aweme/v1/playwm/?s_vid=93f1b41336a8b7a442dbf1c29c6bbc569e748f551cc25ae99221c35b080756a55a1dd75742144fa8e4c080d418b69e554150d60e91f33d2a629aeb3b8ba82eb4&line=0",
cover: "https://p9.pstatp.com/large/275c1000436aced6f739d.jpg"
});
});
script>
然后提取HTML内容中的链接,然后将链接中的“”更改为“play”,将“&line=0”更改为“&line=1”。 然后请求改变后的链接,请求时获取302跳转链接。 此链接为抖音无水印链接。 链接具有时间敏感性,在一段时间后就会过期。 该版本对应的核心代码如下(这部分代码不再有效):
res = requests.get(url=self.share_link, headers=self.headers)
video_link = re.findall(r"playAddr: \"(.+?)\"", res.text)[0]
real_link = re.sub(r"playwm", "play", video_link)
real_link = re.sub(r"&line=0", "&line=1", real_link)
# 此处要用手机浏览器UA
res = requests.get(real_link, headers=self.headers1, allow_redirects=False)
real_link = res.headers['Location']
2.通过抓包获取官方接口()
我通过搜索找到的方法用了一段时间就被屏蔽了。 第二步就是自己动手做。 什么也别说。 我们先抓一个包看一下(按照官方流程,整个过程就是抓包)。 玩过抖音的朋友都知道,抖音短视频可以通过链接的形式进行分享。 我们不妨直接在手机浏览器中打开分享链接,看看抖音官方是如何获取无水印视频的。 该进程用于抓包整个过程,分析官方请求路径。 用浏览器打开并播放后发现直接播放的视频是带水印的视频。 不过,点击顶部的“打开看一看”选项,会直接打开抖音应用(我这里使用的测试机)并播放这段视频。 至此,抓包结束。
然后我们一一查看抓包数据,看看是否有获取可疑数据的接口。 基本上就是简单浏览一下,看看有没有和这个视频相关的数据。 结果我发现有一个基本上包含了这个视频的所有信息,比如视频标题、封面、无水印链接等等,所以我们基本上可以确认这就是我们想要的界面,然后我们查看了请求标头。 没想到我们发现基本没有验证,而且还是json格式。 是不是很精彩,哈哈~
该接口只需要一个动态参数,就是短视频。 这个参数很容易获得。 可以直接请求分享链接,然后获取302跳转链接。 链接里就有这个id,这里就不详细说了。 以下是抖音无水印短视频解析版爬虫版该接口的核心源码(该接口现已停运,而且业余,代码比较粗糙,所以就放在那个[面罩]):
class Douyin(object):
def __init__(self, share_link, proxies, ua='Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A405 Safari/600.1.4'):
self.headers1 = {
'User-Agent': ua,
'Host': 'v.douyin.com',
}
self.headers2 = {
'User-Agent': 'okhttp/3.10.0.1',
'Accept-Encoding': 'utf-8',
'Host': 'api-hl.aweme.com',
'sdk-version': '1',
}
self.share_link = share_link
self.proxies = proxies
def getData(self):
res1 = requests.get(self.share_link, headers=self.headers1, allow_redirects=False)
aweme_id = re.findall(r"video\/(.+?)\/", res1.headers['Location'])[0]
api_link = 'https://aweme-hl.snssdk.com/aweme/v1/aweme/detail/?origin_type=web&retry_type=no_retry&device_id=67913728029&ac=wifi&channel=baidu&aid=1128&app_name=aweme&version_code=660&version_name=6.6.0&device_platform=android&ssmix=a&device_type=HUAWEI+VOG-L29&device_brand=HUAWEI&language=zh&os_api=19&os_version=9.0.0&uuid=867000796904268&openudid=502b73dc52682085&manifest_version_code=660&resolution=640*960&dpi=320&update_version_code=6602&_rticket=1561064545285&mcc_mnc=46007&js_sdk_version=&ts=1561064545aweme_id=' + aweme_id
res2 = requests.get(api_link, headers=self.headers2)
json_res = json.loads(res2.text)
real_link = json_res['aweme_detail']['video']['play_addr']['url_list'][0]
# return {'real_link':real_link, 'sort':sort}
3、通过其他接口爬取数据
发现上面的界面后,我想我可以使用它一段时间,然后高枕无忧。 但有一天午休的时候,我实在忍不住了。 我看到一个有趣的抖音视频,想保存它,却发现我的脚本无效。 哎呀,抖音的界面变化这么频繁。 看来抖音程序员的工作还没有饱和。 哈哈哈~我不管,我会保存抖音的无水印视频。 当时我就决定抢个包看看。 一度。
由于我不是程序员,所以公司电脑上基本没有安装编程相关的工具。 我工作时有想法,基本上都是在手机上操作,所以我在手机上安装了JSBox、雷神等应用程序。 这次我就用它来进行互联网上的抓包(基本一键完成,不难,这里就不介绍了)。 按照上次的思路,捕获整个数据包,然后查看请求响应,最终找到我们想要的接口。 但我发现这个接口中有很多用于验证的参数,我得研究一下这些参数是如何生成的。 我是一个会研究这些的人吗? 哈哈哈~
所以果断跳过,看看还有没有其他办法。 第三步,通过另一个渠道获取数据(直接请求、间接请求)。 我们早就听说字节跳动很有野心,想要借力今日头条上的百度搜索,所以整合了今日头条上的各种数据,比如新闻、视频、短视频等,这一点大家应该都知道我要做什么了:通过今日头条接口获取抖音数据!
打开今日头条,你会发现一个小视频入口。 切换后,里面有各种短视频。 但我并没有找到我想要的短视频的突破点。 正当我要改变主意的时候,我发现了顶部的搜索入口。 我试着搜索视频的描述,找到了,而且播放时没有水印。
于是我们赶紧用抓包来看看。 因为请求很少,所以很快就找到了我们想要的请求接口。 但是看到这个请求头,传递的参数太多了。 哎呀,头发掉光了! 我懒得去验证,所以就打算换平台了。
第四步,改变获取数据的平台(App、iOS App、移动web、PC等)。 像今日头条这样的平台都有网页端,直接去网页抓包看一下就可以了。 这时候我只好打开电脑看一看。 毕竟手机抓包还是不方便。 但我不想在公司电脑上安装抓包工具,所以就用浏览器F12打开开发者工具看一下。 还是按照手机上的思路,打开今日头条网页版(点击浏览器开发者选项中的手机图标,模拟手机请求),然后搜索短视频的描述,然后切换到短视频视频选项卡来获取我们需要的搜索结果。 而且无意中发现这个搜索界面没有参数验证,太好了~
然后直接使用开发者选项中的选择工具选择我们搜索到的短视频,查看对应的html内容。 我无意中发现视频链接隐藏在这个a标签中。
然后我们手动访问这个链接,看看是否是我们想要的抖音无水印短视频。 我还是用模拟手机来请求,发现确实是无水印的! 而且,无水印视频的真实链接隐藏在302跳转中。 直接跳302就可以了。
然后下班回家,根据中午在公司抓包的几个接口,写了这个简单的脚本。 原理是先请求抖音短视频的分享链接,获取视频描述和作者,然后使用今日头条的手机网页版短视频搜索界面搜索视频描述,然后遍历搜索结果。 具有相同描述的视频就是我们需要的视频,然后获取这个视频的a标签的链接。 如果您请求此链接并获得302跳转,您将获得无水印的视频链接。 对应的核心代码如下:
# 方案6
res2 = requests.get(location, headers=self.headers2)
author = re.findall(r'(.+?)<\/p>'
, res2.text)[0][1:]
des = re.findall(r'(.+?)<\/p>'
, res2.text)[0]
api = 'https://m.toutiao.com/search/?pd=xiaoshipin&source=search_subtab_switch&traffic_source=&original_source=%20HTTP/1.1&in_tfs=&in_ogs=%20HTTP/1.1&keyword='
url = api + urllib.parse.quote(des)
try:
random_proxy = random.choice(self.proxies)
build_proxy = {'http': random_proxy.ip + ':' + random_proxy.port, 'https': random_proxy.ip + ':' + random_proxy.port}
res3 = requests.get(url, headers=self.headers3, proxies=build_proxy, timeout=3)
except:
res3 = False
else:
sort = 'proxy'
if(not res3):
res3 = requests.get(url, headers=self.headers3)
sort = 'real'
selector = etree.HTML(res3.text)
items = selector.xpath('//a[@class="SmallVideoTab_video_3gWUNMfo tt-word10"]')
link = ''
for item in items:
try:
des_temp = item.xpath('.//p[@class="SmallVideoTab_title_12Va1bWi tt-word-line line-2 tt-size17"]/text()')[0]
author_temp = item.xpath('.//div[@class="SmallVideoTab_user_1c7VzUUt tt-word-line"]/span/text()')[0]
except:
pass
# print(difflib.SequenceMatcher(None, des_temp, des).quick_ratio())
# print(difflib.SequenceMatcher(None, author_temp, author).quick_ratio())
else:
if(des_temp == des):
link = item.xpath('@href')[0]
if(not link):
return {'status':False, 'des':'为能解析出无水印视频!'}
else:
res4 = requests.get(link, headers=self.headers4, allow_redirects=False)
return {'status':True, 'real_link':res4.headers['Location'], 'sort':sort}
4. 总结
改变角度,让爬行变得更简单。 总结一下,改变角度的基本思路如下:
① 先上网搜索一下有没有现成的方法或者接口可以使用。 毕竟热爱发明轮子的程序员还是很多的[笑哭];
② 网上没有现成的数据。 首先要遵循官方的数据采集流程,全程抓包,看看情况再做决定;
③如果接口验证参数较多且复杂,可考虑更换其他平台。 例如,如果该App反爬虫能力较强,不妨尝试一下iOS→App→Web→微信,看看哪个平台的反爬虫能力最弱,然后从该平台入手;
④当更换平台仍然困难时,可以考虑更换数据源渠道,看看是否有其他地方有类似的数据。 例如,可以从用户主页、数据详情页、搜索渠道获取用户数据;
⑤ 全部分析完毕,如果还是无法绕过反爬虫机制,那就算了,直接在网页上访问Web即可。 例如 + 或 + ;
⑥ 既然已经到了这一步,不妨在线向专家请教。 如果专家给你指点一下,你可能就明白怎么操作了[笑哭];
⑦如果最后实在没有选择,就只能硬着头皮对其各种验证算法进行逆向工程。 但还是建议先从网页版入手,最后再考虑app逆向工程;
评论:
按照上面的思路,我找到了至少四五个可供抖音无水印分析的接口,但说到抖音的兴趣,这里就不透露太多了。 如果你遵循这个想法,你总会找到一些东西。 不过如果大家非常感兴趣的话,可以关注公众号:并在后台给我留言。 如果需要的人多的话我会写一个接口供大家使用~(非商业用途!)
最后说实话,只要你够调皮,头发就会少掉,哈哈哈哈~