一呵晨、爬蟲實(shí)戰(zhàn),40G PPT文檔輕松拿

因?yàn)樾枰^多的ppt文檔熬尺,爬了一個網(wǎng)站 www.1ppt.com摸屠。本文主要是記錄這一過程,如果您正在做文檔爬蟲粱哼,或者是MSOffice文檔分析季二,這系列對您可能有些幫助。

本文的主要內(nèi)容是:

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

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

站點(diǎn)分析
分析1ppt.com 并不復(fù)雜,站點(diǎn)的結(jié)構(gòu)也很簡單绊含,它的頁面結(jié)構(gòu)如下:

1ppt 三級目錄

就是個三級目錄桑嘶,沒有什么難點(diǎn),
接下來我分三步來介紹這個過程躬充。

第一步逃顶、根據(jù)首頁讨便,獲取板塊分頁目錄;
第二步口蝠、遍歷板塊中的所有詳情頁連接 器钟;
第三步、獲取文檔信息妙蔗;

1.1傲霸、根據(jù)首頁,獲取板塊分頁目錄

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

分類目錄

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

注意className

通過瀏覽器寸五,CopyXPath能得到:

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

精簡一下語法梳凛,標(biāo)題和描述的定位方法可以寫成:

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')

自此,我們已經(jīng)能拿到這個網(wǎng)站的所有分類目錄梳杏。

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

詳情頁連接

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

遍歷邏輯霞势,nextPage

需要注意的是烹植,這個站點(diǎn)絕大多數(shù)的頁面都是這個樣式,但也有不同的愕贡,做好返回值的判斷草雕。

1.3、獲取文檔信息

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

文件描述的信息有:

docInfo
info_left

下載地址是:


downUrlList

2、pptSpider源碼講解

總的來說嘴纺,爬這個站點(diǎn)是很簡單的败晴,沒有太多的動態(tài)信息菩浙,都是明碼肠骆。找對邏輯,依次抓就是了夯接。

我拿到了這個站點(diǎn)的所有文檔闲擦,其實(shí)也沒多少慢味,3萬多ppt场梆,不到40G。
我已經(jīng)把整理好的源碼傳到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顶岸、根據(jù)首頁,獲取板塊分頁目錄  GetIndexPage()叫编;
2辖佣、遍歷板塊中的所有文檔內(nèi)容   GetContentByURL;
3搓逾、獲取文檔信息             GetDocInfo

擴(kuò)展功能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')

    #根據(jù)首頁卷谈,獲取板塊目錄。在ppt1網(wǎng)站中霞篡,板塊目錄就是初【出版社->年級教材】
    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

    #根據(jù)板塊首頁世蔗,遍歷所有詳情頁
    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 通過“下一頁”的關(guān)鍵字查找
        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)
    
    #根據(jù)詳情頁地址朗兵,獲取文檔信息污淋。ppt1中的docInfo有很多,我只取了其中三項(xiàng)矛市。
    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):

        #模擬報(bào)文頭
        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()

注意事項(xiàng):

  • 下載文檔會有失敗的情況芙沥,有些tryAgain即可解決诲祸;
  • 可以先爬去信息浊吏,再統(tǒng)一下載文檔;
  • 下載后的文檔未解壓救氯,這部分等到ppt文檔分析時再做描述找田;

備注

爬蟲不是本系列的重點(diǎn),我的目的是ppt內(nèi)容分析着憨,所以墩衙,這部分的著墨并不多。如果您有疑問甲抖,可以給我留言漆改。我一周內(nèi)盡量給您回復(fù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末准谚,一起剝皮案震驚了整個濱河市挫剑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柱衔,老刑警劉巖樊破,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愉棱,死亡現(xiàn)場離奇詭異,居然都是意外死亡哲戚,警方通過查閱死者的電腦和手機(jī)奔滑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顺少,“玉大人朋其,你說我怎么就攤上這事∑泶浚” “怎么了令宿?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長腕窥。 經(jīng)常有香客問我粒没,道長,這世上最難降的妖魔是什么簇爆? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任癞松,我火速辦了婚禮,結(jié)果婚禮上入蛆,老公的妹妹穿的比我還像新娘响蓉。我一直安慰自己,他們只是感情好哨毁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布枫甲。 她就那樣靜靜地躺著,像睡著了一般扼褪。 火紅的嫁衣襯著肌膚如雪想幻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天话浇,我揣著相機(jī)與錄音脏毯,去河邊找鬼。 笑死幔崖,一個胖子當(dāng)著我的面吹牛食店,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赏寇,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼吉嫩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嗅定?” 一聲冷哼從身側(cè)響起自娩,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎露戒,沒想到半個月后椒功,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捶箱,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年动漾,在試婚紗的時候發(fā)現(xiàn)自己被綠了丁屎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡旱眯,死狀恐怖晨川,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情删豺,我是刑警寧澤共虑,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站呀页,受9級特大地震影響妈拌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蓬蝶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一尘分、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丸氛,春花似錦培愁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至禾锤,卻和暖如春私股,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背时肿。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工庇茫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留港粱,地道東北人螃成。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像查坪,于是被迫代替她去往敵國和親寸宏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,162評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫偿曙、插件氮凝、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評論 4 62
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)望忆,斷路器罩阵,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 姓名:巢環(huán)環(huán) 公司:寧波大發(fā)化纖有限公司 期數(shù):第264期六項(xiàng)精進(jìn) 組名:努力一組 【日精進(jìn)打卡第67天】共67天...
    巢環(huán)環(huán)閱讀 104評論 0 0
  • 2017年 1 月 5 日星期三 幾天沒更新了竿秆,日子也就這么稀里糊涂地過著。真實(shí)的日子會粗糙一點(diǎn)稿壁,誰會掰著手指頭一...
    奧特霧漫劉閱讀 283評論 0 1