百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Java爬虫:使用Jvppeteer(Puppeteer)爬淘宝商品就这么简单?

liuian 2025-05-05 17:00 99 浏览

大家都知道,想要爬取某宝的商品,如果只是用HttpURLConnection发个请求,失败率是很高的。一般想要保证成功率的话,都会选择真实的浏览器去抓取。

以前常用的解决方案是selenium或phantomjs,但是它两的环境配置太麻烦了,对程序员极度不友好,自从谷歌推出Puppeteer后,puppeteer迅速流行起来,获得大家一致称赞。它是一个NodeJS库,但今天并不是要使用它来爬取某宝商品,而是使用Java语言写的Jvppeteer,Jvppeteer与Puppeteer是同样的实现原理。


思路:

  1. 使用多线程,一个线程负责一个页面的爬取,接下来的内内容会使用page代替页面
  2. 创建与线程池线程数相同的page队列,放在LinkedBlockingQueue队列里,每当有爬取任务时,就从队列里取出一个page,爬取任务完成时,将page放回队列的后面。这样做的原因是重复利用page,减少页面的创建频率,但是要注意的是一个页面不能利用太久或者次数太多,防止出现crash的情况
  3. 拦截图片和多媒体资源的加载,多媒体资源和图片的加载会极大影响页面的加载速度,从而影响爬虫效率,所以要拦截(可选)。
  4. 我们选择获取整个页面内容,然后解析得到商品信息

代码实现

1.启动

 //指定启动路径,启动浏览器
        String path = new String("F:\\java教程\\49期\\vuejs\\puppeteer\\.local-chromium\\win64-722234\\chrome-win\\chrome.exe".getBytes(), "UTF-8");
        ArrayList<String> argList = new ArrayList<>();
        LaunchOptions options = new OptionsBuilder().withArgs(argList).withHeadless(false).withExecutablePath(path).build();
        argList.add("--no-sandbox");
        argList.add("--disable-setuid-sandbox");
        Browser browser = Puppeteer.launch(options);

2.page队列

  //启动一个线程池多线程抓取
        int threadCount = 5;
        ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCount, threadCount, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
        CompletionService service = new ExecutorCompletionService(executor);
        //打开5个页面同时抓取,这些页面可以多次利用,这样减少创建网页带来的性能消耗
        LinkedBlockingQueue<Page> pages = new LinkedBlockingQueue<>();
        for (int i = 0; i < threadCount; i++) {
            Page page = browser.newPage();
            //拦截请求,可选
//            page.onRequest(request -> {
//                if ("image".equals(request.resourceType()) || "media".equals(request.resourceType())) {
//                    //遇到多媒体或者图片资源请求,拒绝,加载页面加载
//                    request.abort();
//                } else {//其他资源放行
//                    request.continueRequest();
//                }
//            });
//            page.setRequestInterception(true);
            pages.put(page);//往队列后面放,阻塞
        }

3.定义爬取线程

static class CrawlerCallable implements Callable<Object> {

        private LinkedBlockingQueue<Page> pages;
        
        public CrawlerCallable(LinkedBlockingQueue<Page> pages) {
            this.pages = pages;
        }

