最近正好在研究Python,看了菜鸟教程上的基本教程,然后又再看极客学院的教学视频,向实战进军。
极客学院的视频是需要年费会员才能下载的,客户端倒是可以批量下载,但是下载之后,没有目录结构,文件名和扩展名也被隐掉了,只能在客户端观看,但是客户端又做的没那么人性化,不能按课程分门别类,所有的课程都是在一个列表之中,很是麻烦,而且资料又不全。
恰好,看到了网页爬虫的相关内容,正好可以解决我这一问题,来个自动化下载,连带资料一起打包,按“类型/阶段/课程/视频”多级目录下载,岂不是很省事。
为什么要写一个自动化的脚本,原因如下:
1 下载一个视频,至少点击两下
2 文件名是一串代号
3 没有批量下载,下载整节课程麻烦死
年费会员的服务也就这样了,除了可以下载和缓存这个特权外,服务就一般般了
说干就干,Let’s go
注:本例基于Python3,在Ubuntu 14.04下开发,其已经集成了Python2和3,默认在控制台输入python命令使用的是Python2,调用Python3使用命令”python3”
爬取极客学院只是体系图中的所有课程体系,并得到其链接集合
http://www.jikexueyuan.com/path/
#!/usr/bin/python3
import requests
import SpiderUtil
from lxml import etree
from CoursePathSpider import CoursePathSpider
class PathSpider(object):
""" 课程路径图爬虫 """
URL_PATH = 'http://www.jikexueyuan.com/path/'
XPATH_PATH_LINK = '//a[@class="pathlist-one cf"]'
XPATH_PATH_NAME = 'div[@class="pathlist-txt"]/h2/text()'
XPATH_PATH_INTRO = 'div[@class="pathlist-txt"]/p/text()'
def __init__(self):
super(PathSpider, self).__init__()
self.path_info_list = []
self.response = None
self.selector = None
def parse_html(self):
print("正在获取课程路线列表...")
# try:
self.response = requests.get(PathSpider.URL_PATH)
# print(self.response.text)
self.selector = etree.HTML(self.response.text)
for link_ele in self.selector.xpath(PathSpider.XPATH_PATH_LINK):
self.path_info_list.append(_PathInfo(link_ele))
# except Exception:
# print("连接异常")
# # exit()
# else:
# pass
def show(self):
n = 0
print("共有学习路线图:", len(self.path_info_list), "个,分别是:")
for info in self.path_info_list:
n += 1
print(str(n)+".", info.name)
def show_detail(self, index):
if SpiderUtil.is_valid_index(index, len(self.path_info_list)):
self.path_info_list[index].show()
return "OK"
else:
return "error"
def download(self, index):
if SpiderUtil.is_valid_index(index, len(self.path_info_list)):
print("开始下载", self.path_info_list[index].name)
self.path_info_list[index].download()
return "OK"
else:
return "error"
class _PathInfo(object):
def __init__(self, selector):
super(_PathInfo, self).__init__()
# print("正在获取课程路线列表...")
self.selector = selector
self.name = selector.xpath(PathSpider.XPATH_PATH_NAME)[0]
self.inrto = selector.xpath(PathSpider.XPATH_PATH_INTRO)
self.url = selector.xpath('@href')[0]
def show(self):
print("课程:", self.name)
print("简介:", self.inrto)
print("链接:", self.url)
return
def sub_spider(self):
spider = CoursePathSpider(self.url, self.name)
return spider
def download(self):
self.sub_spider().download()
分析具体的课程体系,按章节分组,并得到其课程视频链接集合
获取的结果是一个二级目录机构,如下所示:
在下载视频时,将其作为存储路径,这样就得到了一个层级的目录结构,方便观看
代码如下:
#!/usr/bin/python3
import requests
import SpiderUtil
import os
from lxml import etree
from LessonVideoSpider import VideoSpider
class CoursePathSpider(object):
""" 课程路径图网页分析 """
# 课程章路径
XPATH_CHAPTER = '//*[@id="container"]/div/div[@class="pathstage mar-t30"]'
# 章节名
xpath_chapter_name = 'div[@class="pathstage-txt"]/h2/text()'
# 章下的课程列表路径
xpath_chapter_lesson_list = 'div/div[@class="stagewidth lesson-list"]/ul[@class="cf"]/li'
# 课程名和链接
xpath_lesson_name = 'div[@class="lesson-infor"]/h2[@class="lesson-info-h2"]/a/text()'
xpath_lesson_link = 'div[@class="lesson-infor"]/h2[@class="lesson-info-h2"]/a/@href'
def __init__(self, url, simple_name):
super(CoursePathSpider, self).__init__()
self.url = url
self.simple_name = simple_name
self.response = None
self.chapter_list = []
self.selector = None
self.title = ''
self.chapter_list = []
def parse_html(self):
print("正在打开网址:", self.url)
self.response = requests.get(self.url)
print("开始处理返回结果...")
self.selector = etree.HTML(self.response.text)
self.title = self.selector.xpath('//title/text()')[0]
if self.simple_name == '':
if len(self.title) > 10:
self.simple_name = self.title[0, 10]
else:
self.simple_name = self.title
print("课程名称:", self.title)
for chapterEle in self.selector.xpath(CoursePathSpider.XPATH_CHAPTER):
self.add_chapter(_Chapter(chapterEle))
def add_chapter(self, chapter):
if isinstance(chapter, _Chapter):
self.chapter_list.append(chapter)
else:
raise ValueError("chapter is not a instance of Chapter")
def download(self, path, index='a'):
path = path + "/" + self.simple_name
if SpiderUtil.is_all(index):
print("下载完整路线")
self.download_all(path)
else:
index2 = SpiderUtil.is_valid_index(index, len(self.chapter_list))
print("下载:" + self.chapter_list[index2].name)
return self.chapter_list[index2].download(path)
def download_all(self, path):
for chapter in self.chapter_list:
chapter.download(path)
print("课程路线:", self.title, '保存成功')
def show(self):
print(self.title)
for chapter in self.chapter_list:
chapter.show()
def lessons(self):
lesson_list_2 = []
for chapter in self.chapter_list:
lesson_list_2.extend(chapter.lessonlist)
return lesson_list_2
class _Chapter(object):
"""按章分析 """
def __init__(self, selector):
super(_Chapter, self).__init__()
self.selector = selector
self.lesson_list = []
self.name = ""
self.parse_html()
def parse_html(self):
self.name = self.selector.xpath(CoursePathSpider.xpath_chapter_name)[0]
print(self.name)
index = 0
for lessonEle in self.selector.xpath(CoursePathSpider.xpath_chapter_lesson_list):
index += 1
self.add_lesson(_Lesson(lessonEle, pre_name=str(index) + ". "))
def add_lesson(self, lesson):
if isinstance(lesson, _Lesson):
self.lesson_list.append(lesson)
else:
raise ValueError("lesson is not a instance of Lesson")
def download(self, path, index='a'):
if SpiderUtil.is_all(index):
self.download_all(path)
else:
index2 = SpiderUtil.is_valid_index(index, len(self.lesson_list))
if index2 != 0:
print("下载:" + self.lesson_list[index2].name)
return self.lesson_list[index2].download(path)
else:
return "error"
return "OK"
def download_all(self, parent):
path = parent + "/" + self.name
for lesson in self.lesson_list:
lesson.download(path)
# result =
# if not SpiderUtil.is_ok(result):
# break
def show(self):
print(self.name)
for lesson in self.lesson_list:
lesson.show()
class _Lesson(object):
"""分析课程信息 """
def __init__(self, selector, pre_name=''):
self.selector = selector
self.name = pre_name + selector.xpath(CoursePathSpider.xpath_lesson_name)[0]
self.link = selector.xpath(CoursePathSpider.xpath_lesson_link)[0]
self.path = ""
self.sub_spider = VideoSpider()
# print("--", self.name)
def download(self, parent):
self.path = parent + "/" + self.name
if not os.path.exists(self.path):
os.makedirs(self.path)
self.save_inf()
print("正在下载课程:", self.name)
self.sub_spider.download(self.path, self.link)
self.sub_spider.save_info(self.path)
def save_inf(self):
file = open(self.path + "/readme.txt", "a+")
file.write("#课程名称")
file.write("\nname=" + self.name)
file.write("\n#课程链接")
file.write("\nlink=" + self.link)
file.close()
def show(self):
print("-- ", self.name, "=", self.link)
重点就是这个了,极客学院的视频下载很麻烦,没有批量下载入口。观看视频时只能切换一个视频,然后点“下载本节视频”,很是不方便,把cookies和请求头,视频播放链接,三个核心参数,传给下面模块,就可以实现自动下载了。
#!/usr/bin/python3
import os
import re
import requests
from lxml import etree
import SpiderUtil
class VideoSpider(object):
STATUE_SUCCEED = '成功:'
STATUE_FAILED = '失败:'
STATUE_JUMPED = '跳过:'
url_download = 'http://www.jikexueyuan.com/course/video_download'
video_ex_name = ".mp4"
xpath_lesson_bg = '//div[@class="infor-content"]/text()'
xpath_video_list = '//div[@class="lesson-box"]/ul/li'
xpath_video_index = 'i[@class="lessonmbers"]/em/text()'
xpath_video_name = 'div[@class="text-box"]/h2/a/text()'
xpath_video_href = 'div[@class="text-box"]/h2/a/@href'
""" VideoSpider 课程详情页,即视频播放页面 """
def __init__(self):
super(VideoSpider, self).__init__()
self.url = ""
self.course_id = ""
self.video_list = []
self.bg_txt = ""
self.response = None
self.selector = None
def parse_html(self, url):
if re.match("http://", url) is None:
raise ValueError("Invalid URL "+url)
self.url = url
print("正在获取下载地址:" + self.url)
course_id_list = re.findall('/(\d*?).html', url)
self.course_id = ""
if len(course_id_list) == 1:
self.course_id = course_id_list[0]
self.response = requests.get(self.url, headers=SpiderUtil.headers, cookies=SpiderUtil.cookies)
self.selector = etree.HTML(self.response.text)
self.bg_txt = self.selector.xpath(VideoSpider.xpath_lesson_bg)
for video_ele in self.selector.xpath(VideoSpider.xpath_video_list):
video = Video()
video.parse_html(video_ele, self.course_id)
self.add_video(video)
print("下载地址分析完成:" + self.url)
def add_video(self, video):
if isinstance(video, Video):
self.video_list.append(video)
def download(self, path, url):
self.parse_html(url)
print("开始下载视频")
result = {VideoSpider.STATUE_SUCCEED: 0, VideoSpider.STATUE_FAILED: 0, VideoSpider.STATUE_JUMPED: 0}
if not os.path.exists(path):
os.makedirs(path)
for video in self.video_list:
data = video.download(path)
result[data] += 1
file = open(path + "/readme.txt", "a+")
file.write("\n下载日志:总计" + str(len(self.video_list)) + str(result))
file.close()
print("该课程视频下载完成:总计", len(self.video_list), result)
return result
def save_info(self, path):
if not os.path.exists(path):
os.makedirs(path)
file = open(path + "/readme.txt", "a+")
for text in self.bg_txt:
file.write(text)
for video in self.video_list:
video.save_info(file)
file.close()
class Video(object):
"""docstring for VideoInfo"""
def __init__(self):
super(Video, self).__init__()
self.seq = "1"
self.index = ""
self.name = ""
self.href = ""
self.response = None
self.result_dic = {}
self.download_flag = False
def parse_html(self, selector, course_id):
self.index = selector.xpath(VideoSpider.xpath_video_index)[0]
self.name = selector.xpath(VideoSpider.xpath_video_name)[0]
self.href = selector.xpath(VideoSpider.xpath_video_href)[0]
temp = re.findall('_(\d).html', self.href)
if len(temp) == 1:
self.seq = temp[0]
params = {'seq': self.seq, 'course_id': course_id}
self.response = requests.get(VideoSpider.url_download, params=params,
headers=SpiderUtil.headers, cookies=SpiderUtil.cookies)
self.result_dic = eval(self.response.text)
# print("下载请求返回结果:", self.response.text)
if len(self.result_dic["data"]) == 0:
raise ValueError("cookies is not a valid")
else:
self.download_flag = True
return "OK"
def url(self):
if self.result_dic["code"] == 200:
return self.result_dic["data"]["urls"]
else:
return ""
def file_name(self):
try:
self.result_dic["filename"]
except KeyError:
file_name = SpiderUtil.replace_special(self.result_dic["data"]["title"])
self.result_dic["filename"] = self.index + "." + file_name + VideoSpider.video_ex_name
else:
pass
finally:
return self.result_dic["filename"]
def download(self, path):
if not self.download_flag:
raise ValueError("cookies is not a valid")
file_name = path + "/" + self.file_name()
if not os.path.exists(file_name):
try:
print("正在下载视频:", self.file_name())
response = requests.get(self.url())
with open(file_name, "wb") as code:
code.write(response.content)
print("【", file_name, "】下载完成")
except Exception:
return VideoSpider.STATUE_FAILED
else:
return VideoSpider.STATUE_SUCCEED
else:
print("【", file_name, "】已经存在了")
return VideoSpider.STATUE_JUMPED
def save_info(self, file):
file.write("\n"+self.seq + self.name)
file.write("\n请求结果:" + str(self.result_dic))
#!/usr/bin/python3
from PathSpider import PathSpider
import platform
import os
import re
def int_input(info="请选择:", list=()):
input_str = ""
while input_str == "":
input_str = input(info)
input_int = -1
try:
input_int = int(input_str)
except ValueError:
print("请输入数字!")
continue
else:
if list.count(input_int) == 0:
print("请根据提示输入!")
continue
else:
return input_int
def path_input():
''' 检查输入的路径是否存在,存在则返回
如果不存在,创建该文件夹,
创建失败,重新输入
创建成功,返回路径
'''
default = default_path()
input_path = ""
while input_path == "":
input_path = input('请输入存储路径【默认"' + default + '"】:')
if input_path == "":
input_path = default
elif re.match("[A-Z]|[a-z]://", input_path) is None:
input_path = default + "/" + input_path
elif re.match("/|~", input_path) is None:
input_path = default + "/" + input_path
else:
pass
if check_path(input_path) or make_file_path(input_path):
return input_path
else:
print("地址【", input_path, "】无效,情重新输入", flush=True)
continue
def check_path(file_path):
if os.path.exists(file_path):
return True
else:
return False
def make_file_path(file_path):
try:
os.makedirs(file_path)
except IOError as ioe:
ioe.print("创建文件夹失败")
return False
else:
return True
def default_path():
sys_name = platform.system()
path_list = []
if sys_name == "Windows":
path_list = ["F://", "E://", "D://", "C://"]
elif sys_name == "Linux":
path_list = ["/mnt/hgfs/G/", "~/"]
else:
return ''
for dpath in path_list:
if os.path.exists(dpath):
return dpath + '极客学院视频'
return ""
if __name__ == '__main__':
try:
path_spider = PathSpider()
path_spider.parse_html()
path_spider.show()
_path_list = path_spider.path_info_list
course_spider = None
index = 0
if len(_path_list) > 0:
print("[1~", len(_path_list), "]选择课程路线/ 0 退出")
index = int_input(list=range(0, len(_path_list)))
if index == 0:
exit()
else:
_path_list[index - 1].show()
course_spider = _path_list[index - 1].sub_spider()
course_spider.parse_html()
print("全部下载[0],按章下载请输入[1~", len(course_spider.chapter_list), "]")
index = int_input(list=range(0, len(_path_list)))
path = path_input()
print("视频将下载到下载到:", path)
if index == 0:
course_spider.download(path)
else:
course_spider.download(path, index)
except ConnectionError as ce:
print("连接超时,请检查网络!")
else:
print("下载结束!")
#!/usr/bin/python3
import string
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6',
'Connection': 'keep-alive',
'DNT': '1',
'Host': 'www.jikexueyuan.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36'}
# 具体的值就不分享了,每次登录之后也是不一样的,想要那个视频的可以留言,发你邮箱
cookies = {'stat_uuid': '',
'sensorsdata2015jssdkcross': '',
'r_user_id': '', # stat_fromWebUrl': '',
'stat_ssid': '',
'looyu_id': '',
'_gat': '1',
'uname': '用户名',
'uid': '',
'code': '',
'authcode': '登录了你的会员账号,去浏览器里复制cookies',
'level_id': '2',
'is_expire': '0',
'domain': '',
'_99_mon': '',
'Hm_lvt_f3c68d41bda15331608595c98e9c3915': '',
'Hm_lpvt_f3c68d41bda15331608595c98e9c3915': '',
# 'undefined': '',
'stat_isNew': '0',
'looyu_20001269': '好像没什么用',
'_ga': '', }
def is_ok(str1):
if isinstance(str1, str):
return str1.lower() == "ok" or str1.lower() == "y" or str == ''
else:
return False
def is_all(str1):
if isinstance(str1, str):
return str1.lower() == "a" or str == ''
else:
return False
def is_valid_index(index, length):
if isinstance(index, int):
if (index >= 1) and (index <= length):
return index - 1
elif isinstance(index, str):
try:
index2 = int(index)
except Exception as e:
print(e)
return 0
else:
if (index2 >= 1) and (index2 <= length):
return index2 - 1
else:
return 0
def replace_special(source_str):
special = ('/', '\\', ':', '<', '>', '|', '*', '?', '"', ' ')
for s in special:
source_str = source_str.replace(s, "")
return source_str
if __name__ == '__main__':
jieguo = is_valid_index("3", 10)
print(jieguo)
print(is_ok("Ok"))
print(is_ok("oo"))
print("特殊字符替换", replace_special('/ \\ " ? * | < > : '))
这样我们就得到了,一个带目录结构的链接列表了,我们可以根据这个,创建基本目录,从而将下载的视频文件写入到对应目录。
以上这个课程体系链接是不需要什么验证就能直接打开的,但是打开我们爬取到的链接是需要用户名验证的,有些收费视频只有会员才能观看,而且是只有会员才能下载的。
接下来,需要在提交请求的时候,将验证信息一同提交,以拿到下载视频的链接
前提:有会员账号,点我注册即送一个月会员
执行命令:./Main.py
正在获取课程路线列表...
共有学习路线图: 24 个,分别是:
1. Android
2. HTML5开发
3. Java语言
4. PHP语言
5. JavaWeb
6. iOS开发
7. Asp.Net
8. C语言
9. Python
10. Unity3D
11. Swift语言
12. C#
13. Bootstrap
14. Cocos2d-x游戏开发
15. 计算机一级
16. 计算机二级
17. GUI
18. WatchKit开发
19. Docker
20. Egret
21. Arduino
22. Android UiAutomator
23. JavaScript
24. Node.js
[1~ 24 ]选择课程路线/ 0 退出
请选择:2
课程: HTML5开发
简介: ['HTML5增加了很多新特性,包含Canvas元素、Video元素和Audio元素等。\r\n']
链接: http://www.jikexueyuan.com/path/html5/
正在打开网址: http://www.jikexueyuan.com/path/html5/
开始处理返回结果...
课程名称: Html5从入门到精通学习知识体系_极客学院
1. HTML5开发前准备
2. HTML5基础
3. CSS基础
4. CSS3 基础
5. CSS3 炫酷动画
6. JavaScript基础
7. HTML5新特性
8. 响应式布局
9. jQuery基础
10. jQuery UI基础
11. jQuery Mobile基础
12. 移动HTML5开发进阶
全部下载[0],按章下载请输入[1~ 12 ]
请选择:0
请输入存储路径【默认"/mnt/hgfs/G/极客学院视频"】:
视频将下载到下载到: /mnt/hgfs/G/极客学院视频
下载完整路线
正在下载课程: 1. HTML5开发前准备
正在获取下载地址:http://www.jikexueyuan.com/course/181.html
下载地址分析完成:http://www.jikexueyuan.com/course/181.html
开始下载视频
正在下载视频: 1.HTML5开发前的准备.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/1. HTML5开发前准备/1. HTML5开发前准备/1.HTML5开发前的准备.mp4 】下载完成
正在下载视频: 2.开发前的准备-快捷键.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/1. HTML5开发前准备/1. HTML5开发前准备/2.开发前的准备-快捷键.mp4 】下载完成
该课程视频下载完成:总计 2 {'跳过:': 0, '失败:': 0, '成功:': 2}
正在下载课程: 1. HTML5特性简介
正在获取下载地址:http://www.jikexueyuan.com/course/127.html
下载地址分析完成:http://www.jikexueyuan.com/course/127.html
开始下载视频
正在下载视频: 1.HTML5简介.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/1. HTML5特性简介/1.HTML5简介.mp4 】下载完成
正在下载视频: 2.HTML5集成开发环境搭建.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/1. HTML5特性简介/2.HTML5集成开发环境搭建.mp4 】下载完成
正在下载视频: 3.HTML5基础详解.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/1. HTML5特性简介/3.HTML5基础详解.mp4 】下载完成
该课程视频下载完成:总计 3 {'跳过:': 0, '失败:': 0, '成功:': 3}
正在下载课程: 2. HTML5元素、属性和格式化
正在获取下载地址:http://www.jikexueyuan.com/course/128.html
下载地址分析完成:http://www.jikexueyuan.com/course/128.html
开始下载视频
正在下载视频: 1.HTML5元素简介及使用方法.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/2. HTML5元素、属性和格式化/1.HTML5元素简介及使用方法.mp4 】下载完成
正在下载视频: 2.HTML5属性使用方法.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/2. HTML5元素、属性和格式化/2.HTML5属性使用方法.mp4 】下载完成
正在下载视频: 3.HTML5格式化及使用.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/2. HTML5元素、属性和格式化/3.HTML5格式化及使用.mp4 】下载完成
该课程视频下载完成:总计 3 {'跳过:': 0, '失败:': 0, '成功:': 3}
正在下载课程: 3. HTML5样式、链接和表格
正在获取下载地址:http://www.jikexueyuan.com/course/136.html
下载地址分析完成:http://www.jikexueyuan.com/course/136.html
开始下载视频
正在下载视频: 1.HTML5样式的使用.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/3. HTML5样式、链接和表格/1.HTML5样式的使用.mp4 】下载完成
正在下载视频: 2.HTML5链接属性及使用.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/3. HTML5样式、链接和表格/2.HTML5链接属性及使用.mp4 】下载完成
正在下载视频: 3.HTML5表格使用.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/3. HTML5样式、链接和表格/3.HTML5表格使用.mp4 】下载完成
该课程视频下载完成:总计 3 {'跳过:': 0, '失败:': 0, '成功:': 3}
正在下载课程: 4. HTML5列表、块和布局
正在获取下载地址:http://www.jikexueyuan.com/course/135.html
下载地址分析完成:http://www.jikexueyuan.com/course/135.html
开始下载视频
正在下载视频: 1.HTML5列表的使用.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/4. HTML5列表、块和布局/1.HTML5列表的使用.mp4 】下载完成
正在下载视频: 2.HTML5块元素标签的使用.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/4. HTML5列表、块和布局/2.HTML5块元素标签的使用.mp4 】下载完成
正在下载视频: 3.HTML5布局的使用.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/4. HTML5列表、块和布局/3.HTML5布局的使用.mp4 】下载完成
该课程视频下载完成:总计 3 {'跳过:': 0, '失败:': 0, '成功:': 3}
正在下载课程: 5. HTML5表单提交和PHP环境搭建
正在获取下载地址:http://www.jikexueyuan.com/course/139.html
下载地址分析完成:http://www.jikexueyuan.com/course/139.html
开始下载视频
正在下载视频: 1.HTML5表单的创建.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/5. HTML5表单提交和PHP环境搭建/1.HTML5表单的创建.mp4 】下载完成
正在下载视频: 2.PHP环境搭建.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/5. HTML5表单提交和PHP环境搭建/2.PHP环境搭建.mp4 】下载完成
正在下载视频: 3.HTML5表单与PHP交互.mp4
【 /mnt/hgfs/G/极客学院视频/HTML5开发/2. HTML5基础/5. HTML5表单提交和PHP环境搭建/3.HTML5表单与PHP交互.mp4 】下载完成
该课程视频下载完成:总计 3 {'跳过:': 0, '失败:': 0, '成功:': 3}
好了,这样直接运行Main.py就可以实现下载了,前面三个模块都是可以独立使用的。LessonVideoSpider需要依赖SpiderUtil,当然你也可以将两个类合并一下。
刚刚开始学习,有错误的地方请指正