最近着迷化學, 特別是古代的冶煉技術,感嘆古人的聰明。
春秋時期的煉鐵方法是塊煉鐵,即在較低的冶煉溫度下,將鐵礦石固態還原獲得海綿鐵,再經鍛打成的鐵塊。冶煉塊煉鐵,一般采用地爐、平地築爐和豎爐3種。鐵礦石在溫度較高的煉鐵爐中高溫還原並滲碳,得到含碳達到3~4%的液態生鐵。戰國初期,我國已掌握了脫碳、熱處理技術方法,發明了韌性鑄鐵。
在中國,鋼鐵的總產量在唐代年產已達到1200噸,宋朝為4700噸,明朝最多達到4萬噸。在13世紀,中國是世界上最大的鐵的生產國和消費國,直到17世紀仍保持着這一領先地位。從漢代到明朝,中國人不僅在數量上處於領先地位,而且還擁有世界上最先進的鋼鐵冶煉技術。
鑄鐵脫碳鋼 將含碳3~4%的低硅鑄鐵器在氧化氣氛中加熱,在適當條件下,特別是厚度不大的情況下,可以避免石墨的形成。早期煉鐵溫度較低,含硅量低,石墨析出較慢,有利於脫碳,使制造韌性鑄鐵的工藝發展成為鑄鐵脫碳成鋼的方法。這種鋼稱為鑄鐵脫碳鋼,這類鋼板可加工成的鐵鏃、環首刀。
炒鋼 向熔化的生鐵鼓風,同時進行攪拌促使生鐵中的碳氧化。用這種方法可將生鐵制成熟鐵,再經過滲碳鍛打成鋼。也可有控制地把生鐵含碳量炒到需要的程度,再鍛制成鋼制品。這種鋼中含有的硅酸鐵夾雜物成分比較一致而數量較少。炒鋼技術始於西漢末年,到東漢已相當普及。江蘇出土新莽殘劍,徐州出土建初二年(77)五十煉鋼劍,山東臨沂蒼山出土的永初六年(112)三十煉鋼刀等所用的原料都屬於這一類型。曹操(155~220)在《內誡令》提到“百煉利器”,孫權(182~252)有以“百煉”命名的寶刀。初步可以認為百煉鋼是用炒鋼反復疊打變形,細化晶粒和夾雜物而成的,甚至可以用不同含碳鋼材復合組成。煉數大致相當於反復折疊鍛打后最后的層數。煉數增多,表明加工量加大,晶粒和夾雜進一步細化,質量提高。炒鋼技術的發明是煉鋼史上的一次革命。
來源:http://wenku.baidu.com/view/7c9bd28d84868762caaed5ed.html
哎! 就在查找古人是如何冶煉金屬、鑄造錢幣、分離金屬元素時,找到了這個大連理工大學講的“化學與社會”公開課。講的很有調理,讓讀者很容易理解,越看越覺的這個公開課是一個經典課程,想收藏頁面怕以后鏈接會失效,所以決定把這個經典的公開課下載下來。
那么問題來了,下載網頁嵌入的flash 視頻,不是容易的事。試了網上好多視頻下載插件(DownLoad Helper 、 VDownLoad嗅探器、flv視頻下載、ImovieBox)也么有分析出網頁的鏈接視頻。好吧,我使用F12 調試網頁工具查看網絡響應,發現有type=video/mp4,然后另存為就可以了,但問題是課程有近100個,不可能一個個打開鏈接,查看網頁Network點擊視頻讓其加載出type=video/mp4 類型,再另存為。這樣太麻煩了。開動腦筋想用程序直接把視頻下載鏈接分析出來,然后保存在本地。
1. 獲取鏈接地址
查看:http://ptr.chaoxing.com/course/2533204.html 源碼,課程的list寫在了clas=“p20” ul里面的li標簽列表中
通過PyQuery可以獲取所有課程的視頻播放地址
d = self.pq('http://ptr.chaoxing.com/course/2533204.html') DomTree = d('.p20 ul li a') for my_div in DomTree.items(): URL = 'http://ptr.chaoxing.com' + my_div.attr('href') # 課時detail URL l = my_div.find('.l').html() # 課時章節NO r = my_div.find('.r').html() # 課時Name self.LessonList.append({'url': URL, "name": l + r})
2. 分析下載地址
打開一個課程視頻播放時,都會XHR請求加載一個鏈接,該鏈接的內容是:
然而我們發現,每一個視頻地址頁面都會請求一個類似於這樣的地址:http://ptr.chaoxing.com/ananas/status/************?k=&_dc=1476770383911
該地址返回一個帶有視頻mp4路徑的Json格式字符串。其中filename為當前視頻課程的名稱,http為(standard)標准清晰視頻 sd.mp4, httphd為(high)高清視頻 hd.mp4
進一步的分析我們發現,在該地址請求之前有一個類型為Document的html加載出頁面內容區域的html flash播放器
當這個播放器加載完成通過all-classes.js?v=20141027:1的Ajax請求http://ptr.chaoxing.com/ananas/status/************?k=&_dc=***。查看網頁源代碼,查找status后的這一串字符串發現這個字符串應該是視頻播放的objectID
在iframe標簽的data屬性里面。試着復制一個視頻的objectID去模擬請求http://ptr.chaoxing.com/ananas/status/************發現居然成功了!不知道此方法是否也使用其他flash視頻下載。
這樣下載課程視頻的思路就出來了:在第一步獲取下載鏈接,通過每一個視頻頁面源碼中的objectID去請求http://ptr.chaoxing.com/ananas/status/************ 獲取下載地址。然后下載視頻教程。so easy!
3. 下載視頻
通過上一步分析地址,已經知道獲取flash視頻objectID並Ajax 請求http://ptr.chaoxing.com/ananas/status/************ 就能獲取視頻地址。這一步我們就下載視頻。
通過PyQuery 獲取視頻頁面中的objectID
def getVideo(self, url): ''' 獲取視頻 ''' d = self.pq(url) DomTree = d("iframe") jsonData = DomTree.attr('data') objectid = json.loads(jsonData)['objectid'] # 獲取下載資源視頻的對象 downloadUrl = self.pq('http://ptr.chaoxing.com/ananas/status/' + objectid) # 獲取下載資源的URL jsonData = json.loads(downloadUrl.html())['httphd'] # 在這里,我們要下載的是高清視頻 return jsonData
在視頻下載中遇到了些小問題,可參考:https://www.zhihu.com/question/41132103
完整代碼:
# -*- coding: UTF8 -*- from pyquery import PyQuery as pq import sys, os import json import requests from contextlib import closing class SaveVideo(): LessonList = [] def __init__(self): pass # 獲取課時的列表 def getLesson(self): try: # 該網站請求時必須帶上User-Agent d = self.pq('http://ptr.chaoxing.com/course/2533204.html') DomTree = d('.p20 ul li a') for my_div in DomTree.items(): URL = 'http://ptr.chaoxing.com' + my_div.attr('href') # 課時detail URL l = my_div.find('.l').html() # 課時章節NO r = my_div.find('.r').html() # 課時Name self.LessonList.append({'url': URL, "name": l + r}) except Exception as e: print(e) if (len(self.LessonList) > 0): if not os.path.exists('./Video'): os.makedirs('./Video') for lesson in self.LessonList: video = self.getVideo(lesson['url']) if video: self.downloadVideo(video, lesson['name']) print('完成下載!!!') def getVideo(self, url): ''' 獲取視頻 ''' d = self.pq(url) DomTree = d("iframe") jsonData = DomTree.attr('data') video='' try: objectid = json.loads(jsonData)['objectid'] # 獲取下載資源視頻的對象 downloadUrl = self.pq('http://ptr.chaoxing.com/ananas/status/' + objectid) # 獲取下載資源的URL video = json.loads(downloadUrl.html())['httphd'] # 在這里,我們要下載的是高清視頻 except: pass return video def pq(self, url, headers=None): ''' 將PyQuery 請求寫成方法 ''' d = pq(url=url, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}) return d def downloadVideo(self, url, file_name=''): ''' 下載視頻 :param url: 下載url路徑 :return: 文件 ''' with closing(requests.get(url, stream=True)) as response: chunk_size = 1024 content_size = int(response.headers['content-length']) file_D='./Video/' + file_name + '.mp4' if(os.path.exists(file_D) and os.path.getsize(file_D)==content_size): print('跳過'+file_name) else: progress = ProgressBar(file_name, total=content_size, unit="KB", chunk_size=chunk_size, run_status="正在下載",fin_status="下載完成") with open(file_D, "wb") as file: for data in response.iter_content(chunk_size=chunk_size): file.write(data) progress.refresh(count=len(data)) ''' 下載進度 ''' class ProgressBar(object): def __init__(self, title, count=0.0, run_status=None, fin_status=None, total=100.0, unit='', sep='/', chunk_size=1.0): super(ProgressBar, self).__init__() self.info = "[%s] %s %.2f %s %s %.2f %s" self.title = title self.total = total self.count = count self.chunk_size = chunk_size self.status = run_status or "" self.fin_status = fin_status or " " * len(self.statue) self.unit = unit self.seq = sep def __get_info(self): # 【名稱】狀態 進度 單位 分割線 總數 單位 _info = self.info % ( self.title, self.status, self.count / self.chunk_size, self.unit, self.seq, self.total / self.chunk_size, self.unit) return _info def refresh(self, count=1, status=None): self.count += count # if status is not None: self.status = status or self.status end_str = "\r" if self.count >= self.total: end_str = '\n' self.status = status or self.fin_status print(self.__get_info(), end=end_str) if __name__ == '__main__': C = SaveVideo() C.getLesson() sys.exit()
通過pyinstaller打包
import sys if __name__ == '__main__': from PyInstaller import __main__ params = ['-F','-c','--noupx', '--icon=favicon.ico', 'save.py'] __main__.run(params)
查看:
4:分享課程視頻
已經將視頻打包分享到雲盤中,有興趣的可以在這 下載