一、爬蟲實戰,40G PPT文檔輕松拿

因為需要較多的ppt文檔,爬了一個網站 www.1ppt.com。本文主要是記錄這一過程,如果您正在做文檔爬蟲,或者是MSOffice文檔分析,這系列對您可能有些幫助。

本文的主要內容是:

  • 簡單介紹1ppt.com的爬取邏輯;
  • pptSpider源碼講解;

1.簡單介紹1ppt.com的爬取邏輯

站點分析
分析1ppt.com 并不復雜,站點的結構也很簡單,它的頁面結構如下:

1ppt 三級目錄

就是個三級目錄,沒有什么難點,
接下來我分三步來介紹這個過程。

第一步、根據首頁,獲取板塊分頁目錄;
第二步、遍歷板塊中的所有詳情頁連接 ;
第三步、獲取文檔信息;

1.1、根據首頁,獲取板塊分頁目錄

1ppt.com的頁面布局是這樣的:

分類目錄

獲取它的分頁目錄,不管是描述還是連接,都很方便。

注意className

通過瀏覽器,CopyXPath能得到:

/html/body/div[5]/dl[1]/dd/ul[1]/li[2]/h4/a

精簡一下語法,標題和描述的定位方法可以寫成:

self.m_PageListDes = selector.xpath('//dd[@class="ikejian_col_nav"]/ul/li/h4/a/@title')
self.m_PageListURL = selector.xpath('//dd[@class="ikejian_col_nav"]/ul/li/h4/a/@href')

自此,我們已經能拿到這個網站的所有分類目錄。

1.2、遍歷板塊中的所有詳情頁連接

詳情頁連接

詳情頁也不難抓,”arclist“下就是詳情頁信息的集合。同時,所有頁面的遍歷方法可通 過"下一頁"button來判斷。如果有這個按鈕,就一直找下去,所有詳情頁就能找全了。

遍歷邏輯,nextPage

需要注意的是,這個站點絕大多數的頁面都是這個樣式,但也有不同的,做好返回值的判斷。

1.3、獲取文檔信息

詳情頁信息主要是兩部分,文件描述和下載地址。

文件描述的信息有:

docInfo
info_left

下載地址是:


downUrlList

2、pptSpider源碼講解

總的來說,爬這個站點是很簡單的,沒有太多的動態信息,都是明碼。找對邏輯,依次抓就是了。

我拿到了這個站點的所有文檔,其實也沒多少,3萬多ppt,不到40G。
我已經把整理好的源碼傳到git,地址為:https://github.com/northtower/pptSpider
感謝大家Star!!

# -*- coding:utf8 -*-

import requests
import os
from lxml import etree
from requests.exceptions import ReadTimeout,ConnectionError,RequestException

LOCALPATH = "/Users/Sophia/Codes/python/spider/pptDownLoad/"
HOMEPAGE  = 'http://www.1ppt.com'

