更新项目代码

This commit is contained in:
JoeamAmier 2023-11-29 22:41:15 +08:00
parent b9dd05652d
commit 88cc09c371
9 changed files with 48 additions and 55 deletions

View File

@ -125,6 +125,20 @@ print(xhs.extract(video_demo, download=download))
<img src="static/获取Cookie示意图.png" alt="">
<h1>♥️ 支持项目</h1>
<p>如果 <b>XHS-Downloader</b> 对您有帮助,请考虑为它点个 <b>Star</b> ⭐,感谢您的支持!</p>
<table>
<thead>
<tr>
<th align="center">微信(WeChat)</th>
<th align="center">支付宝(Alipay)</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="./static/微信赞助二维码.png" alt="微信赞助二维码" height="200" width="200"></td>
<td align="center"><img src="./static/支付宝赞助二维码.png" alt="支付宝赞助二维码" height="200" width="200"></td>
</tr>
</tbody>
</table>
<p>如果您愿意,可以考虑提供资助为 <b>XHS-Downloader</b> 提供额外的支持!</p>
<h1>✉️ 联系作者</h1>
<ul>
<li>QQ: 2437596031</li>

11
main.py
View File

@ -1,5 +1,4 @@
from source import XHS
from source import XHSDownloader
def example():
@ -8,6 +7,9 @@ def example():
error_demo = "https://github.com/JoeanAmier/XHS_Downloader"
image_demo = "https://www.xiaohongshu.com/explore/63b275a30000000019020185"
video_demo = "https://www.xiaohongshu.com/explore/64edb460000000001f03cadc"
multiple_demo = (
"https://www.xiaohongshu.com/explore/63b275a30000000019020185 "
"https://www.xiaohongshu.com/explore/64edb460000000001f03cadc")
# 实例对象
path = "" # 作品下载储存根路径,默认值:当前路径
folder = "Download" # 作品下载文件夹名称自动创建默认值Download
@ -23,13 +25,14 @@ def example():
timeout=timeout,
chunk=chunk, ) # 使用自定义参数
# xhs = XHS() # 使用默认参数
download = True # 是否下载作品文件
download = False # 是否下载作品文件
# 返回作品详细信息,包括下载地址
print(xhs.extract(error_demo)) # 获取数据失败时返回空字典
print(xhs.extract(image_demo, download=download))
print(xhs.extract(video_demo, download=download))
print(xhs.extract(multiple_demo, download=download))
if __name__ == '__main__':
# example()
XHSDownloader().run()
example()
# XHSDownloader().run()

View File

@ -18,7 +18,7 @@ class Download:
folder: str,
headers: dict,
proxies=None,
chunk=256 * 1024, ):
chunk=1024 * 1024, ):
self.temp = root.joinpath("./temp")
self.root = self.__init_root(root, path, folder)
self.headers = self.__delete_cookie(headers)
@ -30,14 +30,12 @@ class Download:
self.chunk = chunk
def __init_root(self, root: Path, path: str, folder: str) -> Path:
if path and (r := Path(path)).exists():
if path and (r := Path(path)).is_dir():
root = r.joinpath(folder or "Download")
else:
root = root.joinpath(folder or "Download")
if not root.is_dir():
root.mkdir()
if not self.temp.is_dir():
self.temp.mkdir()
root.mkdir(exist_ok=True)
self.temp.mkdir(exist_ok=True)
return root
def run(self, urls: list, name: str, type_: int, log):

View File

@ -1,4 +1,3 @@
from requests import ReadTimeout
from requests import exceptions
from requests import get
@ -37,7 +36,7 @@ class Html:
exceptions.SSLError,
exceptions.ChunkedEncodingError,
exceptions.ConnectionError,
ReadTimeout,
exceptions.ReadTimeout,
):
print("获取网页源码失败,请尝试设置 Cookie 后重试!")
return ""

View File

