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()
好了。就这样。最后配合下载和保存数据库
原文:http://www.cnblogs.com/kings0/p/7811806.html