python爬虫的方便大家都懂的。那么,既然常用,那么我们当然要封装啦。
那么我们可以先封装一个父类的爬虫
我自己的设计想法就是,首先,爬虫必须要有个字段来存储匹配的规则gainRule,然后有个字段存储需要取什么属性outAttr,
然后就是有个需要处理的数据列表gainList,最后是一个存储输出列表数据的outList,和存储输出单条数据的outData
那么这个爬虫的父类定义如下
from bs4 importBeautifulSoupimportrequestsimportreclassSpiderHp:#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):ifgainList:
self.gainList=gainListfor url inself.gainList:
self.InitUrlList(url)#处理单页数据
defstart(self,gainData):
self.InitUrlList(gainData)
爬虫的基本功能ok之后。接着我们要定义自己的种类爬虫。
比如我们一般需要一个爬取单个页面,单个特征值的普通爬虫,那么。我们写一个爬虫继承父类
#单页单条数据爬虫
classSpiderSigDataHp(SpiderHp):defInitUrlList(self, url):
reqData= self.req.get(url, headers=self.headers)
soup= BeautifulSoup(reqData.text, "lxml")
nodeList=soup.select(self.gainRule)ifnodeList:ifself.outAttr:
self.outData=nodeList[0].get(self.outAttr)else:
self.outData= nodeList[0]
像这个刚刚定义的爬虫我们一般可以用来爬取分页数量之类的。
接着我们再定义一个专门处理列表页的爬虫
#列表页通用爬虫
classSpiderListHp(SpiderHp):defInitUrlList(self, url):
reqData= self.req.get(url, headers=self.headers)
soup= BeautifulSoup(reqData.text, "lxml")
nodeList=soup.select(self.gainRule)for node innodeList:ifself.outAttr:
data=node.get(self.outAttr)else:
data=nodeif data not inself.outList:
self.outList.append(data)if notnodeList:print("nodelist err",url)
最后再定义一个详情页的爬虫即可
#详情页爬虫
classSpiderDetailHp(SpiderHp):defInitUrlList(self, url):
reqData= self.req.get(url, headers=self.headers)
soup= BeautifulSoup(reqData.text, "lxml")
data={}for key inself.gainRule:
ps=soup.select(self.gainRule[key])ifps:ifself.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)
这样我们的爬虫就完成了。如果还有其他特殊需求的。可以再自己定义。
一般通过这三种爬虫的组合使用。可以解决大多数网页的捕获。接着我来随便演示下使用。
importSpiderimportre
home="http://www.xxxxxxx.net/" #就不告诉你们我在爬什么了
defmain():
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 inrange(len(hlist)):
hlist[i]=home+hlist[i]print(hlist[i])
imgList=getDetail(hlist)print(imgList)print(len(imgList))#获取页面的分页数量
defgetPage(url):
gainRule= "span.pageinfo > strong"mgr=Spider.SpiderSigDataHp(gainRule)
mgr.start(url)
str=repr(mgr.outData)#去掉所有的标签的内容
num=int(re.sub("<.+?>","",str))returnnum#获取列表页
defgetList(list):
gainRule= "ul.piclist > li > a"outAttr= "href"mgr=Spider.SpiderListHp(gainRule, outAttr)
mgr.startAll(list)returnmgr.outList#获取详情页信息
defgetDetail(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)returnmgr.outListif __name__=="__main__":
main()
好了。就这样。最后配合下载和保存数据库