четверг, 12 июля 2007 г.

Полезный скрипт для извлечения видео из кэша Firefox (под Win)

Часто поднимается вопрос, как скачать видео с youtube.com и других подобных сайтов, есть даже сайты, типа youtubex.com специально предназначенные для скачивания локально .flv - файлов, есть плагины для Firefox.
Я использую другой метод, правда, он может помочь Вам только в случае если вы используете Firefox, как и я :-)
Представляю вашему вниманию скрипт (python) который ползет в кэш браузера Mozilla Firefox и достает оттуда уже просмотренные вами видео-файлы, на данный момент он распознает форматы FLV (именно в этом формате хранится большинство видео на youtube) и SWF (флэш-файлы). Извлеченные файлы копируются в специальную директорию, и к ним присоединяется нужное расширение.
Собственно, сам скрипт:



# file: getflv.py
import os
import os.path
import shutil
import time

REG_DIR = 'REG'
DATE_FORMAT = "%Y_%m_%d, %H-%M-%S"

OUTDIRS = {
'FLV': 'flv',
'SWF': 'swf',
}

def createDirIfNeeded(fullPath):
if not os.path.exists(fullPath):
os.makedirs(fullPath)

def createDirsIfNeeded():
for dir in OUTDIRS.itervalues():
createDirIfNeeded(dir)

createDirIfNeeded(REG_DIR)

def fileSize(fPath):
return os.stat(fPath).st_size

def getFileType(path):
s = open(path).read(30)

if s[:3] == 'FLV':
return 'FLV'
elif s[:3] == 'FWS':
return 'SWF'

return None

def isInReg(f, sourcePath):
# name and size matches
return (f in os.listdir(REG_DIR) and open(REG_DIR + '/' + f).read() == str(fileSize(sourcePath)))

def formDirName():
return time.strftime(DATE_FORMAT)

def doCopy(fromPath, outDirName, fName, fileType):
print 'Copying %s video: %s of size %s' % (fileType, fName, fileSize(fromPath))

ext = fileType.lower()

createDirIfNeeded(OUTDIRS[fileType] + '/' + outDirName)

shutil.copyfile(fromPath, OUTDIRS[fileType] + '/' + outDirName + '/' + fName + '.' + ext)

# add to reg
open(REG_DIR + '/' + fName, 'w').write(str(fileSize(fromPath)))

def getFirefoxCacheDir():
profileDir = os.environ['USERPROFILE']
firefoxProfile = profileDir + '/Local Settings/Application Data/Mozilla/Firefox/Profiles'

files = os.listdir(firefoxProfile)
assert len(files) == 1

hashDir = firefoxProfile + '/' + files[0]
assert os.path.isdir(hashDir)

return hashDir + '/Cache'

def main():
createDirsIfNeeded()
outDirName = formDirName()
cacheDir = getFirefoxCacheDir()
files = os.listdir(cacheDir)

for f in files:
path = cacheDir + '/' + f

fileType = getFileType(path)

if fileType in ('FLV', 'SWF'):
if not isInReg(f, path): # path to determine size
# copying
doCopy(path, outDirName, f, fileType)

if __name__ == '__main__':
main()


Немного поясню принцип работы. Конфигурировать скрипт никак не требуется. После запуска (в первый раз) будет созданы директории с именами swf, flv и REG в директории со скриптом. Первые две будут, разумеется, использоваться для наполнения извлеченными видео-файлами, а директория REG имеет служебное назначение. В ней хранится список выкачанных файлов и их размеров, чтоб при следующем запуске скрипта они повторно не выкачивались. При каждом запуске в случае обнаружения в кэше новых видео-файлов в соответствующей директории (flv, swf) будет создана новая директория с именем составленным из текущего таймстемпа, в нее будут скопированны файлы данного типа.
Директория кэша браузера находится исходя из настройки переменной окружения %USERPROFILE% (разумеется, речь идет о Windows). Файлы в кэше браузера распознаются по сигнатурам начала файла (flv-файл начинается на 3 байта 'FLV', а flash-файл на 'FWS'). Собственно по сигнатурам можно распознавать и другие файлы, было бы хорошо сделать mov, wmv, avi, mp3 но там сигнатуры посложнее. Если кто сделает - обязательно дайте знать, буду оч. благодарен! )
Да, и совет сделать кэш браузера слегка побольше (100 - 150 мб).

5 коммент.:

Анонимный комментирует...

но как запустить скрипт?

Анонимный комментирует...

Привет. Скрипт не работает для flv - могу прислать файл на email. Сможешь поправить?

Анонимный комментирует...

Работает, оч. полезная тулза!

Анонимный комментирует...

Владимир...
Поставил Питон последней версии
для Win32
Запустил Ваш скрипт...
в DOS-экране выдает

main()
^
IndentationError: expected an indented block

Что следует сделать?
как поравить синтаксис?

Владимир, а Вы занимались усовершенствованием данного скипта,
как аддона, помогающе пользовать кеш лиса?
Может быть у Вас есть новые наработки?

Спасибо Вам за труд))

Анонимный комментирует...

новый год уже вот-вот ))