一、爬虫实战,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"//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阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,413评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,591评论 18 139
  • 姓名:巢环环 公司:宁波大发化纤有限公司 期数:第264期六项精进 组名:努力一组 【日精进打卡第67天】共67天...
    巢环环阅读 104评论 0 0
  • 2017年 1 月 5 日星期三 几天没更新了,日子也就这么稀里糊涂地过着。真实的日子会粗糙一点,谁会掰着手指头一...
    奥特雾漫刘阅读 273评论 0 1