爬取視頻的時候發現,現在的視頻都是經過加密(m3u8),不再是mp4或者avi鏈接直接在網頁顯示,都是經過加密形成ts文件分段進行播放。
今天就教大家如果通過python爬取下載m3u8加密視頻。
http://www.caisetv.com/
http://www.caisetv.com/dongzuopian/chaidanzhuanjia/0-1.html
在視頻播放的頁面,通過F12可以查看網絡數據包
https://xigua-cdn.haima-zuida.com/20210219/19948_fcbc225a/1000k/hls/index.m3u8
這里的ts就電影的加密分段視頻
https://xigua-cdn.haima-zuida.com/20210219/19948_fcbc225a/1000k/hls/
上面的m3u8鏈接掉index.m3u8后,在拼上075a34cccdd000000.ts等ts名稱就是分段視頻的鏈接
如下所示:
https://xigua-cdn.haima-zuida.com/20210219/19948_fcbc225a/1000k/hls/075a34cccdd000000.ts
通過瀏覽器把這個分段視頻下載后打開:
所以只要把所有的ts下載并合并就是完整的電影視頻!!!
剛剛已經把ts的所有名稱下載下來了
接下來通過python代碼去讀取這個文件,提取出名稱,拼接鏈接后下載保存到一個文件夾里!
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0',}
###下載ts文件
def download(url,name):
r = requests.get(url, headers=headers)
with open(name+"", "wb") as code:
code.write(r.content)
with open("index.m3u8","r") as f:
ts_list = f.readlines()
#去掉前面沒用的信息
ts_list = ts_list[5:]
urlheader="https://xigua-cdn.haima-zuida.com/20210219/19948_fcbc225a/1000k/hls/"
count = 0
for i in ts_list:
if "#" not in i:
i = i.replace("\n","")
download(urlheader+""+i,"cdzj2/"+str(count)+".ts")
count = count+1
print(count)
這樣就可以把ts文件全部下載下來,但是一個一個下載很慢,下面通過多線程下載,提升下載速度!!!
for i in ts_list:
if "#" not in i:
i = i.replace("\n","")
n = i[-7:]
threading.Thread(target=download, args=(urlheader+""+i,"cdzj2/"+str(n),)).start()
#download(urlheader+""+i,"cdzj2/"+str(count)+".ts")
通過多線程很快就可以將這些ts文件下載到本地!!!
copy /b *.ts new.mp4
通過這個命令(cmd終端中運行),在含有ts文件的文件夾中就可以將ts文件合并(按名稱順序進行排列合并),并保存成new.mp4
1.分析m3u8加密文件
2.python下載ts文件
3.cmd合并ts保存成mp4格式
程不是科學,而是一門手藝
Python 具有豐富的解析庫和簡潔的語法,所以很適合寫爬蟲。這里的爬蟲指的是爬取網頁的“蟲子”。簡而言之,爬蟲就是模擬瀏覽器訪問網頁,然后獲取內容的程序。
爬蟲工程師是個很重要的崗位。爬蟲每天爬取數以億計的網頁,供搜索引擎使用。爬蟲工程師們當然不是通過單擊鼠標右鍵并另存的方式來爬取網頁的,而會用爬蟲“偽裝”成真實用戶,去請求各個網站,爬取網頁信息。
本文選自《Python基礎視頻教程》一書,每一小節都給出了視頻講解,配合視頻微課帶你快速入門Python。
( 正 文 )
1、初識 HTTP :4行代碼寫一個爬蟲
超文本傳輸協議(HyperText Transfer Protocol,HTTP)是網絡中最常見的網絡傳輸協議。常見網站的網址大都以 http 開頭或者以 https 開頭,https 在 http 基礎上做了一層加密的協議。
通常情況下,在瀏覽器里給服務器發送 http 或 https 請求,服務器拿到請求后會向瀏覽器返回相應的結果(response),瀏覽器解析、潤色后呈現給用戶。
寫爬蟲沒有那么難,下面用 4 行代碼寫一個爬蟲。在 first_spider.py 文件中寫入以下代碼:
1from urllib import request
2page = request.urlopen('http://www.yuqiaochuang.com/')
3ret = page.read()
4print(ret)
python first_spider.py 運行后,會看到屏幕上打印出了頁面的源代碼,這短短 4行就是一個爬蟲。
從本質上來說,這和打開瀏覽器、輸入網址去訪問沒有什么區別,只不過后者是借助瀏覽器獲取頁面內容,而爬蟲則是用原生的 HTTP 獲取內容。屏幕上打印的源代碼和在 Chrome 瀏覽器中單擊鼠標右鍵,然后在彈出的快捷菜單中單擊“查看網頁源代碼”是一樣的。
在此可以看到,網頁的源代碼是由很多標簽組成的。
尖括號包圍的就是一個標簽,如<head>、<body>和<div>。標簽內可以有屬性,例如<html lang="zh-CN">,有一個值為"zh-CN"的 lang 屬性,表示語言是中文。標簽通常是成對出現的,例如,<title>Python 教程 - 雨敲窗個人博客</title>。“Python 教程 - 雨敲窗個人博客”被<title>和</title>包括起來,包括起來的部分被稱為標簽的內容。
2、正則表達式
前面用 4 行代碼寫了一個爬蟲,運行成功后可以看到爬取的內容。不過,這卻是一個大塊的內容,如果想提取其中的某些字段該怎么辦?
常用的做法就是用正則表達式(Regular Expression)提取。
對初學編程的人來說,很難理解正則表達式是“何方神圣”。其實大家可以把正則表達式當作一個提取器來看,通過制定一些規則,從字符串中提取出想要的內容。
下面先看看正則表達式的幾個簡單用法。在regular_expression.py 文件中寫入以下代碼:
1import re # 正則表達式的包
2
3m = re.findall("abc", "aaaaabcccabcc")
4print(m)
5m = re.findall("\d", "abc1ab2c")
6print(m)
7m = re.findall("\d\d\d\d", "123abc1234abc")
8print(m)
9m = re.findall(r"<div>(.*)</div>", "<div>hello</div>")
10print(m)
11m = re.findall(r"<div>(.*)</div>", "<div>hello</div><div>world</div>")
12print(m)
13m = re.findall(r"<div>(.*?)</div>", "<div>hello</div><div>world</div>")
14print(m)
python regular_expression.py 的運行結果如下:
1['abc', 'abc']
2['1', '2']
3['1234']
4['hello']
5['hello</div><div>world']
6['hello', 'world']
首先,需要“import re”,以引用正則表達式模塊,這樣才能使用正則表達式庫中的方法。
之后,上述代碼中的 m = re.findall("abc", "aaaaabcccabcc") 從"aaaaabcccabcc"中提取出"abc",返回的 m 是一個列表,里面有兩個'abc'。
m = re.findall("\d", "abc1ab2c") 從"abc1ab2c"中提取出單個數字,"\d"表示提取的目標字符是數字,返回的結果是['1', '2'] 。
m = re.findall("\d\d\d\d", "123abc1234abc")提取 4 個連續的數字,返回的結果是['1234']。
m = re.findall(r"<div>(.*)</div>", "<div>hello</div>")從"<div>hello</div>"中提取出<div>和</div>中間的內容,括號括起來就表示提取括號中的內容,“.”表示可以匹配任何字符,“*”表示可以匹配任意多個字符,返回的結果是['hello']。
m = re.findall(r"<div>(.*)</div>", "<div>hello</div><div>world</div>")從"<div> hello</div><div>world</div>" 中 提 取 div 中 的 內 容 , 返 回 的 結 果 是 ['hello</div> <div>world']。與上一行的提取規則相同,為什么沒有單獨提取出 hello 和 world 呢?因為正則表達式默認用的是貪婪匹配,所謂貪婪匹配就是能匹配多長就匹配多長。"<div>hello</div><div>world</div>"就從頭匹配到了末尾,提取出來一個大長串。
m = re.findall(r"<div>(.*?)</div>", "<div>hello</div><div>world</div>") 在括號中加入一個“?”就表示以非貪婪匹配去提取,即能匹配多短就匹配多短,所以提取出來的結果是['hello', 'world']。
結合前面的幾個例子,可以總結出正則表達式中最常用的 findall 方法的用法。第一個參數是定義的提取語法,第二個參數是原始字符串。返回的是一個列表,列表里是符合提取規則的字符串。
關于正則表達式更詳細的語法,大家可以借助搜索引擎,搜索“菜鳥教程正則表達式”。
3、爬取靜態頁面的網站
還 記 得 前 面 寫 的 那 個 只 有 4 行 代 碼 的 爬 蟲 嗎 ?它 爬 取 了 “ http://www. yuqiaochuang.com”整個頁面的內容。在學過正則表達式之后,就可以提取想要的內容。
還是以爬取這個博客為例,提取這個博客上文章列表的標題。
在爬取一個網站前,通常要先分析一下這個網站是否是靜態頁面。靜態頁面是指,網站的源代碼里包含所有可見的內容,也就是所見即所得。常用的做法是,在瀏覽器中單擊鼠標右鍵,然后在彈出的快捷菜單中選擇“顯示網頁源代碼”,推薦使用 Chrome 瀏覽器。
類似上圖中的代碼,就是網頁的源代碼,這里能夠看到該博客中文章的標題和網址。
接下來使用正則表達式提取各標題。前面那個只有 4 行代碼的爬蟲用的是標準庫里的urllib 庫。推薦使用 requests 庫,其具有更強大、更易用的功能。使用 pip 安裝,在 PowerShell 命令行窗口中輸入以下命令:
1pip install requests
上述代碼的前兩行先將要使用的庫“import”進來,然后調用 requests 庫中的 get方法獲取頁面(page)。之后使用 re.findall 方法提取所有的標題,page.text 即頁面的源代碼內容。將頁面中以“<p><a.*>”開頭、“</a></p>”結尾的標題提取出來。
若欲了解更多與 requests 庫相關的資料,可以借助搜索引擎,搜索“python requests”查看具體用法。
4、beautifulsoup4
beautifulsoup4 也是一個 Python 的第三方庫,提供解析網頁的功能。其有些類似于正則表達式,但是比正則表達式的語法更加優雅和便利。
在 PowerShell 命令行窗口中輸入以下命令安裝 beautifulsoup4:
1pip install beautifulsoup4
還是以“http://www.yuqiaochuang.com”的網頁源代碼為例,提取這些文章的標題和鏈接。在 blog_spider_use_bs4.py 文件中寫入以下代碼:
1from bs4 import BeautifulSoup
2import requests
3page = requests.get('http://www.yuqiaochuang.com/')
4soup = BeautifulSoup(page.text, features="html.parser")
5all_title = soup.find("div", "entry-content").find_all("a")
6for title in all_title:
7 print(title["href"], title.string)
“from bs4 import BeautifulSoup ”將 BeautifulSoup 引 進 程 序 。
“ soup = BeautifulSoup(page.text, features="html.parser")”聲明了一個解析結構 soup。這里解析的是爬取的網頁源代碼 page.text;features 指定了“html.parser”這個默認的解析器。
在此可以看到,想爬取的標題都在 class 是“entry-content”的 div 塊中。“soup.find("div", "entry-content")”用于提取 class 是“entry-content”的 div 塊。緊接著調用 find_all,爬取所有標題的標簽。find_all 方法返回的是一個列表,這個列表中的元素是符合查找條件的標簽。
然后寫一個循環,把標題的標簽打印下來。通過調用 title["href"]可以獲取標簽中屬性的值—鏈接。title.string 則是獲取標簽中的內容。
5、爬取圖片
如果網站中僅有枯燥的文字,則很難吸引用戶持續觀看,所以,好的網站都是圖文并茂的。如果想將圖片也爬取下來,該怎么辦呢?爬蟲當然也可以爬取圖片,就像在用瀏覽器訪問網站時,可以在圖片上單擊鼠標右鍵,然后在彈出的快捷菜單中選擇“另存為”選項去下載圖片一樣。
利用 requests 庫也可以抓取圖片。還是以爬取“http://www.yuqiaochuang.com”為例,這次爬取網站左上角的圖片。在左上角的圖片上面單擊鼠標右鍵,接著在彈出的快捷菜單中選擇“檢查”。
在此可以看到,瀏覽器下方區域出現了一個工具欄,里面突出顯示的部分就是圖片地址的網頁源代碼。
在此可以看到,圖片是以“img”標簽開頭的。這個“img”標簽在 class 是“profile”的 div 中,因此可以使用 requests+beautifulsoup4 提取圖片的地址。
在 image_spider.py文件中寫入以下代碼:
1from bs4 import BeautifulSoup
2import requests
3
4page = requests.get('http://www.yuqiaochuang.com/')
5soup = BeautifulSoup(page.text, features="html.parser")
6img = soup.find("div", "profile").find("img")
7print(img["src"])
python image_spider.py 的運行結果如圖下。
soup.find("div", "profile").find("img") 直接提取了 img 標簽,然后打印 img 標簽中的 src 字段,在此可以看到圖片地址被提取了出來。但是,你有沒有發現這個鏈接地址似乎少了一些前綴?
沒錯,少了"http://www.yuqiaochuang.com"。有些網站的圖片會省略前綴,在爬取時補上即可。接下來正式爬取圖片,在 image_spider.py 文件中寫入以下代碼:
1from bs4 import BeautifulSoup
2import requests
3
4page = requests.get('http://www.yuqiaochuang.com/')
5soup = BeautifulSoup(page.text, features="html.parser")
6img = soup.find("div", "profile").find("img")
7
8image_url = "http://www.yuqiaochuang.com" + img["src"]
9img_data = requests.get(image_url)
10img_file = "image.png"
11
12f = open(img_file, 'wb')
13f.write(img_data.content)
14f.close()
python image_spider.py 運行后,可以看到當前文件夾下多了一個“image.png”圖片文件。
在獲取圖片地址后,調用 requests 的 get 方法,獲取圖片的請求數據,然后調用寫文件的方法,將圖片數據寫入到文件中。
前面爬取文字時,調用的是 text 字段,為什么這里變成了 content 字段呢?
這是因為 content 是最原始的數據,二進制的數據流;而 text 則是經過編碼的數據。在寫文件時,參數也不是'w',而是'wb'。'wb'的意思是,寫入的數據是二進制數據流,而不是經過編碼的數據。爬取圖片和爬取文字的本質,都是根據網頁鏈接發送請求,然后獲取內容,只不過圖片需要用二進制的形式保存到本地文件中。
—— 完 ——
對編程充滿向往和好奇,卻不知如何上手嗎?
博文視點學院精品課程【每天5分鐘:Python基礎視頻教程(書+課)】帶你打開編程世界的大門!
今日僅需39元,你將獲得:
Python中爬取網站上的視頻通常涉及幾個步驟:定位視頻資源的URL,下載視頻文件,以及處理可能的登錄、反爬蟲機制等。以下是一個基本的流程和代碼示例,使用requests和BeautifulSoup庫來獲取網頁中的視頻鏈接,然后使用urllib或requests來下載視頻。
首先,確保你已經安裝了必要的庫:
Bash
深色版本
1pip install requests beautifulsoup4
接下來,你可以使用以下代碼框架來抓取視頻:
import requests
from bs4 import BeautifulSoup
import os
def fetch_video_url(url):
# 發送HTTP請求獲取網頁內容
response = requests.get(url)
# 解析HTML文檔
soup = BeautifulSoup(response.text, 'html.parser')
# 查找視頻標簽
video_tag = soup.find('video')
# 獲取視頻源鏈接
video_url = video_tag['src'] if video_tag else None
return video_url
def download_video(video_url, save_path):
# 檢查目錄是否存在,不存在則創建
if not os.path.exists(os.path.dirname(save_path)):
os.makedirs(os.path.dirname(save_path))
# 發送請求并下載視頻
with open(save_path, 'wb') as f:
response = requests.get(video_url, stream=True)
total_length = response.headers.get('content-length')
if total_length is None: # no content length header
f.write(response.content)
else:
dl = 0
total_length = int(total_length)
for data in response.iter_content(chunk_size=4096):
dl += len(data)
f.write(data)
done = int(50 * dl / total_length)
print('\r[%s%s]' % ('=' * done, ' ' * (50-done)), end='')
if __name__ == "__main__":
url = "http://example.com/video-page"
video_url = fetch_video_url(url)
if video_url:
save_path = "./videos/video.mp4"
download_video(video_url, save_path)
print("Video downloaded successfully.")
else:
print("No video found on the page.")
注意事項:
請確保在使用網絡爬蟲時尊重網站的robots.txt文件,不要對網站服務器造成過大的負擔,遵守道德和法律規定。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。