diff --git a/README.md b/README.md index 3f3bfaa..4fc3e8a 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ multiple_demo = f"{image_demo} {video_demo}" path = "" # 作品数据/文件保存根路径,默认值:项目根路径 folder_name = "Download" # 作品文件储存文件夹名称(自动创建),默认值:Download user_agent = "" # 请求头 User-Agent +cookie = "" # 小红书网页版 Cookie,无需登录 proxy = "" # 网络代理 timeout = 5 # 网络请求超时限制,单位:秒,默认值:10 chunk = 1024 * 1024 # 下载文件时,每次从服务器获取的数据块大小,单位:字节 @@ -64,6 +65,7 @@ max_retry = 2 # 请求数据失败时,重试的最大次数,单位:秒, async with XHS(path=path, folder_name=folder_name, user_agent=user_agent, + cookie=cookie, proxy=proxy, timeout=timeout, chunk=chunk, @@ -106,6 +108,12 @@ async with XHS(path=path, 默认 UA +cookie +str +小红书网页版 Cookie,无需登录 +默认 Cookie + + proxy str 设置代理 @@ -131,6 +139,16 @@ async with XHS(path=path, +

🌐 Cookie

+
    +
  1. 打开浏览器(可选无痕模式启动),访问小红书任意网页
  2. +
  3. F12 打开开发人员工具
  4. +
  5. 选择 控制台 选项卡
  6. +
  7. 输入 document.cookie 后回车确认
  8. +
  9. 输出内容即为所需 Cookie
  10. +
+
+

♥️ 支持项目

如果 XHS-Downloader 对您有帮助,请考虑为它点个 Star ⭐,感谢您的支持!