@ -2,7 +2,7 @@ from json import dump
from json import load
from pathlib import Path
__all__ = ['Settings', 'Batch']
__all__ = ['Settings']
class Settings:
@ -13,7 +13,7 @@ class Settings:
"cookie": "",
"proxies": None,
"timeout": 10,
"chunk": 256 * 1024,
"chunk": 1024 * 1024,
}
def run(self):
@ -25,19 +25,9 @@ class Settings:
def create(self) -> dict:
with self.file.open("w", encoding="utf-8") as f:
dump(self.default, f, indent=2)
dump(self.default, f, indent=4)
return self.default
def update(self, data: dict):
with self.file.open("w", encoding="utf-8") as f:
dump(data, f, indent=2, ensure_ascii=False)
class Batch:
file = Path("../xhs.txt")
def read_txt(self) -> list:
if self.file.is_file():
with self.file.open("r") as f:
return [i.rstrip('\n') for i in f.readlines()]
return []
dump(data, f, indent=4, ensure_ascii=False)

View File

@ -18,7 +18,6 @@ from .Download import Download
from .Explore import Explore
from .Html import Html
from .Image import Image
from .Settings import Batch
from .Settings import Settings
from .Video import Video
@ -45,7 +44,7 @@ class XHS:
cookie=None,
proxies=None,
timeout=10,
chunk=256 * 1024,
chunk=1024 * 1024,
):
self.__update_cookie(cookie)
self.html = Html(self.headers, proxies, timeout)
@ -72,16 +71,14 @@ class XHS:
self.download.run(url, self.__naming_rules(container), 0, log)
container["下载地址"] = url
def extract(self, url: str, download=False, log=None) -> dict:
def extract(self, url: str, download=False, log=None) -> dict | list[dict]:
if not self.__check(url):
print(f"无效的作品链接: {url}")
return {}
html = self.html.get_html(url)
if not html:
return {}
data = self.explore.run(html)
if not data:
print(f"获取作品数据失败: {url}")
return {}
if data["作品类型"] == "视频":
self.__get_video(data, html, download, log)
@ -105,21 +102,20 @@ class XHS:
class XHSDownloader(App):
VERSION = 1.6
Beta = True
CSS_PATH = Path(__file__).resolve().parent.parent.joinpath(
ROOT = Path(__file__).resolve().parent.parent
CSS_PATH = ROOT.joinpath(
"static/XHS-Downloader.tcss")
BINDINGS = [
Binding(key="q", action="quit", description="退出程序"),
("d", "toggle_dark", "切换主题"),
]
APP = XHS(**Settings().run())
Batch = Batch()
def compose(self) -> ComposeResult:
yield Header()
yield ScrollableContainer(Label("请输入小红书图文/视频作品链接"),
yield ScrollableContainer(Label("请输入小红书图文/视频作品链接(多个链接使用空格分隔)"),
Input(placeholder="URL"),
HorizontalScroll(Button("下载无水印图片/视频", id="solo"),
Button("读取 xhs.txt 文件并批量下载作品", id="batch"),
HorizontalScroll(Button("下载无水印图片/视频", id="deal"),
Button("读取剪贴板", id="paste"),
Button("清空输入框", id="reset"), ))
yield Log(auto_scroll=True)
@ -129,26 +125,22 @@ class XHSDownloader(App):
self.title = f"小红书作品采集工具 V{self.VERSION}{" Beta" if self.Beta else ""}"
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "solo":
self.solo()
elif event.button.id == "batch":
self.batch()
if event.button.id == "deal":
self.deal()
elif event.button.id == "reset":
self.query_one(Input).value = ""
elif event.button.id == "paste":
self.query_one(Input).value = paste()
def solo(self):
def deal(self):
url = self.query_one(Input).value
log = self.query_one(Log)
log.write_line(f"当前作品链接: {url}")
self.APP.extract(url, True, log)
def batch(self):
urls = self.Batch.read_txt()
log = self.query_one(Log)
if not urls:
log.write_line("未检测到 xhs.txt 文件 或者 该文件为空!")
for url in urls:
log.write_line(f"当前作品链接: {url}")
if not url:
log.write_line("未输入任何作品链接!")
else:
self.APP.extract(url, True, log)
self.query_one(Input).value = ""
class FakeGUI:
pass

View File

@ -10,10 +10,7 @@ Button {
margin: 1 1;
text-style: bold;
}
Button#solo {
tint: green 35%;
}
Button#batch {
Button#deal {
tint: green 35%;
}
Button#paste {

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB