您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Python如何利用scrapy爬蟲通過短短50行代碼下載整站短視頻”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Python如何利用scrapy爬蟲通過短短50行代碼下載整站短視頻”這篇文章吧。
一、撕開爬蟲的面紗——爬蟲是什么,它能做什么
爬蟲是什么
爬蟲就是一段能夠從互聯(lián)網(wǎng)上高效獲取數(shù)據(jù)的程序。
我們每天都在從互聯(lián)網(wǎng)上獲取數(shù)據(jù)。當(dāng)打開瀏覽器訪問百度的時(shí)候,我們就從百度的服務(wù)器獲取數(shù)據(jù),當(dāng)拿起手機(jī)在線聽歌的時(shí)候,我們就從某個(gè)app的服務(wù)器上獲取數(shù)據(jù)。簡單的歸納,這些過程都可以描述為:我們提交一個(gè)Request請求,服務(wù)器會(huì)返回一個(gè)Response數(shù)據(jù),應(yīng)用根據(jù)Response來渲染頁面,給我們展示數(shù)據(jù)結(jié)果。
爬蟲最核心的也是這個(gè)過程,提交Requests——〉接受Response。就這樣,很簡單,當(dāng)我們在瀏覽器里打開一個(gè)頁面,看到頁面內(nèi)容的時(shí)候,我們就可以說這個(gè)頁面被我們采集到了。
只不過當(dāng)我們真正進(jìn)行數(shù)據(jù)爬取時(shí),一般會(huì)需要采集大量的頁面,這就需要提交許多的Requests,需要接受許多的Response。數(shù)量大了之后,就會(huì)涉及到一些比較復(fù)雜的處理,比如并發(fā)的,比如請求序列,比如去重,比如鏈接跟蹤,比如數(shù)據(jù)存儲(chǔ),等等。于是,隨著問題的延伸和擴(kuò)展,爬蟲就成為了一個(gè)相對獨(dú)立的技術(shù)門類。
但它的本質(zhì)就是對一系列網(wǎng)絡(luò)請求和網(wǎng)絡(luò)響應(yīng)的處理。
爬蟲能做什么
爬蟲的作用和目的只有一個(gè),獲取網(wǎng)絡(luò)數(shù)據(jù)。我們知道,互聯(lián)網(wǎng)是個(gè)數(shù)據(jù)的海洋,大量的信息漂浮在其中,想把這些資源收歸己用,爬蟲是最常用的方式。特別是最近幾年大樹據(jù)挖掘技術(shù)和機(jī)器學(xué)習(xí)以及知識(shí)圖譜等技術(shù)的興盛,更是對數(shù)據(jù)提出了更大的需求。另外也有很多互聯(lián)網(wǎng)創(chuàng)業(yè)公司,在起步初期自身積累數(shù)據(jù)較少的時(shí)候,也會(huì)通過爬蟲快速獲取數(shù)據(jù)起步。
二、python爬蟲框架scrapy——爬蟲開發(fā)的利器
如果你剛剛接觸爬蟲的概念,我建議你暫時(shí)不要使用scrapy框架?;蛘吒鼘挿旱恼f,如果你剛剛接觸某一個(gè)技術(shù)門類,我都不建議你直接使用框架,因?yàn)榭蚣苁菍υS多基礎(chǔ)技術(shù)細(xì)節(jié)的高級(jí)抽象,如果你不了解底層實(shí)現(xiàn)原理就直接用框架多半會(huì)讓你云里霧里迷迷糊糊。
在入門爬蟲之初,看scrapy的文檔,你會(huì)覺得“太復(fù)雜了”。當(dāng)你使用urllib或者Requests開發(fā)一個(gè)python的爬蟲腳本,并逐個(gè)去解決了請求頭封裝、訪問并發(fā)、隊(duì)列去重、數(shù)據(jù)清洗等等問題之后,再回過頭來學(xué)習(xí)scrapy,你會(huì)覺得它如此簡潔優(yōu)美,它能節(jié)省你大量的時(shí)間,它會(huì)為一些常見的問題提供成熟的解決方案。
scrapy數(shù)據(jù)流程圖
這張圖是對scrapy框架的經(jīng)典描述,一時(shí)看不懂沒有關(guān)系,用一段時(shí)間再回來看?;蛘甙驯疚淖x完再回來看。
在一些書上會(huì)把爬蟲的基本抓取流程概括為UR 2 IM,意思是數(shù)據(jù)爬取的過程是圍繞URL、Request(請求)、Response(響應(yīng))、Item(數(shù)據(jù)項(xiàng))、MoreUrl(更多的Url)展開的。上圖的 綠色箭頭 體現(xiàn)的正是這幾個(gè)要素的流轉(zhuǎn)過程。圖中涉及的四個(gè)模塊正是用于處理這幾類對象的:
Spider模塊:負(fù)責(zé)生成Request對象、解析Response對象、輸出Item對象
Scheduler模塊:負(fù)責(zé)對Request對象的調(diào)度
Downloader模塊:負(fù)責(zé)發(fā)送Request請求,接收Response響應(yīng)
ItemPipleline模塊:負(fù)責(zé)數(shù)據(jù)的處理
scrapy Engine負(fù)責(zé)模塊間的通信
各個(gè)模塊和scrapy引擎之間可以添加一層或多層中間件,負(fù)責(zé)對出入該模塊的UR 2 IM對象進(jìn)行處理。
scrapy的安裝
參考官方文檔,不再贅述。官方文檔:https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/install.html
三、scrapy實(shí)戰(zhàn):50行代碼爬取全站短視頻
python的優(yōu)雅之處在于能夠讓開發(fā)者專注于業(yè)務(wù)邏輯,花更少的時(shí)間在枯燥的代碼編寫調(diào)試上。scrapy無疑完美詮釋了這一精神。
開發(fā)爬蟲的一般步驟是:
確定要爬取的數(shù)據(jù)(item)
找到數(shù)據(jù)所在頁面的url
找到頁面間的鏈接關(guān)系,確定如何跟蹤(follow)頁面
那么,我們一步一步來。
既然是使用scrapy框架,我們先創(chuàng)建項(xiàng)目:
scrapy startproject DFVideo
緊接著,我們創(chuàng)建一個(gè)爬蟲:
scrapy genspider -t crawl DfVideoSpider eastday.com
這是我們發(fā)現(xiàn)在當(dāng)前目錄下已經(jīng)自動(dòng)生成了一個(gè)目錄:DFVideo
目錄下包括如圖文件:
spiders文件夾下,自動(dòng)生成了名為DfVideoSpider.py的文件。
爬蟲項(xiàng)目創(chuàng)建之后,我們來確定需要爬取的數(shù)據(jù)。在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()#視頻標(biāo)題 video_local_path = scrapy.Field()#視頻本地存儲(chǔ)路徑
接下來,我們需要確定視頻源的url,這是很關(guān)鍵的一步。
現(xiàn)在許多的視頻播放頁面是把視頻鏈接隱藏起來的,這就使得大家無法通過右鍵另存為,防止了視頻別隨意下載。
但是只要視頻在頁面上播放了,那么必然是要和視頻源產(chǎn)生數(shù)據(jù)交互的,所以只要稍微抓下包就能夠發(fā)現(xiàn)玄機(jī)。
這里我們使用fiddler抓包分析。
發(fā)現(xiàn)其視頻播放頁的鏈接類似于:video.eastday.com/a/180926221513827264568.html?index3lbt
視頻源的數(shù)據(jù)鏈接類似于:mvpc.eastday.com/vyule/20180415/20180415213714776507147_1_06400360.mp4
有了這兩個(gè)鏈接,工作就完成了大半:
在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
至此,一個(gè)簡單但強(qiáng)大的爬蟲便完成了。
如果你希望將視頻的附加數(shù)據(jù)保存在數(shù)據(jù)庫,可以在pipeline.py中進(jìn)行相應(yīng)的操作,比如存入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()
當(dāng)然,你需要在setting.py中將pipelines打開:
ITEM_PIPELINES = { 'TouTiaoVideo.pipelines.ToutiaovideoPipeline': 300, }
以上是“Python如何利用scrapy爬蟲通過短短50行代碼下載整站短視頻”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。