python爬蟲實戰:利用scrapy,短短50行代碼下載整站短視頻

来源:https://www.cnblogs.com/mamingqian/archive/2018/10/28/9867697.html
-Advertisement-
Play Games

近日,有朋友向我求助一件小事兒,他在一個短視頻app上看到一個好玩兒的段子,想下載下來,可死活找不到下載的方法。這忙我得幫,少不得就抓包分析了一下這個app,找到了視頻的下載鏈接,幫他解決了這個小問題。 因為這個事兒,勾起了我另一個念頭,這不最近一直想把python爬蟲方面的知識梳理梳理嗎,乾脆藉機 ...


近日,有朋友向我求助一件小事兒,他在一個短視頻app上看到一個好玩兒的段子,想下載下來,可死活找不到下載的方法。這忙我得幫,少不得就抓包分析了一下這個app,找到了視頻的下載鏈接,幫他解決了這個小問題。

因為這個事兒,勾起了我另一個念頭,這不最近一直想把python爬蟲方面的知識梳理梳理嗎,乾脆藉機行事,正湊著短視頻火熱的勢頭,做一個短視頻的爬蟲好了,中間用到什麼知識就理一理。

我喜歡把事情說得很直白,如果恰好有初入門的朋友想瞭解爬蟲的技術,可以將就看看,或許對你的認識會有提升。如果有高手路過,最好能指點一二,本人不勝感激。

一、撕開爬蟲的面紗——爬蟲是什麼,它能做什麼

爬蟲是什麼

爬蟲就是一段能夠從互聯網上高效獲取數據的程式。

我們每天都在從互聯網上獲取數據。當打開瀏覽器訪問百度的時候,我們就從百度的伺服器獲取數據,當拿起手機線上聽歌的時候,我們就從某個app的伺服器上獲取數據。簡單的歸納,這些過程都可以描述為:我們提交一個Request請求,伺服器會返回一個Response數據,應用根據Response來渲染頁面,給我們展示數據結果。

爬蟲最核心的也是這個過程,提交Requests——〉接受Response。就這樣,很簡單,當我們在瀏覽器里打開一個頁面,看到頁面內容的時候,我們就可以說這個頁面被我們採集到了。

只不過當我們真正進行數據爬取時,一般會需要採集大量的頁面,這就需要提交許多的Requests,需要接受許多的Response。數量大了之後,就會涉及到一些比較複雜的處理,比如併發的,比如請求序列,比如去重,比如鏈接跟蹤,比如數據存儲,等等。於是,隨著問題的延伸和擴展,爬蟲就成為了一個相對獨立的技術門類。

但它的本質就是對一系列網路請求和網路響應的處理。

爬蟲能做什麼

爬蟲的作用和目的只有一個,獲取網路數據。我們知道,互聯網是個數據的海洋,大量的信息漂浮在其中,想把這些資源收歸己用,爬蟲是最常用的方式。特別是最近幾年大樹據挖掘技術和機器學習以及知識圖譜等技術的興盛,更是對數據提出了更大的需求。另外也有很多互聯網創業公司,在起步初期自身積累數據較少的時候,也會通過爬蟲快速獲取數據起步。

二、python爬蟲框架scrapy——爬蟲開發的利器

如果你剛剛接觸爬蟲的概念,我建議你暫時不要使用scrapy框架。或者更寬泛的說,如果你剛剛接觸某一個技術門類,我都不建議你直接使用框架,因為框架是對許多基礎技術細節的高級抽象,如果你不瞭解底層實現原理就直接用框架多半會讓你雲里霧裡迷迷糊糊。

在入門爬蟲之初,看scrapy的文檔,你會覺得“太複雜了”。當你使用urllib或者Requests開發一個python的爬蟲腳本,並逐個去解決了請求頭封裝、訪問併發、隊列去重、數據清洗等等問題之後,再回過頭來學習scrapy,你會覺得它如此簡潔優美,它能節省你大量的時間,它會為一些常見的問題提供成熟的解決方案。

scrapy數據流程圖

這張圖是對scrapy框架的經典描述,一時看不懂沒有關係,用一段時間再回來看。或者把本文讀完再回來看。