        @Override
        public Object call() {
            Page page = null;
            try {
                page = pages.take();
                PageNavigateOptions navigateOptions = new PageNavigateOptions();
                navigateOptions.setWaitUntil(Arrays.asList("domcontentloaded"));
                System.out.println("gotothreadName:"+Thread.currentThread().getName());
                page.goTo("https://item.taobao.com/item.htm?id=541605195654", navigateOptions);
                String content = page.content();
              //解析商品
                return parseItem(content);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (page != null) {
                    try {
                        pages.put(page);//把已经抓取完的网页放回队列里
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }
        
    }

4.关闭线程池,获取结果

 //结果集
        List<Future<Object>> futures = new ArrayList<>();
        //抓取100次
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100; i++) {
            Future<Object> future = service.submit(new CrawlerCallable(pages));
            futures.add(future);
        }

        //关闭线程池
        executor.shutdown();
        //获取结果
        int i = 0;
        for (Future<Object> result : futures) {
            Object item = result.get();
            i++;
            System.out.println(i + ":" + Constant.OBJECTMAPPER.writeValueAsString(item));
        }
        long end = System.currentTimeMillis();
        System.out.println("时间:" + (end - start));

在俺电脑测试,100个爬取任务只需要15s,速度还是非常的快。速度的快慢受到根据电配置以及带宽的影响,配置越好,速度越快。

相关推荐

m2固态硬盘安装系统教程(m2固态如何装系统)

加装m.2固态硬盘后,重装系统的操作步骤如下:1、下载U盘启动盘制作工具,下载一个GHOST版最新的WIN7,准备一个足够大的U盘(16G足够了),用U盘启动盘制作工具将其制作成启动U盘;2、插入新电...

运行chkdsk工具(运行chkdsk工具怎么解决)

1、win+R键打开运行,输入cmd。2、输入并回车执行chkdsk/?命令,可以了解chkdsk命令的使用方法。3、比如一些常用的命令,输入并按回车执行chkdskm:/f命令,可以检...

办公软件2007官方下载免费完整版

office字体都变成了英文是因为设置了英文模式。具体的解决步骤如下:我们需要准备的材料分别是:电脑、Word文档。1、首先我们打开Word文档,点击打开左上角的文件中的“选项”。2、然后我们在弹出来...

手机u盘有必要买吗(手机u盘需要什么软件)

网上卖的手机U盘大都是各地的实体数码店进行发货和销售的。他们采用的U盘质量和工厂生产的质量是一致的。并没有什么区别对待。而且由于网上销售费用比较低,所以他在售卖比实体数码店售卖的价格更低,所以这种手机...

电脑系统怎么下载到u盘中(电脑系统win7纯净版下载官方免费版最新版)

下载电脑系统,可以到电脑系统资源下载网站,找到下载页面的下载点,右击下载点,选择迅雷下载,可以把系统文件下载到硬盘里,然后插上U盘,将下载好的系统文件复制到U盘。另一种方法是,将迅雷软件的默认下载路径...

小米主题安装器(红米主题商店app下载安装)

很抱歉,一加九手机无法直接安装小米主题。因为一加九和小米手机使用的是不同的操作系统和主题引擎,它们之间不兼容。一加九使用的是基于Android的OxygenOS操作系统,而小米手机使用的是基于Andr...

hp电脑恢复出厂系统(hp电脑恢复出厂系统操作)

  在开始菜单的【设置】中找到【重置此电脑】的选项即可开始重置恢复到出厂设置;如果您需要整个硬盘格式化,可以选择其中的【删除所有文件】的选项,等待系统设置完成之后会重新进入新系统设置。以下是详细介绍:...

ghost做c盘镜像的步骤(ghost制作镜像步骤)

共9个步骤:1、一般GHOST工具是在PE启动后使用,这个就是PE中GHOST所在路径,找到这个软件并运行。2、界面是英文版本的,因为软件的易操作易学习性,所以这个软件基本没有中文版版本,然后在弹出的...

win10家庭版怎么激活系统(win10家庭版激活步骤)

win10家庭中文版怎么激活1.在win10系统桌面上,点击左下角的开始按钮选择设置选项进入。2.进入设置列表菜单,点击更新和安全选项进入。3.点击激活选项继续下一步操作。4.在弹出输入产品密钥的对话...

office2010和2016区别(office2010和2016差别大不大)

一、指代不同1、word2010:Word2010是Microsoft公司开发的Office2010办公组件之一,主要用于文字处理工作。2、word2016::Word2016是Microsoft公司...

在电脑上怎么截图(在电脑上怎么截图保存到桌面)
  • 在电脑上怎么截图(在电脑上怎么截图保存到桌面)
  • 在电脑上怎么截图(在电脑上怎么截图保存到桌面)
  • 在电脑上怎么截图(在电脑上怎么截图保存到桌面)
  • 在电脑上怎么截图(在电脑上怎么截图保存到桌面)
win10官网下载教程(windows官网下载win10)

步骤1首先打开360安全浏览器步骤2在搜索框中输入“微软官网”,点击“搜索”按钮步骤3点击进入微软官网步骤4下滑界面,在下方可以看到可以下载的系统,此处以windows10企业版下载为例,点击这个版本...

恢复帝app下载(恢复帝app官方)

微信删除好友一般是不能恢复的,有时候在网上会看到一些关于微信删除好友可以帮助恢复的黑客,大多数都是骗人的,因此,再着急恢复好友也需要理智、谨防上当受骗。1.电源:首先确认摄像头通电是否正常状态,指示灯...

系统之家下载安装(系统之家安装版)

是靠谱的。系统之家(HomeSystem)广义上包含了电脑系统安装和手机系统安装,在之前手机软件还不是很普及的时候一般特指电脑系统安装,可如今手机用户大量的出现,安卓系统可以说超过Windows系统...

win10正版系统官网原版纯净版老电脑

一,纯净版Win10系统是根据正版系统制作的,没有夹杂其它软件和驱动,和正版系统一样安装完后需要打各种驱动和根据安装常用软件。二,本质上纯净版Win10也是盗版系统,这是和正版系统最大的区别,而且可能...