使用Apify的Puppetteer抓取工具抓取网站页面

时间:2020-08-25 18:38:15

标签: javascript jquery puppeteer cheerio apify

(*)情况:

你好!

我要刮擦google hotels platform,我点击一个城市,它将给我该城市的所有酒店。 例如New York City的结果,它将为我们提供1200多家酒店,所以我要抓取有关这些酒店的所有信息。

我使用了Apify的Puppeteer Crawler,在 起始网址 中,放置了第一页的网址。 在 链接选择器 中,我将选择器置于酒店详细信息页面。

这就是我在 页面功能 中输入的内容:

async function pageFunction(context) {
    
    const { request, log, skipLinks, page } = context;
   

    //request.userData = list_links;
    if (request.userData.label === 'START') {
        log.info('Store opened!');
       
    }

    if (request.userData.label === 'DETAIL') {
        const { url } = request;
        log.info(`Scraping ${url}`);
        await skipLinks();
        
        const titleP = page.$eval(
            'title',
            (el => el.textContent)
        );
       const priceP = page.$eval(
           'div.JGa7fd',
           (el => el.getAttribute('aria-label'))
       );
        const ratingP = page.$eval(
            'div.iDqPh.BgYkof',
            (el => el.textContent)
        );
        const reviewsNumberP = page.$eval(
            'a.eS7K5e',
            (el => el.textContent)
        );
        const hotelStarP = page.$eval(
            'div.fnmyY > span.CFH2De',
            (el => el.textContent)
        );
        const adressP = page.$$eval(
           'div.K4nuhf span.CFH2De',
           (els) => els[0].textContent
       ); 
       
        const phoneP = page.$$eval(
            'div.K4nuhf span.CFH2De',
            (els) => els[2].textContent

        );
        const websiteP = page.$$eval(
            'a.FKF6mc.TpQm9d',
            (els) => els[0].getAttribute('href')
        );

        
        const [
            title,
            price,
            rating,
            reviewsNumber,
            adress,
            phone,
            hotelStar,
            website,
            
        ] = await Promise.all([
            titleP,
            priceP,
            ratingP,
            reviewsNumberP,
            adressP,
            phoneP,
            hotelStarP,
            websiteP,
        ]);

    
        

        return {
            title,
            price,
            rating,
            reviewsNumber,
            adress,
            phone,
            hotelStar,
            website,
        };
    }
}

(*)问题:

如果您分析页面,您会发现它们不是枚举页面(第1页,第2页,第3页),我们只有“下一个”和“上一个”按钮(即使您分析URL时也没有) “&page = 1/2/3”或类似的东西,如果我们期望这个按钮(下一个按钮),我们将得到它是一个带有role =“ button”且没有任何href属性可供选择的div标签。

(*)问题:

1-如何使用Puppeteer抓取所有页面?如何转到下一页并将其报废?

2-我可以在APify中使用所有伪造的文档吗,或者它们有一些限制?

3- Pure Puppeteer和Apify的Puppeteer有什么区别?

(*)半解决方案:

对于问题1 ,我尝试了此解决方案,与Pure Puppeteer一起使用,转到首页,单击下一步按钮,获取其URL,再次转到下一页,获取其URL等等,直到while循环结束。之后,我将网址复制粘贴到txt文件中,然后将其上传到起始网址。

这是我尝试过的代码源:

const puppeteer = require('puppeteer');

(async function main() {

  try {
    const browser = await puppeteer.launch({ headless: false });
    const [page] = await browser.pages();

    

    const url ="https://www.google.com/travel/hotels/Marrakesh?utm_campaign=sharing&utm_medium=link&utm_source=htls&hrf=CgUIzAgQACIDTUFEKhYKBwjkDxAIGBkSBwjkDxAIGBoYASABsAEAWAFoAYoBKAoSCcxMCO-rXT9AEQMTl9GnSCDAEhIJVRwqc-jwP0ARByaebVl8HsCaATESCU1hcnJha2VzaBokMHhkYWZlZThkOTYxNzllNTE6MHg1OTUwYjY1MzRmODdhZGI4ogEVCggvbS8wNTRydxIJTWFycmFrZXNoqgEbCgIIIRICCAgSAggVEgMIlAISAggvEgIIVBgBqgEHCgMIoQIYAKoBDAoDCLYBEgMIuAEYAaoBBgoCCGQYAKoBCgoCCC4SAghIGAGqAQwKAwiuARIDCLQBGAGqAQoKAghQEgIITxgBqgEMCgMIowESAwimARgBkgECIAE&rp=OAE&ap=KigKEgnMTAjvq10_QBEDE5fRp0ggwBISCVUcKnPo8D9AEQcmnm1ZfB7AMAFanwIKBQjMCBAAIgNNQUQqFgoHCOQPEAgYEhIHCOQPEAgYExgBKACwAQBYAWgBigEoChIJzEwI76tdP0ARAxOX0adIIMASEglVHCpz6PA_QBEHJp5tWXwewJoBMRIJTWFycmFrZXNoGiQweGRhZmVlOGQ5NjE3OWU1MToweDU5NTBiNjUzNGY4N2FkYjiiARUKCC9tLzA1NHJ3EglNYXJyYWtlc2iqARsKAgghEgIICBICCBUSAwiUAhICCC8SAghUGAGqAQcKAwihAhgAqgEMCgMItgESAwi4ARgBqgEGCgIIZBgAqgEKCgIILhICCEgYAaoBDAoDCK4BEgMItAEYAaoBCgoCCFASAghPGAGqAQwKAwijARIDCKYBGAGSAQIgAQ"
    await page.goto(url,{
        waitUntil: 'load',
        // Remove the timeout
        timeout: 0});

  
    //for(i=0;i<10;i+)
    console.log(url);
    console.log('\n');
    while(true){
        await page.click('div.zbLWdb');
        await page.waitFor(30*1000);
        var new_link = page.url();
        
        console.log(new_link);
        console.log('\n\n');
        i++;
    }

    
  } catch (err) {
    console.error(err);
  }
})();

我可以将此脚本放入起始网址以及如何执行此操作吗?

1 个答案:

答案 0 :(得分:0)

我不会为您提供成功刮擦的所有详细信息,但是会给您一些提示。

a)重要的是要正确命名。在这种情况下,您正在使用Puppeteer Scraper。那是一个独立的演员。 PuppeteerCrawler是SDK(JS库)中的类。

b)链接选择器不会单击,它需要查找href(真实链接)。因此它不适用于此用例。

c)在这种情况下,我建议使用PuppeteerCrawler类创建一个新演员(请参见SDK网站中的示例)。

现在回答您的问题:

  1. 您可以在Apify中使用您的代码,它的工作原理相同。允许您将负载分成更多请求的更高级的解决方案是使用enqueueLinksByClickingElements进入下一页。但是我不是100%肯定会在此用例中正常工作。
  2. 这是相同的Puppeteer实例,因此没有限制。 Apify取决于puppeteer软件包。
  3. 唯一的不同是Apify使在Puppeteer中使用身份验证的代理变得简单,否则,是相同的。当然,PuppeteerCrawler为您提供了大量功能,例如自动扩展并发,重试,代理轮换,会话等。