When crawling video sites, many videos use blob url to hide the source address. Through F12, you can find the download address of m3u8 corresponding to the request, but the amount of crawled data is very large. Use f12 to analyze each one. Obviously impossible, this article will parse the blob URL through selenium chrome to get the source m3u8 address
Example in this article: twitter preview link.
url : https://ton.twimg.com/ads-manager/tweet-preview/index.html?data=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
Selenium intercepts all requests, which is equivalent to the network all function in F12
Parse the request log, get the m3u8 address, download the video through ffmpy3, and finally parse the video through opencv to get the attribute value of the video
pip install selenium ffmpy3 opencv-python
code:
代码语言:javascript复制from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import json
import re
from selenium.webdriver.chrome.options import Options
from ffmpy3 import FFmpeg
import cv2
def download_video(video_m3u8_url):
try:
outputs_path = r'/data/test.mp4'
a = FFmpeg(inputs={video_m3u8_url: None}, outputs={outputs_path: None})
a.run()
return outputs_path
except Exception as e:
print(e)
def parse_blob(url):
chromeOpitons = Options()
prefs = {
"profile.managed_default_content_settings.images": 1,
"profile.content_settings.plugin_whitelist.adobe-flash-player": 1,
"profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player": 1,
}
chromeOpitons.add_experimental_option('prefs', prefs)
d = DesiredCapabilities.CHROME
d['goog:loggingPrefs'] = {'performance': 'ALL'}
chromeOpitons.add_experimental_option('w3c', False)
browser = webdriver.Chrome(desired_capabilities=d, chrome_options=chromeOpitons)
try:
browser.get(url)
browser.implicitly_wait(30)
performance_log = browser.get_log('performance')
for i in performance_log:
response = json.loads(i.get('message'))
if response.get('message').get('method') == 'Network.requestWillBeSentExtraInfo':
message = eval(i.get('message'))
headers = message.get('message').get('params').get('headers')
path = headers.get(':path')
if path:
find_content = re.findall(r'.m3u8', path)
if find_content:
authority = headers.get(':authority')
method = headers.get(':method')
scheme = headers.get(':scheme')
video_m3u8_url = scheme '://' authority path
return video_m3u8_url
except Exception as e:
print(e)
finally:
browser.quit()
def get_video_attribute_value(video_path):
try:
cap = cv2.VideoCapture(video_path)
fps = int(round(cap.get(cv2.CAP_PROP_FPS)))
print('fps:', fps)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
print('width:', width)
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print('height:', height)
frame_counter = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
cap.release()
cv2.destroyAllWindows()
print('frame_counter:', frame_counter)
duration = frame_counter / fps
print('duration:', duration)
except Exception as e:
print(e)
if __name__ == '__main__':
url = 'https://ton.twimg.com/ads-manager/tweet-preview/index.html?data=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'
video_m3u8_url = parse_blob(url)
if video_m3u8_url:
video_path = download_video(video_m3u8_url)
if video_path:
get_video_attribute_value(video_path)
result:
fps: 24
width: 1280
height: 720
frame_counter: 4666
duration: 194.41666666666666