1. 程式人生 > >使用python爬蟲爬取愛課程視訊

使用python爬蟲爬取愛課程視訊

CSDN上寫的第一篇部落格,初學程式設計,寫的疏漏頗多,還請見諒。

最初是自己想找一些大學公開課的資源,隨後發現了有一個叫愛課程的網站www.icourses.cn,上面提供了近千門視訊公開課,正符合我的需求,便找了本爬蟲的書,開始學習爬取視訊。

然而,爬取過程並不順利。

首先,視訊網站的視訊連結並不像京東淘寶的圖片一樣存在於當前頁面,你需要進入每個老師的課堂到達視訊播放頁才能提取到連結。

第二,也是困擾我長達一週多的東西,這個網站的url並不會隨著頁面的變化而變化,這和書上說的完全不一樣啊喂(#`O),同樣的,網頁原始碼也始終和第一頁的程式碼保持一致,完全得不到後面四十多頁的任何資訊。當時我換了數個瀏覽器,百度了無數的內容,自行增添網址字尾,都沒有任何效果,絕望的我差點就要放棄了。


第一頁課程


第二頁課程

後來,和我一塊學習爬蟲的同學告訴我,在fiddler中可以看到第二頁之後的網頁原始碼

 

第一頁的網頁原始碼


第二頁的網頁原始碼

這讓我有了一絲繼續下去的希望,至少原始碼能看到了,只要把原始碼都搞到一個檔案裡,課堂的連結就都能提取出來了。

但是,很明顯,五十頁的網頁原始碼光復制貼上就覺得很麻煩,這種方法還是顯得太笨了。我依舊在思考如何能讓程式碼自動翻頁。

在我苦苦追尋答案的幾天裡,同學已經用上面的笨方法爬取了三十頁的視訊= =

偶然的一天我注意到了網頁除了有get請求外還有post請求,而post請求是不會有url的變化的,之前書中介紹的post請求都是和模擬登陸有關我都沒在意,這一天我開啟瀏覽器按下了

f12


果不其然!網頁是向一個videoSearchPage的地方傳送了post請求然後再返回來的!繼續開啟fiddler我查到了傳送請求所需的引數


緊接著我按照書中的教程寫出了爬取頁面的程式碼:

# -*- coding: utf-8 -*-
"""
Created on Wed Apr 11 15:57:56 2018

@author: 好讀秒
"""

import re
import urllib.request
import urllib.parse

a = 31
for a in range(31,35):
    url = "http://www.icourses.cn/web//sword/portal/videoSearchPage"
    postdata = urllib.parse.urlencode({
            'JSESSIONID':"EC283676A72516765DCB5844584D7A23-n1",
            'Hm_lvt_787dbcb72bb32d4789a985fd6cd53a46':'1523326195,1523433916',
            'Hm_lpvt_787dbcb72bb32d4789a985fd6cd53a46':'1523433987',
           'currentPage':f'{a}',
           'listType':'1'
               }).encode('utf-8')
    req = urllib.request.Request(url,postdata)
    req.add_header("User-Agent",'Mozilla/5.0(Windows NT 6.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0')
    data = urllib.request.urlopen(req).read()
    data = str(data)
    ptn = re.compile('<li class="pull-left.*?<div.*?</div>.*?href="(.*?)".*?</a>.*?<a.*?href=.*?title=', re.S)
    data2 = re.findall(ptn, data)
    fhandle = open("d:/1/7.txt",'a')
    fhandle.write(str(data2))
    fhandle.close()

不知為何如果一次性爬多了網路會超時,我最多55頁的爬取,並把這些課堂連結儲存到記事本里。

事情完成了一半,接下來的任務就是爬取記下來的連結中的視訊了。

其實使用urllib.request就能把視訊扒下來(大概),在這裡我想練一下scrapy框架。

開始建立一個scrapy工程(scrapy安裝就不說了):

cmd中進入到你想要建立的目錄中,輸入scraoy startproject icourses:


開啟建立好的工程,首先編寫items.py,用來表示我要爬取的內容,對於我來說只需要視訊名稱(老師名)和視訊地址就夠了:

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class IcoursesItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    mp4name = scrapy.Field()
    mp4url = scrapy.Field()

然後編寫pipelines.py檔案,用來設定爬取下來的東西的儲存位置:

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import urllib.request

class IcoursesPipeline(object):
    def process_item(self, item, spider):
        num = [1,2,3,4,5,6,7,8]
        for i in range(0,len(item["mp4url"])):
            thisurl = item['mp4url'][i]
            url = thisurl + '.mp4'
            num[i] = i
            name = item['mp4name']
            thisname = name + [num[i]]
            urllib.request.urlretrieve(url, filename="d:/1/mp4/"+str(thisname)+".mp4")
        return item

然後設定settings.py檔案,去掉前面的註釋符號就可以啦:

ITEM_PIPELINES = {
    'icourses.pipelines.IcoursesPipeline': 300,
}

重頭戲就是下面的主程式了,首先在工程內建立一個爬蟲:

 

這是建立了一個basic模板的爬蟲,還有其他模板書上沒細講,我也就放棄了。

之後開始修改建立的icourse.py檔案:

# -*- coding: utf-8 -*-
import scrapy
import re 
from icourses.items import IcoursesItem
from scrapy.http import Request


class IcourseSpider(scrapy.Spider):
    name = 'icourse'
    allowed_domains = ['icourse.cn']
    
    f= open(r"d:/1/7.json","r")
    s = f.readlines()

    f.close()
    start_urls = ['']
    def parse(self, response):
        item = IcoursesItem()
        pattern ='(http://res2.icourses.cn/video/mobile/.*?).mp4'
        
        item['mp4url'] = re.compile(pattern).findall(str(response.body))
        
        item['mp4name']=response.xpath("//a[@class='teacher-infor-name']/text()").extract()
        
        yield item

 首先start_url內填上自己想要爬取的網頁,我本來是想直接讀出記事本的內容填進去,沒想到總是出錯,於是我就把網頁直接複製進去了,網頁太多,就不寫出來了

其次xpath我還有很多地方搞不清楚,比如這裡的老師我可以用他爬出來,但是視訊連結怎麼也搞不到,只能使用正則表示式,但是正則表示式我學的也不好,比如視訊連結中有res1的內容:也有res2的內容:我寫的正則表示式只能匹配到res2中的東西,按照書上使用匹配符號之類的都行不通,還是學的不精啊。

最後執行爬蟲,還是在cmd中進入到工程目錄,輸入:

 

等著就行了,建議還是開著日誌,否則出錯了還得自己去找,太麻煩。

下載速度只有40k/s,下了整整一週才把後20頁下完,還僅僅是res2內容的:


中間遇到的無數的bug就不多說了,希望有人能看到這個東西並且有所收穫吧。

以上