diff --git a/main.py b/main.py index d73056c..638e454 100644 --- a/main.py +++ b/main.py @@ -15,6 +15,7 @@ async def example(): path = "" # 作品数据/文件保存根路径,默认值:项目根路径 folder_name = "Download" # 作品文件储存文件夹名称(自动创建),默认值:Download user_agent = "" # 请求头 User-Agent + cookie = "" # 小红书网页版 Cookie,无需登录 proxy = "" # 网络代理 timeout = 5 # 网络请求超时限制,单位:秒,默认值:10 chunk = 1024 * 1024 # 下载文件时,每次从服务器获取的数据块大小,单位:字节 @@ -24,6 +25,7 @@ async def example(): async with XHS(path=path, folder_name=folder_name, user_agent=user_agent, + cookie=cookie, proxy=proxy, timeout=timeout, chunk=chunk, diff --git a/source/Downloader.py b/source/Downloader.py index 0906eac..6a1f6a8 100644 --- a/source/Downloader.py +++ b/source/Downloader.py @@ -29,7 +29,7 @@ class Download: self.proxy = proxy self.chunk = chunk self.session = ClientSession( - headers=manager.headers, + headers={"User-Agent": manager.headers["User-Agent"]}, timeout=ClientTimeout(connect=timeout)) self.retry = retry_ @@ -60,16 +60,16 @@ class Download: return True try: async with self.session.get(url, proxy=self.proxy) as response: - self.__create_progress( - bar, int( - response.headers.get( - 'content-length', 0)) or None) + # self.__create_progress( + # bar, int( + # response.headers.get( + # 'content-length', 0)) or None) with temp.open("wb") as f: async for chunk in response.content.iter_chunked(self.chunk): f.write(chunk) - self.__update_progress(bar, len(chunk)) + # self.__update_progress(bar, len(chunk)) self.manager.move(temp, file) - self.__create_progress(bar, None) + # self.__create_progress(bar, None) self.rich_log(log, f"{name} 下载成功") return True except ( @@ -77,19 +77,19 @@ class Download: ServerDisconnectedError, ): self.manager.delete(temp) - self.__create_progress(bar, None) + # self.__create_progress(bar, None) self.rich_log(log, f"{name} 下载失败", "bright_red") return False - @staticmethod - def __create_progress(bar, total: int | None): - if bar: - bar.update(total=total) + # @staticmethod + # def __create_progress(bar, total: int | None): + # if bar: + # bar.update(total=total) - @staticmethod - def __update_progress(bar, advance: int): - if bar: - bar.advance(advance) + # @staticmethod + # def __update_progress(bar, advance: int): + # if bar: + # bar.advance(advance) @staticmethod def rich_log(log, text, style="bright_green"): diff --git a/source/Manager.py b/source/Manager.py index a3aa933..dc1fe0f 100644 --- a/source/Manager.py +++ b/source/Manager.py @@ -6,11 +6,18 @@ __all__ = ["Manager"] class Manager: - def __init__(self, root: Path, ua: str, retry: int): + def __init__(self, root: Path, ua: str, cookie: str, retry: int): self.temp = root.joinpath("./temp") self.headers = { "User-Agent": ua or "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0", } + "Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0", + "Cookie": cookie or "abRequestId=54c534bb-a2c6-558f-8e03-5b4c5c45635c; xsecappid=xhs-pc-web; a1=18c286a400" + "4jy56qvzejvp631col0hd3032h4zjez50000106381; webId=779c977da3a15b5623015be94bdcc9e9; g" + "id=yYSJYK0qDW8KyYSJYK048quV84Vv2KAhudVhJduUKqySlx2818xfq4888y8KqYy8y2y2f8Jy; web_sess" + "ion=030037a259ce5f15c8d560dc12224a9fdc2ed1; webBuild=3.19.4; websectiga=984412fef754c" + "018e472127b8effd174be8a5d51061c991aadd200c69a2801d6; sec_poison_id=3dd48845-d604-4535" + "-bcc2-a859e97518bf; unread={%22ub%22:%22655eb3d60000000032033955%22%2C%22ue%22:%22656" + "e9ef2000000003801ff3d%22%2C%22uc%22:29}; cache_feeds=[]"} self.retry = retry @staticmethod diff --git a/source/Settings.py b/source/Settings.py index c68691f..b991e6c 100644 --- a/source/Settings.py +++ b/source/Settings.py @@ -10,6 +10,7 @@ class Settings: "path": "", "folder_name": "Download", "user_agent": "", + "cookie": "", "proxy": "", "timeout": 10, "chunk": 1024 * 1024, diff --git a/source/Video.py b/source/Video.py index 949d34e..996a8db 100644 --- a/source/Video.py +++ b/source/Video.py @@ -6,7 +6,7 @@ __all__ = ['Video'] class Video: - VIDEO_TOKEN = compile(r'"originVideoKey":"(\S+?\\u002F\S+?)"') + VIDEO_TOKEN = compile(r'"originVideoKey":"(\S+?)"') def get_video_link(self, html: str) -> list: return [Html.format_url(f"https://sns-video-hw.xhscdn.com/{ diff --git a/source/__init__.py b/source/__init__.py index a92b7b2..5d636d2 100644 --- a/source/__init__.py +++ b/source/__init__.py @@ -6,7 +6,7 @@ from rich.text import Text from textual.app import App from textual.app import ComposeResult from textual.binding import Binding -from textual.containers import Center +# from textual.containers import Center from textual.containers import HorizontalScroll from textual.containers import ScrollableContainer from textual.widgets import Button @@ -28,8 +28,8 @@ from .Video import Video __all__ = ['XHS', 'XHSDownloader'] RELEASES = "https://github.com/JoeanAmier/XHS-Downloader/releases/latest" -VERSION = 1.6 -BETA = False +VERSION = 1.7 +BETA = True ROOT = Path(__file__).resolve().parent.parent @@ -49,13 +49,14 @@ class XHS: path="", folder_name="Download", user_agent: str = None, + cookie: str = None, proxy: str = "", timeout=10, chunk=1024 * 1024, max_retry=5, **kwargs, ): - self.manager = Manager(ROOT, user_agent, max_retry) + self.manager = Manager(ROOT, user_agent, cookie, max_retry) self.html = Html( self.manager.headers, proxy, @@ -175,10 +176,10 @@ class XHSDownloader(App): HorizontalScroll(Button("下载无水印图片/视频", id="deal"), Button("读取剪贴板", id="paste"), Button("清空输入框", id="reset"), ), - Label(Text("程序状态", style="b bright_blue")), + # Label(Text("程序状态", style="b bright_blue")), ) - with Center(): - yield ProgressBar(total=None) + # with Center(): + # yield ProgressBar(total=None) yield RichLog(markup=True) yield Footer() diff --git a/static/XHS-Downloader.ico b/static/XHS-Downloader.ico index f81573f..97cff2d 100644 Binary files a/static/XHS-Downloader.ico and b/static/XHS-Downloader.ico differ diff --git a/static/XHS-Downloader.jpg b/static/XHS-Downloader.jpg index edfabad..8df75a1 100644 Binary files a/static/XHS-Downloader.jpg and b/static/XHS-Downloader.jpg differ diff --git a/static/XHS-Downloader.png b/static/XHS-Downloader.png index a0fd961..d4285a6 100644 Binary files a/static/XHS-Downloader.png and b/static/XHS-Downloader.png differ diff --git a/static/微信赞助二维码.png b/static/微信赞助二维码.png index ab6a46e..e167484 100644 Binary files a/static/微信赞助二维码.png and b/static/微信赞助二维码.png differ diff --git a/static/支付宝赞助二维码.png b/static/支付宝赞助二维码.png index 18676ab..755ec12 100644 Binary files a/static/支付宝赞助二维码.png and b/static/支付宝赞助二维码.png differ diff --git a/static/获取Cookie示意图.png b/static/获取Cookie示意图.png new file mode 100644 index 0000000..13888ae Binary files /dev/null and b/static/获取Cookie示意图.png differ