python爬蟲的方便大家都懂的。那么,既然常用,那么我們當然要封裝啦。
那么我們可以先封裝一個父類的爬蟲
我自己的設計想法就是,首先,爬蟲必須要有個字段來存儲匹配的規則gainRule,然后有個字段存儲需要取什么屬性outAttr,
然后就是有個需要處理的數據列表gainList,最后是一個存儲輸出列表數據的outList,和存儲輸出單條數據的outData
那么這個爬蟲的父類定義如下
from bs4 import BeautifulSoup import requests import re class SpiderHp: #gainRule頁面的解析規則,outAttr頁面存儲的規則,gainList需要解析的列表頁, def __init__(self,gainRule,outAttr=None,gainList=None): self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"} self.gainRule=gainRule self.outAttr=outAttr self.gainList=gainList self.req=requests.Session() self.outList=[] self.outData="" #處理列表數據 def startAll(self,gainList=None): if gainList: self.gainList=gainList for url in self.gainList: self.InitUrlList(url) #處理單頁數據 def start(self,gainData): self.InitUrlList(gainData)
爬蟲的基本功能ok之后。接着我們要定義自己的種類爬蟲。
比如我們一般需要一個爬取單個頁面,單個特征值的普通爬蟲,那么。我們寫一個爬蟲繼承父類
#單頁單條數據爬蟲 class SpiderSigDataHp(SpiderHp): def InitUrlList(self, url): reqData = self.req.get(url, headers=self.headers) soup = BeautifulSoup(reqData.text, "lxml") nodeList = soup.select(self.gainRule) if nodeList: if self.outAttr: self.outData=nodeList[0].get(self.outAttr) else: self.outData = nodeList[0]
像這個剛剛定義的爬蟲我們一般可以用來爬取分頁數量之類的。
接着我們再定義一個專門處理列表頁的爬蟲
#列表頁通用爬蟲 class SpiderListHp(SpiderHp): def InitUrlList(self, url): reqData = self.req.get(url, headers=self.headers) soup = BeautifulSoup(reqData.text, "lxml") nodeList = soup.select(self.gainRule) for node in nodeList: if self.outAttr: data=node.get(self.outAttr) else: data = node if data not in self.outList: self.outList.append(data) if not nodeList: print("nodelist err ",url)
最后再定義一個詳情頁的爬蟲即可
#詳情頁爬蟲 class SpiderDetailHp(SpiderHp): def InitUrlList(self, url): reqData = self.req.get(url, headers=self.headers) soup = BeautifulSoup(reqData.text, "lxml") data = {} for key in self.gainRule: ps = soup.select(self.gainRule[key]) if ps: if self.outAttr[key]: data[key]=ps[0].get(self.outAttr[key]) else: data[key] = ps[0] str=repr(data[key]) #去掉標簽數據。一般如果取到最后還有標簽。都是沒用的了 data[key]=re.sub("<.+?>","",str) self.outList.append(data)
這樣我們的爬蟲就完成了。如果還有其他特殊需求的。可以再自己定義。
一般通過這三種爬蟲的組合使用。可以解決大多數網頁的捕獲。接着我來隨便演示下使用。
import Spider import re home="http://www.xxxxxxx.net/" #就不告訴你們我在爬什么了 def main(): url = home + "hmh/list_6_1.html" num=getPage(url) #獲取分頁數量 list=[home+"hmh/list_6_{}.html".format(i) for i in range(1,2)] hlist=getList(list) for i in range(len(hlist)): hlist[i]=home+hlist[i] print(hlist[i]) imgList=getDetail(hlist) print(imgList) print(len(imgList)) #獲取頁面的分頁數量 def getPage(url): gainRule = "span.pageinfo > strong" mgr = Spider.SpiderSigDataHp(gainRule) mgr.start(url) str=repr(mgr.outData) #去掉所有的標簽的內容 num=int(re.sub("<.+?>","",str)) return num #獲取列表頁 def getList(list): gainRule = "ul.piclist > li > a" outAttr = "href" mgr = Spider.SpiderListHp(gainRule, outAttr) mgr.startAll(list) return mgr.outList #獲取詳情頁信息 def getDetail(list): gainData ={} outAttr = {} gainData["image"]="#imgshow > img" gainData["page"]="li.thisclass > a" outAttr["image"]="src" outAttr["page"]="" mgr = Spider.SpiderDetailHp(gainData, outAttr) mgr.startAll(list) return mgr.outList if __name__=="__main__": main()
好了。就這樣。最后配合下載和保存數據庫