一种避免网络连接失败后重复抓取分页内容的方法与流程

文档序号:15761242发布日期:2018-10-26 19:19阅读:209来源:国知局
本发明涉及springboot爬虫
技术领域
:,特别涉及一种避免网络连接失败后重复抓取分页内容的方法。
背景技术
::在进行网页情报信息抓取时,经常会有各种各样的原因造成连接不上所要抓取的网站,比如抓取的主机发生断网,或者网页所属的服务器重启等。如果不进行一定的技术处理,那每次定时器启动时就会从分页的第一页重新开始抓取,造成数据库中大量信息的重复;为了解决这些问题,需要实现一种能解决重复抓取的功能。技术实现要素:本发明解决的技术问题在于提供一种避免网络连接失败后重复抓取分页内容的方法;解决了网络连接失败后重新启动定时器抓取每个分页内容时容易重复抓取的问题。本发明解决上述技术问题的技术方案是:1、创建主副两张表,主表用于保存标题、链接及链接对应的分页总页数、当前页数等,副表用于保存分页列表、链接及主表id等;2、使用爬虫工具定时抓取1中所述的内容,保存到主表中;3、加载主表内容,然后以当前页数开始,总页数为结束,进行循环,根据标题链接与循环值拼接分页url;4、抓取分页内容时与从副表中读取的数据对比,相同则跳过,继续抓取下一行内容;5、最后把分页的当前页数替换掉主表中的,这样下次抓取的分页就不会重复。从而解决了网络连接失败后重新启动定时器抓取每个分页内容时重复抓取的问题。所述的方法具体包括如下步骤:步骤一、创建主副两张表,其中主表用于保存标题、标题的链接及链接对应的分页总页数、当前页数等,副表用于保存分页列表信息、列表的链接及主表的id等;步骤二、在项目中配置quartz定时器,设定一个时间,定时调用爬虫工具抓取步骤一中所述的内容,把其保存到主表中;步骤三、定义分页查询任务,从数据库中查询出主表的内容,然后以当前页数为开始值,总页数为结束值,进行循环,在循环体内根据标题链接与循环值拼接出分页url;步骤四、加载分页url,使用爬虫工具获取每个列表的链接,并与从副表中读取的当前页的链接进行对比,相同就跳过,然后继续抓取下一行内容;步骤五、保存完抓取的分页内容后,把当前的页数保存到主表中,替换掉原来的当前分页数,若网络异常就会从这个页数开始,避免了从第一页开始重复抓取。本发明的有益效果:通过主副表的形式,把每次网络连接失败后的分页所属的当前页数保存到主表中,再次抓取的时候,就从失败后的那一页开始抓取,并且每次抓取分页列表时都与数据库中的内容进行对比,不相同时才开始下一行的抓取,从而达到网络连接失败后重新启动定时器抓取分页内容时不会重复的目的。有效解决了网络连接失败后重新启动定时器抓取每个分页内容时容易重复抓取的问题。附图说明下面结合附图对本发明进一步说明:图1为本发明的流程图。具体实施方式如图1所示,本发明采用如下步骤:步骤一、创建主副两张表,其中主表用于保存标题、标题的链接及链接对应的分页总页数、当前页数等,副表用于保存分页列表信息、列表的链接及主表的id等;//创建主表droptableifexists`info_main`;createtable`info_main`(`id`bigint(20)notnullauto_incrementcomment'id',`sitename`varchar(500)defaultnull,`maintitle`varchar(500)defaultnullcomment'需要抓取的标题',`content`varchar(500)defaultnullcomment'内容',`mainurl`varchar(500)defaultnullcomment'主url',`params`varchar(1000)defaultnullcomment'url参数',`jsurl`varchar(500)defaultnullcomment'脚本url',`currentpage`int(255)default'0'comment'当前页',`totalpage`int(255)default'0'comment'总页数',`totalnum`int(11)default'0'comment'总条数',`modifydate`datetimedefaultnullcomment'修改日期',`createdate`datetimedefaultnullcomment'创建日期',`hasadd`int(2)default'0'comment'是否添加,0:没有,1:添加',primarykey(`id`))engine=innodbauto_increment=5defaultcharset=utf8;//创建明细表droptableifexists`info_list`;createtable`info_list`(`id`bigint(20)notnullauto_incrementcomment'id',`mainid`bigint(20)defaultnull,`listtitle`varchar(500)defaultnullcomment'需要抓取的标题',`listcontent`varchar(500)defaultnull,`listurl`varchar(500)defaultnullcomment'主url',`jsurl`varchar(500)defaultnullcomment'脚本url',`currentpage`int(255)default'0'comment'当前页',`totalpage`int(255)default'0'comment'总页数',`totalnum`int(11)default'0'comment'总条数',`modifydate`datetimedefaultnullcomment'修改日期',`createdate`datetimedefaultnullcomment'创建日期',`hasadd`int(2)default'0'comment'是否添加,0:没有,1:添加',primarykey(`id`))engine=innodbauto_increment=316defaultcharset=utf8;步骤二、在项目中配置quartz多任务定时器,设定一个时间,定时调用爬虫工具抓取步骤一中所述的内容,把其保存到主表中;//1、配置多任务定时器@configurationpublicclassschedulersettingimplementsapplicationlistener<contextrefreshedevent>{@autowiredpublicinfoschedulerinfoscheduler;@overridepublicvoidonapplicationevent(contextrefreshedeventevent){try{infoscheduler.schedulejobs();}catch(schedulerexceptione){e.printstacktrace();}}@beanpublicschedulerfactorybeanschedulerfactorybean(){schedulerfactorybeanschedulerfactorybean=newschedulerfactorybean();returnschedulerfactorybean;}}//2、配置主任务调用publicclassmainjobimplementsjob{@resourceprivatespiderservicespiderservice;@overridepublicvoidexecute(jobexecutioncontextcontext)throwsjobexecutionexception{try{spiderservice.getinfomain();}catch(exceptione){e.printstacktrace();}}}//3、在controller调用,扫描标题部分与对应分页的总页数等信息@controllerpublicclassquartzcontrollerextendsbasecontroller{@autowiredprivateschedulerfactorybeanschedulerfactorybean;publicvoidschedulejobs()throwsschedulerexception{schedulerscheduler=schedulerfactorybean.getscheduler();startmainjob(scheduler);//startlistjob(scheduler);}privatevoidstartmainjob(schedulerscheduler)throwsschedulerexception{jobdetailjobdetail=jobbuilder.newjob(mainjob.class).withidentity("mainjob","infogroup").build();cronschedulebuilderschedulebuilder=cronschedulebuilder.cronschedule("000001#1");crontriggercrontrigger=triggerbuilder.newtrigger().withidentity("maintrigger","infogroup").withschedule(schedulebuilder).build();scheduler.schedulejob(jobdetail,crontrigger);}}//4、具体抓取标题等信息publicvoidgetinfomain()throwsioexception{try{stringinfo_url="http://www.***.com/titles";documentdoc=jsouputil.getconn(info_url).get();elementselementtitles=doc.select("#titles");stringtotalpage=doc.select(“#totalpage”).get(0).text();for(elemente:elementtitles){stringlinkhref=link.attr("href");stringlinktext=link.text();……infomaininfomain=newinfomain();infomain.setmaintitle(linktext);infomain.settotalpage(totalpage);infomain.setcurrentpage(1);//保存到数据库中infomainmapper.insert();}}catch(scriptexceptione){e.printstacktrace();}}步骤三、定义分页查询任务,从数据库中查询出主表的内容,然后以当前页数为开始值,总页数为结束值,进行循环,在循环体内根据标题链接与循环值拼接出分页url;//1、定义分页查询任务publicclasslistjobimplementsjob{@resourceprivatespiderservicespiderservice;@resourceprivateinfomainserviceinfomainservice;@overridepublicvoidexecute(jobexecutioncontextcontext)throwsjobexecutionexception{try{//2、从主表数据库中读取信息list<infomain>infomainlist=infomainservice.selectbymap(null);if(infomainlist!=null&&infomainlist.size()>0){//3、对每个标题对应的内容抓取for(infomaininfomain:infomainlist){spiderservice.getinfolist(infomain);}}}catch(exceptione){e.printstacktrace();}}}//4、拼接urlpublicvoidgetinfolist(infomaininfomain){try{integertotalpage=infomain.gettotalpage();stringurl=infomain.getmainurl()+infomain.getparams();integercurpage=infomain.getcurrentpage();if(totalpage!=null&&totalpage>0){for(inti=curpage+1;i<=totalpage;i++){url=url+i;……}}}catch(ioexceptione){e.printstacktrace();}catch(interruptedexceptione1){e1.printstacktrace();}}步骤四、加载分页url,使用爬虫工具获取每个列表的链接,并与从副表中读取的当前页的链接进行对比,相同就跳过,继续抓取下一行内容;htmlpagehtmlpage=webclientutil.getwebclient().getpage(url);stringhtmlcontent=htmlpage.asxml();documentdoc=jsoup.parse(htmlcontent);elementspelements=doc.select("p[align=left]");for(elemente:pelements){//获得全a标签信息elementslinks=e.getelementsbytag("a");/对链接标签遍历for(elementlink:links){stringlinkhref=link.attr("href");stringlinktext=link.text();//查询数据库记录,判断当前linkhref是否在数据库中,存在的话就不再添加map<string,object>columnmap=newhashmap<string,object>();columnmap.put("jsurl",linkhref);list<infolist>infolists=infolistmapper.selectbymap(columnmap);if(infolists!=null&&infolists.size()>0){continue;//跳出循环}}}步骤五、保存完抓取的分页内容后,把当前的页数保存到主表中,替换掉原来的当前分页数,若网络异常就会从这个页数开始,避免了从第一页开始重复抓取;//保存分页内容infolistinfolist=newinfolist();infolist.sethasadd(0);infolist.setcurrentpage(i);……infolistmapper.insert(infolist);//更新当前页,其中i为步骤四中循环时的值infomaininfomain=newinfomain();infomain.setcurrentpage(i);……infomainmapper.updatebyid(infomain)。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1