1import { Actor } from 'apify';
2import { PlaywrightCrawler } from 'crawlee';
3
4await Actor.init();
5
6
7const input = await Actor.getInput();
8const country = input.COUNTRY_OR_REGION || 'Austria';
9
10const crawler = new PlaywrightCrawler({
11 requestHandler: async ({ page, request, log }) => {
12 log.info(`Processing ${request.url} with label: ${request.label}`);
13
14 if (request.label === 'START') {
15
16 await page.goto('https://adrepository.apple.com/');
17 log.info(`Selecting Country or Region: ${country}`);
18 await page.getByLabel('Country or Region').click();
19 await page.getByLabel(country).check();
20 await page.getByRole('button', { name: 'Apply' }).click();
21
22 log.info('Waiting for results to load...');
23 await page.waitForTimeout(3000);
24 await page.waitForSelector('.br-md-bottom', { state: 'visible', timeout: 60000 });
25
26
27 const buttons = page.locator('.br-md-bottom .button');
28 const buttonCount = await buttons.count();
29 log.info(`Found ${buttonCount} buttons for ad details.`);
30
31 for (let i = 0; i < buttonCount; i++) {
32 log.info(`Processing button ${i + 1} of ${buttonCount}`);
33
34
35 await buttons.nth(i).click();
36 await page.waitForTimeout(3000);
37
38
39 const adDetails = {
40 app: await page.locator('text=App').locator('xpath=following-sibling::*').nth(0).textContent(),
41 developer: await page.locator('text=Developer').locator('xpath=following-sibling::*').nth(0).textContent(),
42 legalName: await page.locator('text=Legal Name').locator('xpath=following-sibling::*').nth(0).textContent(),
43 placement: await page.locator('text=Placement').locator('xpath=following-sibling::*').nth(0).textContent(),
44 format: await page.locator('text=Format').locator('xpath=following-sibling::*').nth(0).textContent(),
45 country: await page.locator('text=Country or Region').locator('xpath=following-sibling::*').nth(0).textContent(),
46 parameters: await page.locator('text=Parameters').locator('xpath=following-sibling::*').nth(0).textContent(),
47 firstImpression: await page.locator('text=First Impression').locator('xpath=following-sibling::*').nth(0).textContent(),
48 latestImpression: await page.locator('text=Latest Impression').locator('xpath=following-sibling::*').nth(0).textContent(),
49 };
50 log.info(`Extracted Ad Details: ${JSON.stringify(adDetails)}`);
51 await Actor.pushData(adDetails);
52
53
54 log.info('Returning to main page...');
55 await page.goBack();
56 await page.waitForSelector('.br-md-bottom', { state: 'visible', timeout: 60000 });
57 }
58
59
60 const nextButton = page.getByLabel('next');
61 if (await nextButton.isVisible() && await nextButton.isEnabled()) {
62 log.info('Navigating to the next page...');
63 await nextButton.click();
64 await page.waitForTimeout(5000);
65 await page.waitForSelector('.br-md-bottom', { state: 'visible', timeout: 60000 });
66
67
68 const buttonsNextPage = page.locator('.br-md-bottom .button');
69 const buttonCountNextPage = await buttonsNextPage.count();
70 log.info(`Found ${buttonCountNextPage} buttons on the next page.`);
71 } else {
72 log.info('No more pages available.');
73 }
74 }
75 },
76});
77
78
79await crawler.addRequests([{ url: 'https://adrepository.apple.com/', label: 'START' }]);
80
81await crawler.run();
82await Actor.exit();