因?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)如下:
就是個三級目錄桑嘶,沒有什么難點(diǎn),
接下來我分三步來介紹這個過程躬充。
第一步逃顶、根據(jù)首頁讨便,獲取板塊分頁目錄;
第二步口蝠、遍歷板塊中的所有詳情頁連接 器钟;
第三步、獲取文檔信息妙蔗;
1.1傲霸、根據(jù)首頁,獲取板塊分頁目錄
1ppt.com的頁面布局是這樣的:
獲取它的分頁目錄眉反,不管是描述還是連接昙啄,都很方便。
通過瀏覽器寸五,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來判斷。如果有這個按鈕劲适,就一直找下去楷掉,所有詳情頁就能找全了。
需要注意的是烹植,這個站點(diǎn)絕大多數(shù)的頁面都是這個樣式,但也有不同的愕贡,做好返回值的判斷草雕。
1.3、獲取文檔信息
詳情頁信息主要是兩部分固以,文件描述和下載地址促绵。
文件描述的信息有:
下載地址是:
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ù)。