1. 程式人生 > >Python3從零開始爬取今日頭條的新聞【五、解析頭條視訊真實播放地址並自動下載】

Python3從零開始爬取今日頭條的新聞【五、解析頭條視訊真實播放地址並自動下載】

本文目錄:

1.目標

本文目標是自動解析頭條的視訊新聞,通過第三方解析網站得到其真實的下載地址並自動下載到本地

*至於如何通過py自動解析、檢視大咖個人中心的視訊頁籤內容、自動翻頁載入,請移步 《Python3從零開始爬取今日頭條的新聞【四、模擬點選切換tab標籤獲取內容】》 我們檢視央視網新聞這個大V的主頁:央視網新聞

所以我們實際上只要從視訊列表頁面解析得到視訊列表的/item/視訊id編號 ,然後通過selenium 驅動瀏覽自動輸入到上面的解析網站,獲取解析結果即可。

OK,思路有了,下面開搞~

2.實現

獲取到一系列的頭條視訊內部地址後,通過瀏覽器模擬輸入內部地址解析得到真實的下載地址。

這裡講下前幾篇文章沒遇到的一個場景:自動輸入內容到瀏覽器的輸入框,這個怎麼實現呢?核心程式碼如下:
def getRealPalyUrl(self, media_url, id, title, author):
        
        # 查詢視訊地址輸入框,自動輸入內容
        input_els = self.browser.find_element_by_xpath('//div[contains(@class, "input-group")]/input[contains(@placeholder, "請輸入視訊地址")][1]')
        input_els.
send_keys('http://www.toutiao.com' + media_url) parse_btn = self.browser.find_element_by_xpath('//div[contains(@class, "input-group")]/div/button[contains(@class, "btn")][@type="button"][1]') parse_btn.click() try: videoInfo = WebDriverWait(self.browser, 10).until(
EC.presence_of_element_located((By.XPATH, '//div[@class="thumbnail"]/div[@class="caption"]/p[1]/a')) ) page = self.browser.page_source page_etree = etree.HTML(page) video_a = page_etree.xpath('//div[@class="thumbnail"]/div[@class="caption"]/p[1]/a[last()]') if video_a and len(video_a) > 0: video_a = video_a[0] # 得到下載地址,視訊清晰度描述 download_url = video_a.xpath('./@href')[0] desc = '' video_desc = video_a.xpath('./text()') if video_desc and len(video_desc) > 0 and ('視訊下載' in video_desc[0]): desc = str(video_desc[0]).replace('視訊下載', '') # 儲存到資料庫 updateVideoInfo2DB(id, download_url, desc) # 下載到本地 dl = DownloadFile() dl.download(download_url, title, author) except Exception as ex: print(ex)

函式getRealPalyUrl(self, media_url, id, title, author):media_url 就是前面說的頭條內部視訊地址比如:/item/6606468202769678855/

 input_els = self.browser.find_element_by_xpath('//div[contains(@class, "input-group")]/input[contains(@placeholder, "請輸入視訊地址")][1]')
 input_els.send_keys('http://www.toutiao.com' + media_url)

上面第一行是為了找到“請輸入視訊地址”這個輸入框,第二行是模擬鍵盤輸入完整的地址內容。

parse_btn = self.browser.find_element_by_xpath('//div[contains(@class, "input-group")]/div/button[contains(@class, "btn")][@type="button"][1]')
parse_btn.click()

上面第一行是為了找到 解析視訊 這個按鈕,然後模擬滑鼠點選按鈕向伺服器傳送請求。

 videoInfo = WebDriverWait(self.browser, 10).until(
                EC.presence_of_element_located((By.XPATH, '//div[@class="thumbnail"]/div[@class="caption"]/p[1]/a'))
            )

接下來這個程式碼是在點選解析視訊按鈕之後等待頁面出現下載地址再進行下一步,這裡是最多等待10s,一般情況下都足夠了。後面就是解析得到具體的downloadurl了,然後通過這個真實的url下載到本地。其中用到的下載類DownloadFile的程式碼如下:

#!/usr/bin/python3
# -*- coding:utf-8 -*-

import os
import sys
import time
from urllib import request

class DownloadFile(object):


    def __init__(self):
        self.start_time = time.time()

    '''
    urllib.urlretrieve 的回撥函式:
    def callbackfunc(blocknum, blocksize, totalsize):
        @blocknum:  已經下載的資料塊
        @blocksize: 資料塊的大小
        @totalsize: 遠端檔案的大小
    '''
    def __Schedule(self, blocknum, blocksize, totalsize):
        speed = (blocknum * blocksize) / (time.time() -self.start_time)
        # speed_str = " Speed: %.2f" % speed
        speed_str = " Speed: %s" % self.__format_size(speed)
        recv_size = blocknum * blocksize
     
        
        # 設定下載進度條
        f = sys.stdout
        pervent = recv_size / totalsize
        percent_str = "%.2f%%" % (pervent * 100)
        n = round(pervent * 50)
        s = ('█' * n).ljust(50, '-')
        f.write(percent_str.ljust(8, ' ') + '█' + s + '█' + speed_str)
        f.flush()
        f.write('\r')
    
    # 位元組bytes轉化K\M\G
    def __format_size(self, bytes):
        try:
            bytes = float(bytes)
            kb = bytes / 1024
        except:
            print("傳入的位元組格式不對")
            return "Error"
        if kb >= 1024:
            M = kb / 1024
            if M >= 1024:
                G = M / 1024
                return "%.3fG" % (G)
            else:
                return "%.3fM" % (M)
        else:
            return "%.3fK" % (kb)
    
    def __downloadFile(self, url, folder, fileName):
        
        print("正在下載: %s" % fileName)
        print(url)
        request.urlretrieve(url, folder + "\\" + fileName, self.__Schedule)

    def download(self, url, title, author):
       
        curFolder = 'H:\\py\\downloads\\' + author

        if not os.path.exists(curFolder):
            try:
                os.makedirs(curFolder)
            except Exception as ex:
                print(ex)
        else:
            try:
                # 下載檔案
                self.__downloadFile(url, curFolder, title + '.mp4')
            except Exception as ex:
                print(ex)

全文完結,後續實現用其它框架來爬蟲新聞資源。敬請期待~

參考資料: