├── .gitattributes
├── .gitignore
├── .idea
├── Kuaishou_bot.iml
├── encodings.xml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── README.md
├── cookies.txt
├── kuaishou_chrome.py
└── test
├── demo.py
├── kuaishou.py
└── ss.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # celery beat schedule file
95 | celerybeat-schedule
96 |
97 | # SageMath parsed files
98 | *.sage.py
99 |
100 | # Environments
101 | .env
102 | .venv
103 | env/
104 | venv/
105 | ENV/
106 | env.bak/
107 | venv.bak/
108 |
109 | # Spyder project settings
110 | .spyderproject
111 | .spyproject
112 |
113 | # Rope project settings
114 | .ropeproject
115 |
116 | # mkdocs documentation
117 | /site
118 |
119 | # mypy
120 | .mypy_cache/
121 | .dmypy.json
122 | dmypy.json
123 |
124 | # Pyre type checker
125 | .pyre/
126 |
127 |
128 | /Google Chrome/
129 | /download/
--------------------------------------------------------------------------------
/.idea/Kuaishou_bot.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
100 |
101 |
102 |
103 | video
104 | fileNum
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 | 1587349779100
290 |
291 |
292 | 1587349779100
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 快手视频下载小助手 V 0.12
2 | ### 只需电脑即可,selenium项目
3 |
4 | * 项目就在kuaishou_chrome.py ,最后使用pyinstaller打包exe,大约79M
5 | * V0.1 使用同时电脑和手机自动化项目
6 | * V0.11 使用selenium, https://ww.lanzous.com/ic5kdte
7 | * V0.12 修复bug,完善流程 https://ww.lanzous.com/ic675uf
8 | * V0.13 修复bug,增加使用快手号下载 https://ww.lanzous.com/ic69bkd
9 |
10 | >项目结构源码(因为浏览器太大,上传不了github): https://ww.lanzous.com/ic69ibg
11 |
12 |
13 | ### 项目如何打包
14 | > 在output 文件夹中有发布的范本,例如打算发布版本V0.13
15 | > 蓝奏云:
16 |
17 | 1. 在output中复制一份重命名 kuaishou_v0.13
18 | 2. 打开命令行,切换到你的环境
19 | 3. cd D:\python_project\Kuaishou_bot\output\kuaishou_v0.13
20 | 4. 压缩打包:pyinstaller -F -i f.ico D:\python_project\Kuaishou_bot\kuaishou_chrome.py
21 | 5. dist文件夹中是解压出的exe
22 | > 说明:Google Chrome是一个绿色版浏览器
23 |
24 |
--------------------------------------------------------------------------------
/cookies.txt:
--------------------------------------------------------------------------------
1 | [{"domain": "live.kuaishou.com", "expiry": 2219103593, "httpOnly": true, "name": "kuaishou.live.bfb1s", "path": "/", "secure": true, "value": "3e261140b0cf7444a0ba411c6f227d88"}, {"domain": ".kuaishou.com", "expiry": 1619919593.30184, "httpOnly": true, "name": "clientid", "path": "/", "secure": false, "value": "3"}, {"domain": "live.kuaishou.com", "expiry": 1588469931.221201, "httpOnly": true, "name": "userId", "path": "/", "secure": true, "value": "1886888275"}, {"domain": ".kuaishou.com", "expiry": 1619919593, "httpOnly": false, "name": "did", "path": "/", "secure": false, "value": "web_6ba1fece692fb4e3ebb2a32bac89a628"}, {"domain": "live.kuaishou.com", "expiry": 1588469931.22117, "httpOnly": true, "name": "kuaishou.live.web_ph", "path": "/", "secure": true, "value": "dc241ff574f89f61e2814b9a062e07a19350"}, {"domain": ".kuaishou.com", "expiry": 1619919593.301922, "httpOnly": true, "name": "client_key", "path": "/", "secure": false, "value": "65890b29"}, {"domain": "live.kuaishou.com", "expiry": 1588469931.221083, "httpOnly": true, "name": "kuaishou.live.web_st", "path": "/", "secure": true, "value": "ChRrdWFpc2hvdS5saXZlLndlYi5zdBKgAUu_T9W9JXiyqmwMhJrCgbgpkbNTzhvkT_gMehhi2BPhWbZyCqbe4LfmpbYlREUxy0EmC1U5CA2kG-0r9Rm7PBdzPOLWeZj2zJcNtottOPNv6HpTo_WIqQ-THTmrEvjMs2nkDbmpgDsiC4ZqKkhnpnTxAWvBK4YsTT4HmVF3a6JGdO2VqnZBNpZrZpgBctQUa-CkpIyzuEa_XRfvH6R2H8saEqoO82cRG00nqSoI30_iGx2JSCIggImyl7xGU1atd9GAn1DQ5RyvKyP-599Ib2K24O_wdngoBTAB"}]
--------------------------------------------------------------------------------
/kuaishou_chrome.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import pycurl
4 | import queue
5 | import re
6 | import sys
7 | import time
8 | import traceback
9 | from threading import Thread
10 | from urllib.parse import urlparse
11 | import certifi
12 | import requests
13 | from bs4 import BeautifulSoup
14 | from selenium.common.exceptions import TimeoutException
15 | from selenium.webdriver.support import expected_conditions as EC
16 | from selenium import webdriver
17 | from selenium.webdriver.common.by import By
18 | from selenium.webdriver.support.wait import WebDriverWait
19 |
20 |
21 | def read_cookies(driver):
22 | with open("cookies.txt", "r") as fp:
23 | cookies = json.load(fp)
24 | for cookie in cookies:
25 | driver.add_cookie(cookie)
26 |
27 | def write_cookie(driver):
28 | cookies = driver.get_cookies()
29 | with open("cookies.txt", "w") as fp:
30 | json.dump(cookies, fp)
31 |
32 | def fileNum(path):
33 | fileNum=0
34 | for lists in os.listdir(path):
35 | sub_path = os.path.join(path, lists)
36 | if os.path.isfile(sub_path):
37 | fileNum = fileNum + 1 # 统计文件数量
38 | return fileNum
39 |
40 | def downloadFile(name, video_url):
41 | with open("download/" + name, 'wb') as f:
42 | c = pycurl.Curl()
43 | c.setopt(pycurl.USERAGENT,
44 | "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1") # 配置请求HTTP头的User-Agent
45 | c.setopt(c.URL, video_url)
46 | c.setopt(c.CAINFO, certifi.where())
47 | c.setopt(c.WRITEDATA, f)
48 | c.perform()
49 | c.close()
50 |
51 | def isSafePresent(browser,css):
52 | flag = True
53 | try:
54 | browser.find_element_by_css_selector(css)
55 | return flag
56 |
57 | except:
58 | flag = False
59 | return flag
60 |
61 | def auth(url):
62 | chrome_options2 = webdriver.ChromeOptions()
63 | chrome_options2.add_argument("--mute-audio") # 静音
64 | chrome_options2.add_experimental_option('excludeSwitches', ['enable-logging'])
65 | chrome_options2.binary_location = os.path.dirname(sys.argv[0]) + "\Google Chrome\chrome.exe"
66 | browser2 = webdriver.Chrome(executable_path=os.path.dirname(sys.argv[0]) + "\Google Chrome\chromedriver.exe",
67 | options=chrome_options2)
68 | browser2.get("https://www.baidu.com/")
69 | read_cookies(browser2)
70 | browser2.get(url)
71 | input("是否完成认证(y/n)")
72 | write_cookie(browser2)
73 | browser2.quit()
74 |
75 | def task():
76 | time.sleep(2)
77 | flag=1
78 | mflag=0
79 | while flag:
80 | if not q.empty():
81 | mydict = q.get()
82 | try:
83 | file_name=mydict.get("file_name")
84 | if file_name=="重复下载":
85 | time.sleep(1)
86 | print("\033[1;93m下载视频线程:" + file_name + "" + "\033[0m")
87 | else:
88 | video_url=mydict.get("video_url")
89 | print("\033[1;93m下载视频线程:" + file_name + ":开始下载" + "\033[0m")
90 | downloadFile(file_name, video_url)
91 | print("\033[1;93m下载视频线程:" + file_name + ":下载完成" + "\033[0m")
92 | except:
93 | print(traceback.format_exc())
94 | print("下载视频线程:" + mydict + "下载失败")
95 | mflag=0
96 |
97 | else:
98 | print("\033[1;93m下载视频线程:当前下载队列为空" + "\033[0m")
99 | if mflag==6:
100 | flag=0
101 | mflag=mflag+1
102 | time.sleep(10)
103 | os.system("pause")
104 |
105 |
106 | def open_brower(browser,ID):
107 | browser.get("https://www.baidu.com/")
108 | url = "https://live.kuaishou.com/profile/" + ID
109 | read_cookies(browser)
110 | browser.get(url)
111 | print("检测是否有安全认证弹框?")
112 | time.sleep(3)
113 | # body > iframe
114 | if isSafePresent(browser, "body > iframe"):
115 | print("存在认证")
116 | print("打开浏览器中,请在打开的浏览器中完成安全验证,完成验证不要关闭浏览器")
117 | auth(url)
118 | open_brower(browser,ID)
119 | else:
120 | print("没有安全认证")
121 |
122 | def get_video(browser,wait,alreay_li,num):
123 | for i in range(round(num / 10)):
124 | li_list = browser.find_elements_by_css_selector(
125 | "#app > div.profile > div.load-more.profile-content > div:nth-child(3) > ul > li")
126 | for li in li_list:
127 | li_text = li.text
128 | # print(li_text)
129 | if li_text not in alreay_li:
130 | alreay_li.append(li_text)
131 | raw_name = li_text.strip().replace("\n", "-")
132 | raw_file_name = raw_name.replace(" ", "")
133 | raw_file_name = re.sub('[\/:*?"<>|]', '-', raw_file_name)
134 | if len(raw_file_name) > 50:
135 | raw_file_name = raw_file_name[:49]
136 | else:
137 | raw_file_name = raw_file_name
138 | myfileNum = fileNum("download")
139 | k = "%03d" % (myfileNum + 1)
140 | file_name = str(k) + raw_file_name + ".mp4"
141 | browser.execute_script("arguments[0].scrollIntoView();", li)
142 | time.sleep(1)
143 | browser.execute_script('arguments[0].scrollIntoView(false);', li)
144 | li.click()
145 | time.sleep(1)
146 | try:
147 | element = WebDriverWait(browser, 2).until(
148 | EC.visibility_of_element_located((By.CSS_SELECTOR, "body > div.pl-modal.alert > div"))
149 | )
150 | print("出现注意弹框")
151 | get_video(browser,wait,num,alreay_li)
152 | except TimeoutException:
153 | print("没有出现弹框")
154 | finally:
155 | element = wait.until(EC.presence_of_element_located((By.TAG_NAME, 'video')))
156 | element1 = wait.until(
157 | EC.presence_of_element_located(
158 | (By.CSS_SELECTOR, '#app > div.profile > div.photo-preview > div.close')))
159 |
160 | video = browser.find_element_by_tag_name("video")
161 | video_url = video.get_attribute("src")
162 | browser.find_element_by_css_selector("#app > div.profile > div.photo-preview > div.close").click()
163 | print("\033[1;94m获取链接:"+ str({"file_name":file_name,"video_url":video_url})+ "\033[0m")
164 | q.put({"file_name":file_name,"video_url":video_url})
165 | else:
166 | q.put({"file_name":"重复下载","video_url":""})
167 |
168 |
169 | def kuaishou():
170 | kuaishou_flag=input("作者是否有快手号(y/n):")
171 | if kuaishou_flag=="y":
172 | ID = input("输入作者快手号:")
173 | else:
174 | line = input("输入作者分享链接:")
175 | pattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')
176 | url_list = re.findall(pattern, line)
177 | html_url = url_list[0]
178 | # print(html_url)
179 | header = {
180 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Mobile Safari/537.36'
181 | }
182 | r = requests.get(html_url, headers=header)
183 | reditList = r.history
184 | last_url = reditList[len(reditList) - 1].headers["location"]
185 | print("获取链接:"+last_url)
186 | path = urlparse(last_url).path
187 | ID = path.split("/")[3]
188 | print("获取ID:"+ID)
189 | chrome_options = webdriver.ChromeOptions()
190 | chrome_options.add_argument('--headless')
191 | chrome_options.add_argument('--disable-gpu')
192 | chrome_options.add_argument("--mute-audio") # 静音
193 | chrome_options.add_experimental_option('excludeSwitches', ['enable-logging'])
194 | chrome_options.binary_location = os.path.dirname(sys.argv[0]) + "\Google Chrome\chrome.exe"
195 | browser = webdriver.Chrome(executable_path=os.path.dirname(sys.argv[0]) + "\Google Chrome\chromedriver.exe",
196 | options=chrome_options)
197 | wait = WebDriverWait(browser, 10)
198 | open_brower(browser,ID)
199 |
200 | time.sleep(1)
201 | element1 = wait.until(
202 | EC.visibility_of_element_located(
203 | (By.CSS_SELECTOR, '#app > div.profile > div.load-more.profile-content > div.tab > span.active')))
204 | raw_num = browser.find_element_by_css_selector(
205 | "#app > div.profile > div.load-more.profile-content > div.tab > span.active").text.strip()
206 | re_num = re.match(".*?(\d+).*?", raw_num, re.S)
207 | num = int(re_num.group(1))
208 | print("作者的作品数:" + str(num))
209 | alreay_li = []
210 | p = Thread(target=task)
211 | p.start()
212 | get_video(browser,wait,alreay_li,num)
213 |
214 |
215 | # body > div.pl-modal.alert > div
216 |
217 | if __name__ == "__main__":
218 | q = queue.Queue()
219 |
220 | if not os.path.exists("download"):
221 | os.mkdir("download")
222 |
223 | print('''
224 | ************************************************************************************************************************
225 | 快手视频下载小助手 V 0.13
226 | Github地址:https://github.com/Gaoyongxian666/Kuaishou_bot
227 | QQ群:1056916780 下载目录:解压目录/download 更新:2020-5-2
228 | 功能:批量下载作品
229 | 说明:有快手号的,输入快手号。不显示快手号的,或者显示用户ID的:使用作者分享链接的方式。
230 | 允许软件网络访问,登陆是必须操作,为了获取cookie,有了cookie以后不用频繁登陆。
231 | 进行登陆,安全认证使用的压缩包里面的浏览器与外部浏览器无关,程序调起浏览器,主程序会处于阻塞状态。
232 | 登陆完成,安全认证完成不要关闭浏览器,一定要回到主程序里面进行输入,从阻塞状态变成执行状态。
233 | 程序打开的浏览器页面不要自己关闭,主程序里面有提示,按照操作完成。
234 | ************************************************************************************************************************''')
235 |
236 |
237 |
238 | cookie=input("是否完成过登陆(y/n):")
239 | if cookie!="y":
240 | print("\033[1;92m网页登陆:打开浏览器中,允许软件网络访问"+ "\033[0m")
241 | print("\033[1;92m网页登陆:请在浏览器中完成登陆,登陆后不要关闭浏览器,记得回到主程序输入"+ "\033[0m")
242 |
243 | chrome_options1 = webdriver.ChromeOptions()
244 | chrome_options1.binary_location = os.path.dirname(sys.argv[0]) + "\Google Chrome\chrome.exe"
245 | browser = webdriver.Chrome(executable_path=os.path.dirname(sys.argv[0]) + "\Google Chrome\chromedriver.exe",
246 | options=chrome_options1)
247 | browser.get("https://live.kuaishou.com/")
248 | print("************************************************************************************************************************")
249 |
250 | input("\033[1;92m网页登陆:等待完成页面登陆(y/n):"+ "\033[0m")
251 | print("\033[1;92m网页登陆:开始写入cookie"+ "\033[0m")
252 | write_cookie(browser)
253 | print("\033[1;92m网页登陆:写入cookie完成"+ "\033[0m")
254 | browser.quit()
255 | print("************************************************************************************************************************")
256 | kuaishou()
257 |
258 | else:
259 | kuaishou()
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
--------------------------------------------------------------------------------
/test/demo.py:
--------------------------------------------------------------------------------
1 | # import os
2 | # import pycurl
3 | # import random
4 | # import re
5 | #
6 | # import certifi
7 | # import requests
8 | # from bs4 import BeautifulSoup
9 | # from selenium import webdriver
10 | #
11 | #
12 | # # url="https://v.kuaishou.com/2mGpmP"
13 | # # chrome_options = webdriver.ChromeOptions()
14 | # # chrome_options.add_argument('--headless')
15 | # # chrome_options.add_argument('--disable-gpu')
16 | # # chrome_options.binary_location = r"D:\python_project\Kuaishou_bot\Google Chrome\chrome.exe"
17 | # #
18 | # # browser = webdriver.Chrome(executable_path=r"D:\python_project\tv\chromedriver.exe",options=chrome_options)
19 | # # browser.set_page_load_timeout(10) # 设置页面加载超时
20 | # #
21 | # # try:
22 | # # browser.get(url)
23 | # # except:
24 | # # print("超时了,强制停止刷新")
25 | # # finally:
26 | # # html=browser.page_source
27 | # # soup = BeautifulSoup(html, "lxml")
28 | # # video_url=soup.video["src"]
29 | # # print(video_url)
30 | # # raw_name="xx"
31 | # # raw_file_name = raw_name.replace(" ", "")
32 | # # raw_file_name = re.sub('[\/:*?"<>|]', '-', raw_file_name)
33 | # # file_name=raw_file_name+".mp4"
34 | # # with open("download/"+file_name, 'wb') as f:
35 | # # c = pycurl.Curl()
36 | # # c.setopt(pycurl.USERAGENT,
37 | # # "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1") # 配置请求HTTP头的User-Agent
38 | # # c.setopt(c.URL, video_url)
39 | # # c.setopt(c.CAINFO, certifi.where())
40 | # # c.setopt(c.WRITEDATA, f)
41 | # # c.perform()
42 | # # c.close()
43 | # # print(html)
44 | # # for j in range(22):
45 | # # k = "%03d" % 1
46 | # # print(k)
47 | # #
48 | # # browser.close()
49 | #
50 | # totalSize = 0
51 | # fileNum = 0
52 | # dirNum = 0
53 | #
54 | #
55 | # def visitDir(path):
56 | # global totalSize
57 | # global fileNum
58 | # global dirNum
59 | # for lists in os.listdir(path):
60 | # sub_path = os.path.join(path, lists)
61 | # if os.path.isfile(sub_path):
62 | # fileNum = fileNum + 1 # 统计文件数量
63 | # totalSize = totalSize + os.path.getsize(sub_path) # 文件总大小
64 | # elif os.path.isdir(sub_path):
65 | # dirNum = dirNum + 1 # 统计文件夹数量
66 | # visitDir(sub_path) # 递归遍历子文件夹
67 | #
68 | # visitDir("download")
69 | # print(fileNum)
70 |
71 | for j in range(22):
72 | k = "%03d" % j
73 | print(k)
74 | print("\033[1;94m网页登陆:请在浏览器中完成登陆,登陆后不要关闭浏览器,记得回到主程序输入" +str({"file_name":1,"video_url":2})+ "\033[0m")
75 |
--------------------------------------------------------------------------------
/test/kuaishou.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pycurl
3 | import queue
4 | import sys
5 | from threading import Thread
6 | import certifi
7 | import uiautomator2 as u2
8 | import random
9 | import re
10 | from bs4 import BeautifulSoup
11 | import requests
12 | import time
13 |
14 | from selenium import webdriver
15 |
16 |
17 |
18 | def fileNum(path):
19 | fileNum=0
20 | for lists in os.listdir(path):
21 | sub_path = os.path.join(path, lists)
22 | if os.path.isfile(sub_path):
23 | fileNum = fileNum + 1 # 统计文件数量
24 | return fileNum
25 |
26 |
27 |
28 | def task():
29 | chrome_options = webdriver.ChromeOptions()
30 | chrome_options.add_argument('--headless')
31 | chrome_options.add_argument('--disable-gpu')
32 | chrome_options.add_experimental_option('excludeSwitches', ['enable-logging'])
33 |
34 | chrome_options.binary_location = os.path.dirname(sys.argv[0]) + "\Google Chrome\chrome.exe"
35 | browser = webdriver.Chrome(executable_path=os.path.dirname(sys.argv[0]) + "\Google Chrome\chromedriver.exe",
36 | options=chrome_options)
37 | browser.set_page_load_timeout(10) # 设置页面加载超时
38 | browser.get("https://www.baidu.com/")
39 | time.sleep(2)
40 | flag = 1
41 | mflag = 0
42 | while flag:
43 | if not q.empty():
44 | line = q.get()
45 | name_list=re.match(pattern2, line)
46 | name=name_list.group(1)
47 | url_list = re.findall(pattern, line)
48 | html_url = url_list[0]
49 | try:
50 | url_list = re.findall(pattern, line)
51 | html_url = url_list[0]
52 | try:
53 | browser.get(html_url)
54 | except:
55 | print("超时了,强制停止刷新")
56 | finally:
57 | html = browser.page_source
58 | soup = BeautifulSoup(html, "lxml")
59 | video_url = soup.video["src"]
60 | raw_name = name
61 | raw_file_name = raw_name.replace(" ", "")
62 | raw_file_name = re.sub('[\/:*?"<>|]', '-', raw_file_name)
63 | myfileNum=fileNum("download")
64 | k="%03d" % (myfileNum+1)
65 | file_name = str(k)+raw_file_name + ".mp4"
66 | with open("download/" + file_name, 'wb') as f:
67 | c = pycurl.Curl()
68 | c.setopt(pycurl.USERAGENT,
69 | "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1") # 配置请求HTTP头的User-Agent
70 | c.setopt(c.URL, video_url)
71 | c.setopt(c.CAINFO, certifi.where())
72 | c.setopt(c.WRITEDATA, f)
73 | c.perform()
74 | c.close()
75 | print("\033[1;93m下载视频线程:" + file_name + ":下载完成" + "\033[0m")
76 | except:
77 | print("下载视频线程:" + line + "下载失败")
78 | mflag = 0
79 |
80 | else:
81 | print("\033[1;93m下载视频线程:当前下载队列为空" + "\033[0m")
82 | if mflag == 1:
83 | flag = 0
84 | mflag = mflag + 1
85 | time.sleep(5)
86 | browser.close()
87 | os.system("pause")
88 |
89 |
90 |
91 | if __name__ == "__main__":
92 | print("设置ADB环境变量中。。。。")
93 | work_dir = os.path.dirname(sys.argv[0])
94 | # print(work_dir)
95 | os.chdir(work_dir)
96 | line = 'adb.exe devices'
97 | # print(line)
98 | os.system(line)
99 | q = queue.Queue()
100 | pattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')
101 | pattern2 = re.compile(r'(.*?)https.*')
102 |
103 | header_list = [
104 | # 遨游
105 | {"user-agent": "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)"},
106 | # 火狐
107 | {"user-agent": "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"},
108 | # 谷歌
109 | {
110 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"}
111 | ]
112 |
113 | if not os.path.exists("download"):
114 | os.mkdir("download")
115 |
116 | print('''
117 | ************************************************************************************************************************
118 | 快手视频下载小助手 V 0.1
119 | Github地址:https://github.com/Gaoyongxian666/Kuaishou_bot
120 | 公众号:我的光印象 QQ群:1056916780 下载目录:解压目录/download
121 | 功能:批量下载作品,本地下载限制,不能下载长图类型的短视频
122 | 特点:因为是模拟手机操作,本软件可以一直使用,除非你进行了APP升级。
123 | 说明:本软件基于开源项目uiautomator2项目,所以本项目也是开源的,自己也可进行更改,项目很简单。
124 | 注意:快手app版本必须是最新版本 V7.3.10.13314 更新时间:2020-4-20
125 | 在输入下载视频个数前,一定要做好三步:
126 | 1.打开调试 USB计算机连接选择传输文件 。。。
127 | 2.安装两个APP。。。
128 | 3.快手勾选全屏模式,打开第一个要下载的视频(可以暂停)
129 | 4.最后输入要下载的视频个数
130 |
131 | 使用方法:
132 | 1.初始化:手机打开调试模式,在首次运行本软件出现弹框点击一直允许,USB计算机连接选择传输文件
133 | 2.首次运行会弹出需要安装2个APP,点击安装,这两个APP都是开源项目可以保证安全性。第一次由于
134 | 需要初始化,所以比较慢,以后运行不需要这一步会很快的。当看到"设备连接成功",说明设备初始化成功。
135 |
136 | 3.开始下载:打开本软件之后第一件事是勾选大屏模式,然后打开第一个视频(原理是从当前视频开始向上
137 | 滑动一个一个下载),必须输入视频数量(在自己的主页或者他人主页可以看到数量,或者自定义)
138 | ************************************************************************************************************************
139 | ''')
140 |
141 | num = input("本次下载视频的数量(不输入默认20,输入完回车,记得看使用方法):")
142 | d = u2.connect()
143 | print(d.info)
144 | print("设备连接成功!")
145 | if num != "":
146 | num = int(num) + int(num) % 10
147 | else:
148 | num = 20
149 |
150 | p = Thread(target=task)
151 | p.start()
152 | raw_url_list=[]
153 |
154 | for i in range(num):
155 | try:
156 | # 点击分享按钮
157 | d(resourceId="com.smile.gifmaker:id/forward_icon").click()
158 |
159 |
160 | # 点击复制
161 | d(text="复制链接").click()
162 |
163 | # 获取链接,好像有延时,所以
164 | time.sleep(0.3)
165 | raw_url = d.clipboard
166 | print("\033[1;36m获取分享链接:" + raw_url + "\033[0m")
167 | if raw_url in raw_url_list:
168 | print("获取分享链接:此链接已经获取过了:"+raw_url)
169 | else:
170 | q.put(raw_url)
171 | raw_url_list.append(raw_url)
172 |
173 |
174 |
175 | # 向上滑动,获取下一个
176 | d(resourceId="com.smile.gifmaker:id/refresh_layout").swipe("up", steps=10)
177 | except:
178 | print("获取分享链接失败")
179 | time.sleep(4)
180 |
181 |
--------------------------------------------------------------------------------
/test/ss.js:
--------------------------------------------------------------------------------
1 | define("web:component/reflow_video/index", function (a, t, e) {
2 | e.exports = Pagelet.extend(
3 | {
4 | el: "#pageletReflowVideo", events: {"click $player": "onPlayVideo"}, channels: {}, init: function (a) {
5 | this.data = a, this.render()
6 | }, hasDataRender: function (a) {
7 | try {
8 | $(".detail.clrfix").removeClass("not-found"), $(".bg-ground-anchor").attr("style", "background-image:url(".concat(a.video.cover.url_list[0], ")")), $(".user-avator-anchor").attr("src", a.author.avatar_thumb.url_list[0]), $(".name.nowrap").text("@" + a.author.nickname), a.cha_list & & a.cha_list[0] ? $(".challenge-info .inner").text(a.cha_list[0].cha_name) : $
9 | (".challenge-info").attr("style", "display: none"), $(".desc").text(a.desc)
10 | } catch (t) {
11 | this.hasNoDataRender()
12 | }
13 | }, hasNoDataRender: function () {
14 | $(".detail.clrfix").addClass("not-found"), $(".bg-ground-anchor").attr("style", "background-image:url()"), $(
15 | ".user-avator-anchor").attr(
16 | "src", ""), $(".name.nowrap").text(""), $(".challenge-info").attr("style", "display: none"), $(".desc").attr("style",
17 | "display: none")
18 | },
19 | render: function () {
20 | var a = this;
21 | this.data.itemId || (this.data.itemId = location.pathname.replace(/ ^ \ / |;\ / $ /g, "").split("/")[2]),
22 |
23 |
24 | $.get(
25 | "/web/api/v2/aweme/iteminfo/", {item_ids: this.data.itemId, dytk: this.data.dytk}, function (t) {
26 | if (0 === t.status_code) {
27 | var
28 | e = t.item_list[0], i = !!e;
29 | if (!i)
30 | return void
31 | a.hasNoDataRender();
32 | a.hasDataRender(e);
33 | try {
34 | a.data.videoWidth = e.video.width | | 750, a.data.videoHeight = e.video.height | | 1334, a.data.playAddr =
35 | e.video.play_addr.url_list[0], a.data.cover = e.video.cover.url_list[0], a.data.hasData = i
36 | } catch (d) {
37 | return void
38 | a.hasNoDataRender()
39 | }
40 | var
41 | o = a.$dom.player, r = a.data.videoWidth, n = a.data.videoHeight, s = o.width(),
42 | l = s * n / r;
43 | o.css("height", l)
44 | }
45 | })
46 | }, onPlayVideo: function () {
47 | var
48 | a = this.$dom.player;
49 | if (!this.loaded) {
50 | this.loaded = !0;
51 | var
52 | t = this.data.hasData;
53 | if (!t)
54 | return;
55 | var
56 | e = $("