Skip to content

Commit

Permalink
修复扫码登录获取 Cookie 功能
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeanAmier committed Mar 14, 2024
1 parent e56b34a commit 36d1c07
Show file tree
Hide file tree
Showing 57 changed files with 793 additions and 412 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
* 🟡 TikTokDownloader 开发计划及进度可前往 [Projects](https://github.com/users/JoeanAmier/projects/2) 查阅
* 🔴 请注意,最新源码可能存在一些不稳定的 Bug
* 🔴 如果在使用过程中发现程序 Bug,请及时告知作者修复
* 🔴 TikTok 平台作品下载功能已失效,待修复
* 🔴 夜晚无法下载高分辨率视频,疑似抖音服务端限制

# 📋 项目说明\(Instructions\)
Expand All @@ -110,14 +111,14 @@
</li>
<li>阅读 TikTokDownloader 的免责声明,根据提示输入内容</li>
<li>将 Cookie 信息写入配置文件
<ol><b>手动复制粘贴(推荐)</b>
<ol><b>手动复制粘贴 Cookie(推荐)</b>
<li>参考 <a href="https://github.com/JoeanAmier/TikTokDownloader/blob/master/docs/Cookie%E8%8E%B7%E5%8F%96%E6%95%99%E7%A8%8B.md">Cookie 提取教程</a>,复制所需 Cookie 至剪贴板</li>
<li>选择 <code>复制粘贴写入 Cookie</code> 选项,按照提示将 Cookie 写入配置文件</li>
</ol>
<ol><b>从浏览器获取(推荐)</b>
<ol><b>从浏览器获取 Cookie(推荐)</b>
<li>选择 <code>从浏览器获取 Cookie</code> 选项,按照提示选择浏览器类型</li>
</ol>
<ol><b>扫码登录获取(停用)</b>
<ol><b>扫码登录获取 Cookie(不推荐)</b>
<li>选择 <code>扫码登录获取 Cookie</code> 选项,程序会显示登录二维码图片,并使用默认应用打开图片</li>
<li>使用抖音 APP 扫描二维码并登录账号</li>
<li>按照提示操作,将 Cookie 写入配置文件</li>
Expand Down Expand Up @@ -235,10 +236,10 @@
* https://github.com/Johnserf-Seed/TikTokDownload
* https://github.com/Evil0ctal/Douyin_TikTok_Download_API
* https://github.com/ihmily/DouyinLiveRecorder
* https://github.com/davidteather/TikTok-Api
* https://github.com/psf/requests
* https://github.com/pallets/flask
* https://github.com/Textualize/rich
* https://github.com/pyinstaller/pyinstaller
* https://docs.aiohttp.org/en/stable/
* https://ffmpeg.org/ffmpeg-all.html
* https://html5up.net/hyperspace
64 changes: 52 additions & 12 deletions docs/TikTokDownloader文档.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@
</li>
<li>阅读 TikTokDownloader 的免责声明,根据提示输入内容</li>
<li>将 Cookie 信息写入配置文件
<ol><b>手动复制粘贴(推荐)</b>
<ol><b>手动复制粘贴 Cookie(推荐)</b>
<li>参考 <a href="https://github.com/JoeanAmier/TikTokDownloader/blob/master/docs/Cookie%E8%8E%B7%E5%8F%96%E6%95%99%E7%A8%8B.md">Cookie 提取教程</a>,复制所需 Cookie 至剪贴板</li>
<li>选择 <code>复制粘贴写入 Cookie</code> 选项,按照提示将 Cookie 写入配置文件</li>
</ol>
<ol><b>从浏览器获取(推荐)</b>
<ol><b>从浏览器获取 Cookie(推荐)</b>
<li>选择 <code>从浏览器获取 Cookie</code> 选项,按照提示选择浏览器类型</li>
</ol>
<ol><b>扫码登录获取(停用)</b>
<ol><b>扫码登录获取 Cookie(不推荐)</b>
<li>选择 <code>扫码登录获取 Cookie</code> 选项,程序会显示登录二维码图片,并使用默认应用打开图片</li>
<li>使用抖音 APP 扫描二维码并登录账号</li>
<li>按照提示操作,将 Cookie 写入配置文件</li>
Expand Down Expand Up @@ -101,6 +101,14 @@
<td align="center"><code>https://www.tiktok.com/@TikTok号/video/作品ID</code></td>
<td align="center">账号、视频、图集</td>
</tr>
<tr>
<td align="center"><code>https://www.douyin.com/channel/分区ID?modal_id=作品ID</code></td>
<td align="center">视频、图集</td>
</tr>
<tr>
<td align="center"><code>https://www.douyin.com/lvdetail/作品ID</code></td>
<td align="center">视频(暂不支持)</td>
</tr>
</tbody></table>
<ul>
<li>账号/作品/直播完整链接:使用浏览器打开抖音或 TikTok 链接时,地址栏所显示的 URL 地址。</li>
Expand Down Expand Up @@ -217,17 +225,32 @@ https://www.douyin.com/note/123456789
<tr>
<td align="center">accounts_urls[mark, url, tab, earliest, latest]</td>
<td align="center">list[dict[str, str, str, str, str]]</td>
<td align="center">账号标识, 账号链接, 批量下载类型, 最早发布日期, 最晚发布日期; 批量下载账号作品时使用, 支持多账号, 以字典格式包含五个参数</td>
<td align="center">抖音平台:账号标识, 账号链接, 批量下载类型, 最早发布日期, 最晚发布日期; 批量下载账号作品时使用, 支持多账号, 以字典格式包含五个参数</td>
</tr>
<tr>
<td align="center">mix_urls[mark, url]</td>
<td align="center">list[dict[str, str]]</td>
<td align="center">合集标识, 合集链接或作品链接, 批量下载合集作品时使用<br>支持多合集, 以字典格式包含两个参数</td>
<td align="center">抖音平台:合集标识, 合集链接或作品链接, 批量下载合集作品时使用<br>支持多合集, 以字典格式包含两个参数</td>
</tr>
<tr>
<td align="center">owner_url[mark, url]</td>
<td align="center">dict[str, str]</td>
<td align="center">已登录 Cookie 的账号标识, 账号主页链接, 批量下载收藏作品时使用<br>用于获取账号昵称和 UID, 以字典格式包含两个参数</td>
<td align="center">抖音平台:已登录 Cookie 的账号标识, 账号主页链接, 批量下载收藏作品时使用<br>用于获取账号昵称和 UID, 以字典格式包含两个参数</td>
</tr>
<tr>
<td align="center">accounts_urls_tiktok[mark, url, tab, earliest, latest]</td>
<td align="center">list[dict[str, str, str, str, str]]</td>
<td align="center">未生效</td>
</tr>
<tr>
<td align="center">mix_urls_tiktok[mark, url]</td>
<td align="center">list[dict[str, str]]</td>
<td align="center">未生效</td>
</tr>
<tr>
<td align="center">owner_url_tiktok[mark, url]</td>
<td align="center">dict[str, str]</td>
<td align="center">未生效</td>
</tr>
<tr>
<td align="center">root</td>
Expand Down Expand Up @@ -275,6 +298,11 @@ https://www.douyin.com/note/123456789
<td align="center">抖音网页版 Cookie, 必需参数; 建议通过程序写入配置文件,亦可手动编辑</td>
</tr>
<tr>
<td align="center">cookie_tiktok</td>
<td align="center">dict | str</td>
<td align="center">未生效</td>
</tr>
<tr>
<td align="center">dynamic_cover</td>
<td align="center">bool</td>
<td align="center">是否下载动态封面图, 默认值: <code>false</code></td>
Expand All @@ -290,6 +318,11 @@ https://www.douyin.com/note/123456789
<td align="center">代理地址, 设置为空字符串代表不使用代理</td>
</tr>
<tr>
<td align="center">proxies_tiktok</td>
<td align="center">str</td>
<td align="center">未生效</td>
</tr>
<tr>
<td align="center">download</td>
<td align="center">bool</td>
<td align="center">是否打开下载功能, 如果关闭, 程序将不会下载任何文件; 默认值: <code>true</code></td>
Expand Down Expand Up @@ -345,6 +378,7 @@ https://www.douyin.com/note/123456789
"latest": ""
}
],
"accounts_urls_tiktok": "参数设置规则同上",
"mix_urls": [
{
"mark": "",
Expand All @@ -355,10 +389,12 @@ https://www.douyin.com/note/123456789
"url": "合集链接或者作品链接"
}
],
"mix_urls_tiktok": "参数设置规则同上",
"owner_url": {
"mark": "已登录 Cookie 的账号标识,可以设置为空字符串(可选)",
"url": "已登录 Cookie 的账号主页链接(可选)"
},
"owner_url_tiktok": "参数设置规则同上",
"root": "C:\\TikTokDownloader",
"folder_name": "SOLO",
"name_format": "create_time uid id",
Expand All @@ -372,9 +408,11 @@ https://www.douyin.com/note/123456789
"passport_csrf_token_default": "demo",
"odin_tt": "demo"
},
"cookie_tiktok": "参数设置规则同上",
"dynamic_cover": false,
"original_cover": false,
"proxies": "http://127.0.0.1:9999",
"proxies_tiktok": "参数设置规则同上",
"download": true,
"max_size": 104857600,
"chunk": 10485760,
Expand Down Expand Up @@ -417,7 +455,7 @@ https://www.douyin.com/note/123456789
}
```

<p>将待下载的账号信息写入配置文件,每个账号对应一个对象/字典,<code>tab</code> 参数设置为 <code>favorite</code> 代表批量下载喜欢作品,支持多账号。</p>
<p>将待下载的抖音账号信息写入配置文件,每个账号对应一个对象/字典,<code>tab</code> 参数设置为 <code>favorite</code> 代表批量下载喜欢作品,支持多账号。</p>
<p><b>批量下载账号喜欢作品需要使用已登录的 Cookie,否则可能无法获取正确的账号信息!</b></p>
<h3>发布日期限制</h3>

Expand Down Expand Up @@ -557,13 +595,12 @@ https://www.douyin.com/note/123456789
<h1>功能介绍</h1>
<h2>复制粘贴写入 Cookie</h2>
<p>参考 <a href="https://github.com/JoeanAmier/TikTokDownloader/blob/master/docs/Cookie%E8%8E%B7%E5%8F%96%E6%95%99%E7%A8%8B.md">Cookie 提取教程</a>,手动从浏览器复制所需 Cookie 至剪贴板,按照程序提示输入 Cookie 后回车确认,程序会自动处理 Cookie 并写入配置文件。</p>
<p><b>推荐使用该方法获取 Cookie</b>,如果粘贴 Cookie 至终端后无响应,可能是 Cookie 文本长度超出终端最大文本长度限制,请考虑更换终端或者其他写入方式。</p>
<p>如果粘贴 Cookie 至终端后无响应,可能是 Cookie 文本长度超出终端最大文本长度限制,请考虑更换终端或者其他写入方式。</p>
<h2>从浏览器获取 Cookie</h2>
<p>自动读取本地浏览器的 Cookie 数据,并提取所需 Cookie 写入配置文件,需要完全关闭对应浏览器才能读取 Cookie 数据。</p>
<h2><del>扫码登录获取 Cookie</del></h2>
<p><del>程序自动获取抖音登录二维码,随后会在终端输出二维码,并使用系统默认图片浏览器打开二维码图片,使用者通过抖音 APP 扫码并登录账号,操作后关闭二维码图片窗口,程序会自动检查登录结果并将登录后的 Cookie 写入配置文件。</del></p>
<p><del><b>注意:</b>扫码登录获取的 Cookie 有效期更短,且频繁扫码登录容易导致账号被风控!</del></p>
<p>当前已失效,未来可能修复或移除!</p>
<h2>扫码登录获取 Cookie</h2>
<p>程序自动获取抖音登录二维码,随后会在终端输出二维码,并使用系统默认图片浏览器打开二维码图片,使用者通过抖音 APP 扫码并登录账号,操作后关闭二维码图片窗口,程序会自动检查登录结果并将登录后的 Cookie 写入配置文件。</p>
<p><b>注意:</b>频繁扫码登录容易导致账号被风控,未来可能移除该功能!</p>
<h2>终端交互模式</h2>
<p>功能最全面的模式,支持全部功能。</p>
<h3>批量下载账号作品(TikTok)</h3>
Expand Down Expand Up @@ -639,6 +676,7 @@ document.body.removeChild(downloadLink);
<li><code>https://www.douyin.com/user/账号ID?modal_id=作品ID</code></li>
<li><code>https://www.douyin.com/search/关键词?modal_id=作品ID</code></li>
<li><code>https://www.tiktok.com/@账号昵称/video/作品ID</code></li>
<li><code>https://www.douyin.com/channel/分区ID?modal_id=作品ID</code></li>
</ul>
<p>作品会下载至 <code>root</code> 参数和 <code>folder_name</code> 参数拼接成的文件夹。</p>
<h3>获取直播推流地址</h3>
Expand Down Expand Up @@ -671,6 +709,7 @@ document.body.removeChild(downloadLink);
<li><code>https://www.douyin.com/discover?modal_id=作品ID</code></li>
<li><code>https://www.douyin.com/user/账号ID?modal_id=作品ID</code></li>
<li><code>https://www.douyin.com/search/关键词?modal_id=作品ID</code></li>
<li><code>https://www.douyin.com/channel/分区ID?modal_id=作品ID</code></li>
</ul>
<p>支持采集评论回复、评论表情、评论图片;必须设置 <code>storage_format</code> 参数才能正常使用。</p>
<p>储存名称格式:<code>作品123456789_评论数据</code></p>
Expand All @@ -689,6 +728,7 @@ document.body.removeChild(downloadLink);
<li><code>https://www.douyin.com/user/账号ID?modal_id=作品ID</code></li>
<li><code>https://www.douyin.com/search/关键词?modal_id=作品ID</code></li>
<li><code>https://www.douyin.com/collection/合集ID</code></li>
<li><code>https://www.douyin.com/channel/分区ID?modal_id=作品ID</code></li>
</ul>
<p>如果需要大批量采集合集作品,建议启用 <code>src/custom/function.py</code> 文件的 <code>suspend</code> 函数。</p>
<p>如果当前合集标题或合集标识不是有效的文件夹名称时,程序会提示用户输入临时的合集标识,以便程序继续处理合集。</p>
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
requests>=2.31.0
openpyxl>=3.1.2
Flask>=3.0.2
qrcode>=7.4.2
emoji>=2.10.1
rich>=13.7.1
lxml>=5.1.0
browser-cookie3>=0.19.1
aiosqlite>=0.20.0
aiohttp>=3.9.3
37 changes: 22 additions & 15 deletions src/DataAcquirer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
)
from src.custom import wait
from src.extract import Extractor
from src.tools import retry
from src.tools import PrivateRetry
from src.tools import timestamp

__all__ = [
Expand Down Expand Up @@ -172,7 +172,7 @@ def run(self, text: str) -> str:
return " ".join(self.get_url(i) for i in u)
return text

@retry
@PrivateRetry.retry
def get_url(self, url: str) -> str:
try:
response = request(
Expand Down Expand Up @@ -223,7 +223,10 @@ class Link:
)
live_link_share = compile(
r"\S*?https://webcast\.amemv\.com/douyin/webcast/reflow/\S+")

channel_link = compile(
r"\S*?https://www\.douyin\.com/channel/\d+?\?modal_id=\d{19}\S*?")
lv_detail_link = compile(
r"\S*?https://www\.douyin\.com/[a-z]+?/\d{19}\S*?")
# TikTok 链接
works_link_tiktok = compile(
r"\S*?https://www\.tiktok\.com/@\S+?/(?:video|photo)/(\d{19})\S*?") # 作品链接
Expand All @@ -248,15 +251,19 @@ def works(self, text: str) -> tuple[bool, list]:
for i in self.account_link.findall(urls)] if i]
search = self.works_search.findall(urls)
discover = self.works_discover.findall(urls)
return False, link + share + account + search + discover
channel = self.channel_link.findall(urls)
# detail = self.lv_detail_link.findall(urls)
return False, link + share + account + search + discover + channel

def mix(self, text: str) -> tuple:
urls = self.share.run(text)
share = self.works_share.findall(urls)
link = self.works_link.findall(urls)
search = self.works_search.findall(urls)
discover = self.works_discover.findall(urls)
if u := share + link + search + discover:
channel = self.channel_link.findall(urls)
# detail = self.lv_detail_link.findall(urls)
if u := share + link + search + discover + channel:
return False, u
link = self.mix_link.findall(urls)
share = self.mix_share.findall(urls)
Expand Down Expand Up @@ -350,7 +357,7 @@ def run(self) -> tuple[list[dict], date, date]:
self.favorite_mode()
return self.response, self.earliest, self.latest

@retry
@PrivateRetry.retry
def get_account_data(self, api: str):
if self.favorite:
params = {
Expand Down Expand Up @@ -456,7 +463,7 @@ def __init__(self, params: Parameter, item_id: str, tiktok: bool,
self.id = item_id
self.tiktok = tiktok

@retry
@PrivateRetry.retry
def run(self) -> dict:
if self.tiktok:
params = {
Expand Down Expand Up @@ -541,7 +548,7 @@ def run(self, extractor: Extractor, recorder, source=False) -> list[dict]:
source=source)))
return self.all_data

@retry
@PrivateRetry.retry
def get_comments_data(self, api: str, reply=""):
if reply:
params = {
Expand Down Expand Up @@ -636,7 +643,7 @@ def run(self) -> list:
# break # 调试代码
return self.response

@retry
@PrivateRetry.retry
def _get_mix_data(self):
params = {
"device_platform": "webapp",
Expand Down Expand Up @@ -730,7 +737,7 @@ def with_room_id(self) -> dict:
self.deal_url_params(params, 4)
return self.get_live_data(api, params, headers)

@retry
@PrivateRetry.retry
def get_live_data(
self,
api: str,
Expand All @@ -755,7 +762,7 @@ def __init__(self, params: Parameter, sec_user_id: str,
super().__init__(params, cookie)
self.sec_user_id = sec_user_id

@retry
@PrivateRetry.retry
def run(self) -> dict:
params = {
"device_platform": "webapp",
Expand Down Expand Up @@ -904,7 +911,7 @@ def _run_general(self, data: SimpleNamespace, type_: int, *args):
self.deal_url_params(params, 4 if self.cursor else 8)
self._get_search_data(data.api, params, "data", finished=True)

@retry
@PrivateRetry.retry
def _get_search_data(self, api: str, params: dict, key: str):
if not (
data := self.send_request(
Expand Down Expand Up @@ -960,7 +967,7 @@ def run(self):
self._get_board_data(i, j)
return self.time, self.response

@retry
@PrivateRetry.retry
def _get_board_data(self, index: int, data: SimpleNamespace):
params = {
"device_platform": "webapp",
Expand Down Expand Up @@ -1026,7 +1033,7 @@ def run(self):
self._get_owner_data()
return self.response

@retry
@PrivateRetry.retry
def _get_account_data(self):
params = self.params.copy()
self.deal_url_params(params)
Expand Down Expand Up @@ -1094,7 +1101,7 @@ def __init__(
"downlink": "10",
}

@retry
@PrivateRetry.retry
def run(self) -> dict:
self.deal_url_params(self.params)
form = {
Expand Down

0 comments on commit 36d1c07

Please sign in to comment.