在一些書上會把爬蟲的基本抓取流程概括為UR2IM,意思是數據爬取的過程是圍繞URL、Request(請求)、Response(響應)、Item(數據項)、MoreUrl(更多的Url)展開的。上圖的綠色箭頭 體現的正是這幾個要素的流轉過程。圖中涉及的四個模塊正是用於處理這幾類對象的:

  • Spider模塊:負責生成Request對象、解析Response對象、輸出Item對象
  • Scheduler模塊:負責對Request對象的調度
  • Downloader模塊:負責發送Request請求,接收Response響應
  • ItemPipleline模塊:負責數據的處理
  • scrapy Engine負責模塊間的通信

各個模塊和scrapy引擎之間可以添加一層或多層中間件,負責對出入該模塊的UR2IM對象進行處理。

scrapy的安裝

參考官方文檔,不再贅述。官方文檔:https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/install.html

三、scrapy實戰:50行代碼爬取全站短視頻

python的優雅之處在於能夠讓開發者專註於業務邏輯,花更少的時間在枯燥的代碼編寫調試上。scrapy無疑完美詮釋了這一精神。

開發爬蟲的一般步驟是:

  • 確定要爬取的數據(item)
  • 找到數據所在頁面的url
  • 找到頁面間的鏈接關係,確定如何跟蹤(follow)頁面

那麼,我們一步一步來。

既然是使用scrapy框架,我們先創建項目:

scrapy startproject DFVideo

 緊接著,我們創建一個爬蟲:

scrapy genspider -t crawl DfVideoSpider eastday.com

這是我們發現在當前目錄下已經自動生成了一個目錄:DFVideo

目錄下包括如圖文件:

 

 

 

 

 

 

 

 

spiders文件夾下,自動生成了名為DfVideoSpider.py的文件。

 

 

 

 

 

 

 

爬蟲項目創建之後,我們來確定需要爬取的數據。在items.py中編輯:

import scrapy


class DfvideoItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    video_url = scrapy.Field()#視頻源url
    video_title = scrapy.Field()#視頻標題
    video_local_path = scrapy.Field()#視頻本地存儲路徑

 

接下來,我們需要確定視頻源的url,這是很關鍵的一步。

現在許多的視頻播放頁面是把視頻鏈接隱藏起來的,這就使得大家無法通過右鍵另存為,防止了視頻別隨意下載。

但是只要視頻在頁面上播放了,那麼必然是要和視頻源產生數據交互的,所以只要稍微抓下包就能夠發現玄機。

這裡我們使用fiddler抓包分析。

發現其視頻播放頁的鏈接類似於:video.eastday.com/a/180926221513827264568.html?index3lbt

視頻源的數據鏈接類似於:mvpc.eastday.com/vyule/20180415/20180415213714776507147_1_06400360.mp4

有了這兩個鏈接,工作就完成了大半:

在DfVideoSpider.py中編輯

# -*- coding: utf-8 -*-
import scrapy
from scrapy.loader import ItemLoader
from scrapy.loader.processors import MapCompose,Join
from DFVideo.items import DfvideoItem
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
import time
from os import path
import os


