当前位置: 首页 > 后端技术 > Node.js

Java爬虫:使用Jvppeteer(Puppeteer)轻松爬取淘宝商品

时间:2023-04-03 13:49:00 Node.js

JavaCrawler:使用Jvppeteer(Puppeteer)轻松爬取淘宝商品如果要爬取某宝的商品,如果只是使用HttpURLConnection发送请求,则故障率非常高。一般如果要保证成功率,都会选择真实的浏览器进行爬取。以往常用的方案是selenium或者phantomjs,但是两者的环境配置太麻烦,对程序员极其不友好。自Google推出Puppeteer以来,Puppeteer迅速走红,得到了大家的一致好评。它是一个NodeJS库,不过今天不是用它来爬某宝产品,而是用Java语言写的Jvppeteer。Jvppeteer和Puppeteer的实现原理是一样的。这个想法是使用多线程。一个线程负责抓取一个页面(后面的内容会用page代替page)在线程池中创建一个线程数相同的页面队列。该页面被放置在LinkedBlockingQueue队列中。每当有爬取任务时,就从队列中取出一个页面,当爬取任务完成后,再将页面放回队列中。这样做的原因是为了复用页面,减少页面的创建频率,但需要注意的是一个页面不能使用时间过长或使用次数过多,以防崩溃拦截图片和多媒体资源的加载,以及加载多媒体资源和图片会大大影响页面的加载速度,从而影响爬虫的效率,所以应该拦截(可选)。我们选择获取整个页面内容,然后解析得到商品信息代码实现1.启动浏览器//指定启动路径,启动浏览器Stringpath=newString("F:\\javatutorial\\49issue\\vuejs\\puppeteer\\.local-chromium\\win64-722234\\chrome-win\\chrome.exe".getBytes(),"UTF-8");ArrayListargList=newArrayList<>();LaunchOptionsoptions=newOptionsBuilder().withArgs(argList).withHeadless(false).withExecutablePath(path).build();argList.add("--无沙箱");argList.add("--disable-setuid-sandbox");浏览器browser=Puppeteer.launch(options);2.创建页面队列和线程池//启动一个线程池多线程捕获intthreadCount=5;ThreadPoolExecutorexecutor=newThreadPoolExecutor(threadCount,threadCount,30,TimeUnit.SECONDS,newLinkedBlockingDeque<>());CompletionServiceservice=newExecutorCompletionService(executor);//同时打开5个页面进行抓取,这些页面可以多次使用,从而降低创建网页的性能消耗LinkedBlockingQueuepages=newLinkedBlockingQueue<>();对于(inti=0;i{//if("image".equals(request.resourceType())||"media".equals(request.resourceType())){////遇到多媒体或图片资源请求,拒绝,加载页面加载//request.abort();//}else{//其他资源释放//request.continueRequest();//}//});//page.setRequestInterception(true);pages.put(page);//放到队列后面,block}3.定义爬虫线程的静态内部类staticclassCrawlerCallableimplementsCallable{privateLinkedBlockingQueuepages;publicCrawlerCallable(LinkedBlockingQueuepages){this.pages=pages;}@OverridepublicObjectcall(){页面page=null;尝试{page=pages.take();PageNavigateOptions导航选项=新的PageNavigateOptions();//如果不设置domcontentloaded,页面导航完成,那么goTo方法会超时,因为图片请求被拦截,页面不会到达loaded阶段navigateOptions.setWaitUntil(Arrays.asList("domcontentloaded"));page.goTo("https://item.taobao.com/item.htm?id=541605195654",navigateOptions);字符串内容=page.content();返回解析项(内容);}catch(Exceptione){e.printStackTrace();}finally{if(page!=null){try{pages.put(page);//将抓取到的网页放回队列}catch(InterruptedExceptione){e.printStackTrace();}}}返回空值;}}4。解析乘积,得到结果//ResultsetList>futures=newArrayList<>();//爬取100倍长start=System.currentTimeMillis();对于(整数我=0;我<100;i++){Futurefuture=service.submit(newCrawlerCallable(pages));futures.add(未来);}//关闭线程池executor.shutdown();//得到结果inti=0;for(Futureresult:futures){Objectitem=result.get();我++;System.out.println(i+":"+Constant.OBJECTMAPPER.writeValueAsString(item));}longend=System.currentTimeMillis();System.out.println("时间:"+(end-start));经过测试,爬虫速度非常快,15s完成100个任务,但是不同的电脑配置和带宽会有不同的结果,因为爬虫吃的配置和带宽比较多。总结除了创建页面队列,还可以创建浏览器队列,因为一个浏览器可能会永久崩溃,你可以在项目启动时启动它。浏览器数量,当一个浏览器达到一定的使用次数(如2000次)或使用时间(2h)时,关闭浏览器,然后取出队列中的另一个浏览器,启动一个浏览器放入队列中同一时间。完整代码地址:demo