'''
簡單封裝了ppt1.com單站爬蟲的分步功能,大體上分三個步驟:
1、根據首頁,獲取板塊分頁目錄  GetIndexPage();
2、遍歷板塊中的所有文檔內容   GetContentByURL;
3、獲取文檔信息             GetDocInfo

擴展功能1:提供文件下載功能   DownLoadFile
'''
class CPPT1Spider():
    def __init__(self , homePage):
        self.initWithHomePage(homePage)
    
    def initWithHomePage(self , oHomePage):
        print ""
        html = requests.get(oHomePage)
        html.encoding = 'gb2312'
        selector = etree.HTML(html.text)

        self.m_PageListDes = selector.xpath('//dd[@class="ikejian_col_nav"]/ul/li/h4/a/@title')
        self.m_PageListURL = selector.xpath('//dd[@class="ikejian_col_nav"]/ul/li/h4/a/@href')

    #根據首頁,獲取板塊目錄。在ppt1網站中,板塊目錄就是初【出版社->年級教材】
    def GetIndexPage(self):   
        oCounts = 1             
        for value1,value2 in zip(self.m_PageListDes ,self.m_PageListURL):
            oListPageURL = HOMEPAGE + value2
            createPath = LOCALPATH + value1
            print "[", oCounts, "]", value1, oListPageURL
            oCounts = oCounts + 1        
            self.GetContentByURL(oListPageURL , createPath) 
            #if not os.path.exists(createPath):
                #os.mkdir(createPath)
                #PS_getContentPage.GetContentByURL(oListPageURL , createPath)
            #print createPath

    #根據板塊首頁,遍歷所有詳情頁
    def GetContentByURL(self , oListPageURL , oLocalPath):

        homePage = "http://www.1ppt.com"
        html = requests.get(oListPageURL)
        html.encoding = 'gb2312'
        selector = etree.HTML(html.text)

        # listPage 的獲取辦法
        content3 = selector.xpath('//ul[@class="arclist"]/li/a/@href')
        for value in content3:
            listPageUrl = homePage + value
            self.GetDocInfo(listPageUrl)
            #oRet = PS_downloadFile.downLoadByURL(listPageUrl , oLocalPath)
            
        #have nextpage 通過“下一頁”的關鍵字查找
        content4 = selector.xpath(u"http://a[contains(text(), '下一頁')]")
        for value in content4:
            strlistUrl = value.get('href')
            #herf絕對路徑的方法沒找到,就用字符串拼吧
            op = oListPageURL.rfind('.')
            if (op > 0):
                op1 = oListPageURL.rfind('/') + 1
                strRet = oListPageURL[:op1]
                strRet = strRet.lower()
                oListPageURL = strRet

            nextPage = oListPageURL + strlistUrl
            print "next Page -----------------------"
            print nextPage
            self.GetContentByURL(nextPage , oLocalPath)
    
    #根據詳情頁地址,獲取文檔信息。ppt1中的docInfo有很多,我只取了其中三項。
    def GetDocInfo(self , oUrl):
        html = requests.get(oUrl)
        html.encoding = 'gb2312'        
        selector = etree.HTML(html.text)
        zipUrl  = selector.xpath('//ul[@class="downurllist"]/li/a/@href')
        if not zipUrl:
            return  False

        print "課件詳情頁:" ,oUrl     
        strZip = str(zipUrl[0])
        print "課件地址:" ,strZip
        #下載文件
        #oRet = self.DownLoadFile(strZip)

        #頻道地址
        #docInfoList  = selector.xpath('//div[@class="info_left"]/ul/li[1]/a/@href')

        #課件名稱
        docInfoList  = selector.xpath('//div[@class="ppt_info clearfix"]/h1/text()')
        if docInfoList:
            print "課件名稱:" , docInfoList[0]
        
        print ""
    
    def DownLoadFile(self, oFileURL):

        #模擬報文頭
        oHeader = { "Accept":"text/html,application/xhtml+xml,application/xml;",
                "Accept-Encoding":"gzip",
                "Accept-Language":"zh-CN,zh;q=0.8",
                "Referer":"http://www.1ppt.com/",
                "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36"
                }

        PDFName = self.GetFileNameByURL(oFileURL)
        localPDF = LOCALPATH + PDFName

        try:
            response = requests.get(oFileURL,headers = oHeader ,timeout=10)
            print(response.status_code)
            print localPDF

            if not os.path.exists(localPDF):
                oFile = open(localPDF, "wb")
                for chunk in response.iter_content(chunk_size=512):
                    if chunk:
                        oFile.write(chunk)
            else:
                print "had download file:" ,localPDF

            return True
        except ReadTimeout:
            print("timeout")
        except ConnectionError:
            print("connection Error")
        except RequestException:
            print("error")

        return False

    def GetFileNameByURL(self, oURL):
        op = oURL.rfind('/')
        if (op > 0):
            op = op + 1
            strRet = oURL[op:]
            strRet = strRet.lower()
            return strRet

if __name__ == "__main__":
    oHomePage = 'http://www.1ppt.com/kejian/'
    oSpider = CPPT1Spider(oHomePage)
    oSpider.GetIndexPage()

注意事項:

  • 下載文檔會有失敗的情況,有些tryAgain即可解決;
  • 可以先爬去信息,再統一下載文檔;
  • 下載后的文檔未解壓,這部分等到ppt文檔分析時再做描述;

備注

爬蟲不是本系列的重點,我的目的是ppt內容分析,所以,這部分的著墨并不多。如果您有疑問,可以給我留言。我一周內盡量給您回復。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,808評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,180評論 4 61
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,836評論 18 139
  • 姓名:巢環環 公司:寧波大發化纖有限公司 期數:第264期六項精進 組名:努力一組 【日精進打卡第67天】共67天...
    巢環環閱讀 105評論 0 0
  • 2017年 1 月 5 日星期三 幾天沒更新了,日子也就這么稀里糊涂地過著。真實的日子會粗糙一點,誰會掰著手指頭一...
    奧特霧漫劉閱讀 293評論 0 1