class DfvideospiderSpider(CrawlSpider):
    name = 'DfVideoSpider'
    allowed_domains = ['eastday.com']
    start_urls = ['http://video.eastday.com/']

    rules = (
        Rule(LinkExtractor(allow=r'video.eastday.com/a/\d+.html'),
             callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        item = DfvideoItem()
        try:
            item["video_url"] = response.xpath('//input[@id="mp4Source"]/@value').extract()[0]
            item["video_title"] = response.xpath('//meta[@name="description"]/@content').extract()[0]
            #print(item)
            item["video_url"] = 'http:' + item['video_url']
            yield scrapy.Request(url=item['video_url'], meta=item, callback=self.parse_video)
        except:
            pass


    def parse_video(self, response):

        i = response.meta
        file_name = Join()([i['video_title'], '.mp4'])
        base_dir = path.join(path.curdir, 'VideoDownload')
        video_local_path = path.join(base_dir, file_name.replace('?', ''))
        i['video_local_path'] = video_local_path

        if not os.path.exists(base_dir):
            os.mkdir(base_dir)

        with open(video_local_path, "wb") as f:
            f.write(response.body)

        yield i

 至此,一個簡單但強大的爬蟲便完成了。

如果你希望將視頻的附加數據保存在資料庫,可以在pipeline.py中進行相應的操作,比如存入mongodb中:

from scrapy import log
import pymongo

class DfvideoPipeline(object):
    def __init__(self):

        self.mongodb = pymongo.MongoClient(host='127.0.0.1', port=27017)
        self.db = self.mongodb["DongFang"]

        self.feed_set = self.db["video"]
        # self.comment_set=self.db[comment_set]

        self.feed_set.create_index("video_title", unique=1)
        # self.comment_set.create_index(comment_index,unique=1)

    def process_item(self, item, spider):
        try:
            self.feed_set.update({"video_title": item["video_title"]}, item, upsert=True)
        except:
            log.msg(message="dup key: {}".format(item["video_title"]), level=log.INFO)
        return item

    def on_close(self):
        self.mongodb.close()

 當然,你需要在setting.py中將pipelines打開:

ITEM_PIPELINES = {
    'TouTiaoVideo.pipelines.ToutiaovideoPipeline': 300,
}

 四、執行結果展示

視頻文件:

 

五、最後

今天講了爬蟲的一些基礎的概念,不深也不透,主要是通過一個案例給大家一個直觀的認識。一些細節上的點後續會專門開文細講,喜歡的朋友可以關註,一起探討。

本文所公佈代碼僅作為學習交流之用,請勿用於非法用途,負責後果自負。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第三篇這裡嘗試談談緩存的數據分片(Sharding)以及集群(Cluster)相關方案(具體應用依然以Redis 舉例)另見:分散式系統之緩存的微觀應用經驗談(二) 【主從和主備高可用篇】( https://www.cnblogs.com/bsfz/) 一、先分析緩存數據的分片(Sharding) ... ...
  • 前段時間分別用vue和react寫了兩個後臺管理系統的模板 "vue quasar admin" 和 "3YAdmin" 。兩個項目中都實現了基於RBAC的許可權控制。因為本職工作是後端開發,比較清楚許可權控制一個管理系統應該必須具備的核心功能,而且是可以做到通用的。打算寫寫關於管理系統前後端分離方面的 ...
  • File->settings->Editor->File and Code Templates->Python Script #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : ${DATE} ${TIME} # @Author : Ari ...
  • 之前有瞭解過disconf,也知道它是基於zookeeper來做的,但是對於其運行原理不太瞭解,趁著周末,debug下源碼,也算是不枉費周末大好時光哈 :) 。關於這篇文章,筆者主要是參考disconf源碼和官方文檔,若有不正確地方,感謝評論區指正交流~ disconf是一個分散式配置管理平臺(Di ...
  • 前段時間在某個第三方平臺看到我寫作字數居然突破了 10W 字,難以想象高中 800 字作文我都得巧妙的利用換行來完成(懂的人肯定也乾過😏)。 幹了這行養成了一個習慣:能擼碼驗證的事情都自己驗證一遍。 於是在上周五通宵加班的空餘時間寫了一個工具: https://github.com/cros... ...
  • 在java中,有幾個基本數據類型,在java的一切皆對象的思想下,他們好像顯得比較特殊,比如我們直接一個int i=1;好像這個1並不是一個對象,其實這個是java採用了一種自動裝箱和拆箱來實現,首先java的編譯器對int i =1加上了Integer.valueOf(),使得實際編譯前的這行代碼 ...
  • 生成器的作用:一條一條輸出,輸出一個獲取一個,不像return,輸出後就馬上返回,不能執行後面的函數。 !!!send 獲取下一個值的效果和next基本一致,但是獲取下一個值時,要給上一個yield的位置傳遞一個數據。 !!!第一次使用生成器時,是用next獲取下一個值,最後一個yield不能接受外 ...
  • ThinkPHP5+小程式商城 網盤視頻 有需要聯繫我 QQ:1844912514 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...