www.raywenderlich.com 对于 iOS 开发人员来讲必定不陌生,这多是 iOS 初级教程里面被推荐最多的网站了吧。javascript
其实它不只有 iOS 的开发教程,后面还出了 android 和 Unity 的开发教程。java
教程简明实用,有原理介绍还有代码实现,直接能够看到实现效果,很是推荐你们也能写成像它上面的教程。python
raywenderlich.com is a community site focused on creating high quality programming tutorials.android
We pride ourselves on creating the highest-quality video courses, books, and written tutorials on the Internet.ios
Every tutorial on our site goes through three rounds of editing before publication, to make sure each tutorial works 100%, is technically accurate, and provides comprehensive coverage of the topic.git
Thousands of developers and designers of all backgrounds, from all over the world, come to raywenderlich.com to teach and learn.github
We pay our authors and editor for all of their work, using the highest rates in the industry.正则表达式
Our goal is to create an environment where talented developers and teachers can make a living through their work, or advance their career by being recognized as an expert.chrome
5 月 2 日收到 Ray Wenderlich ray@raywenderlich.com 的订阅邮件。json
五一周末免费开放视频 3 天,太好了,为了之后也有时间观看,我决定把视频下载下来。
最早找到 github.com/ytdl-org/yo…,这上面提供多种视频下载。
代码 clone 下来一运行,报错!登陆不成功。
这个难不倒我,使用 Chrome 开发者工具,找到 Header
里面有一个
'Authorization': 'Token ..'
复制代码
打开 Postman,添加 Authorization
。
Hersers
界面以下:
获得 json
文件:
{
"video": {
"id": 246,
"name": "PDF Printing",
"description": "Create a PDF file. We’ll create a budget report that you could then share.",
"author_notes": "",
"duration": 589,
"pretty_duration": "9 minutes 49 seconds",
"featured": false,
"episode": 6,
"format": "course",
"language": null,
"platform": null,
"editor": null,
"meta_description": null,
"released_at": "2016-05-13T16:00:00.000Z",
"difficulty": "intermediate",
"created_at": "2016-08-04T02:56:51.175Z",
"updated_at": "2019-04-28T10:01:25.399Z",
"free": true,
"attachments": [
{
"id": 4605,
"url": "https://files.betamax.raywenderlich.com/attachments/videos/246/CG-Int-MyList-06.png",
"kind": "watchlist_artwork",
"filename": "CG-Int-MyList-06.png",
"retina": false
},
{
"id": 4606,
"url": "https://files.betamax.raywenderlich.com/attachments/videos/246/CG-Int-MyList-06%402x.png",
"kind": "watchlist_artwork",
"filename": "CG-Int-MyList-06@2x.png",
"retina": true
},
{
"id": 4607,
"url": "https://files.betamax.raywenderlich.com/attachments/videos/246/CG-Int-VideoBanner-06.png",
"kind": "video_banner",
"filename": "CG-Int-VideoBanner-06.png",
"retina": false
},
{
"id": 4608,
"url": "https://files.betamax.raywenderlich.com/attachments/videos/246/CG-Int-VideoBanner-06%402x.png",
"kind": "video_banner",
"filename": "CG-Int-VideoBanner-06@2x.png",
"retina": true
},
{
"id": 1736,
"url": "https://files.betamax.raywenderlich.com/attachments/videos/246/005_IntCoreGraphics_PDF.zip",
"kind": "materials",
"filename": "005_IntCoreGraphics_PDF.zip",
"retina": false
}
],
"authors": [
{
"id": 25,
"role": "instructor",
"user": {
"id": 9,
"external_id": "8f5ca72a-11f3-11e6-b121-2380095a6428",
"email": "caroline@archway.com.au",
"username": "Caroline",
"avatar_url": "https://www.gravatar.com/avatar/bfe2a965cd6136b9e2b485c959a57aff.jpg?d=https%3A%2F%2Fwolverine.raywenderlich.com%2Fv3-resources%2Fimages%2Fdefault-account-avatar_2x.png\u0026s=480",
"name": "Caroline Begbie"
}
}
],
"clips": [
{
"id": 253,
"provider_id": "164661205",
"provider_url": "https://vimeo.com/164661205",
"pretty_duration": "9m 49s",
"clip_type": "primary_content",
"attachments": [
{
"id": 5470,
"url": "https://files.betamax.raywenderlich.com/attachments/clips/253/164661205.vtt",
"kind": "subtitles",
"filename": "#164661205.vtt",
"retina": false
},
{
"id": 1735,
"url": "https://player.vimeo.com/external/164661205.m3u8?s=96740a5872b5272dc2e5b1a29af7b33a92e3739e\u0026oauth2_token_id=897711146",
"kind": "stream",
"filename": "#164661205",
"retina": false
},
{
"id": 24274,
"url": "https://player.vimeo.com/external/164661205.sd.mp4?s=dc9fad611715e5efa3e2544989877c3de083a2a5\u0026profile_id=165\u0026oauth2_token_id=897711146",
"kind": "sd_video_file",
"filename": "164661205.sd.mp4",
"retina": false
},
{
"id": 24275,
"url": "https://player.vimeo.com/external/164661205.hd.mp4?s=327799fd9b66832d7f7a53fa1a3d76cd8f9b902a\u0026profile_id=174\u0026oauth2_token_id=897711146",
"kind": "hd_video_file",
"filename": "164661205.hd.mp4",
"retina": false
}
]
}
],
"categories": [
{
"id": 27,
"name": "carolus: Graphics \u0026 Animation"
},
{
"id": 42,
"name": "domain: ios"
},
{
"id": 6,
"name": "Graphics"
}
]
}
}
复制代码
固然如今已经不行了。
{
"error": "video not available"
}
复制代码
youtube-dl 是能够登陆 raywenderlich,但是又报 Vimeo
登陆错误。
叹!
另辟蹊径吧,咱们来解析一下 json
文件吧。我发现
{
"video": {
"name": "PDF Printing",
"clips": [
{
"attachments": [
{
"id": 1735,
"url": "https://player.vimeo.com/external/164661205.m3u8?s=96740a5872b5272dc2e5b1a29af7b33a92e3739e\u0026oauth2_token_id=897711146",
"kind": "stream",
"filename": "#164661205",
"retina": false
}
]
}
]
}
}
复制代码
找到 "kind": "stream"
内容,使用 FFmpeg 下载。
$ ffmpeg -i "https://player.vimeo.com/external/164661205.m3u8?s=96740a5872b5272dc2e5b1a29af7b33a92e3739e\u0026oauth2_token_id=897711146" "PDF Printing.mp4"
复制代码
好的,能够下载。可是这个下载速度也实在是太慢了吧!
放个人服务器上面下载,结果 FFmpeg 报 CPU
错误,我...
我在 google 上面找啊找,找啊找,仍是找不着解决方法。
实在不行,我多开几个终端慢慢下吧。
经过解析上面的 json
文件,看到还有附件呢,正好前几天有人在 B站 问我要 Ray Wenderlich Video Tutorial - Introducing Custom Controls 的源码,我把源码也下载下来吧。
这个实现比较简单,直接放出源码。
import requests
from bs4 import BeautifulSoup
import os
base_url = 'https://www.raywenderlich.com'
headers = {
"Accept" : "application/json, text/javascript, */*; q=0.01",
"Authorization" : "Bearer xxx",
"Origin" : "https://www.raywenderlich.com",
"Referer" : "https://www.raywenderlich.com/",
"User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
"X-CSRF-Token" : "qnaS...",
"X-Requested-With" : "XMLHttpRequest",
}
def download(url):
r = requests.get(url, headers=headers)
result = raywenderlich_from_dict(r.json())
name = result.video.name.replace('&', '').replace(':', '').replace('?', '')
attachments = result.video.attachments
_id = result.video.id
_name = result.video.name.replace('&', '').replace(':', '').replace('?', '')
for attachment in attachments:
filename = attachment.filename
url = attachment.url
cmd = 'wget -O "%s. %s %s" %s' % (_id, _name, filename, url)
os.system(cmd.encode('utf-8'))
if __name__ == '__main__':
for i in range(2789):
url = 'https://videos.raywenderlich.com/api/v1/videos/%s.json' % I
print(url)
try:
download(url)
except:
print(i)
复制代码
这样就能够下载全部附件了。
次日我又从服务器运行 youtube-dl
,竟然不报错了,太棒了,赶忙下载。
不过 youtube-dl
只能下 youtube-dl
里面的 Video Course 系列视频,而不能下载 Screencast 单个视频。原来 _VALID_URL
是不匹配,并且里面的内容也不同。
是可忍,孰不可忍。
$ git checkout -b raywenderlich_screencast
复制代码
修改 raywenderlich.md
:
class RayWenderlichIE(InfoExtractor):
_VALID_URL = r'''(?x) https?:// (?: videos\.raywenderlich\.com/courses| (?:www\.)?raywenderlich\.com )/ (?P<id>[^/]+) 复制代码
实现内容比以前更简单了,直接从 thumbnail 中找到 video_id 就行了,不过 thumbnail 有时候是空的,好说,正则表达式大法伺候。
因而又安心的睡觉去了。
嘀嘀嘀!原来是磁盘满了,再哭。
好吧,我一咬牙,一跺脚,再买一个磁盘大点的服务器(就买一个月吧,实在是没钱了)。
慢慢下载去吧。
嘘。嘘。嘘。。。
次日磁盘又满了,赶忙下载 BaiduPCS-Go。
快点上传啊,我求求你了。结果没用,好的时候有好几 M 的速度,一下子又只剩下几 k。
最后结果:共有 2K 多的视频,我下载了 1K 多的视频。
关注个人公众号,AI开发日志(AIDevLog) / iOS开发日志(iOSDevLog)。
有须要资源的能够联系我,直接共享容易封,我也在慢慢上传 B站。
有条件的请去官网 www.raywenderlich.com 观看