1import { Actor, Dataset } from 'apify';
2
3await Actor.init();
4
5interface Input {
6 address: string;
7}
8
9const input = await Actor.getInput<Input>();
10if (!input?.address) throw new Error("Missing input!");
11
12const { address } = input;
13
14const zpidScraperInput = {
15 multiple_input_box: address,
16 scrape_type: "property_addresses",
17};
18
19const zpidRun = await Actor.call('sorower/zillow-scrape-address-url-zpid', zpidScraperInput);
20if (!zpidRun.defaultDatasetId) throw new Error('No default dataset ID from the ZPID scraper.');
21
22const zpidDataset = await Dataset.open(zpidRun.defaultDatasetId);
23const { items } = await zpidDataset.getData();
24
25if (!items.length || !items[0].PropertyZillowURL) {
26 throw new Error('PropertyZillowURL not found');
27}
28
29const originalUrl = items[0].PropertyZillowURL;
30const zpidMatch = originalUrl.match(/(\d+)_zpid/);
31if (!zpidMatch) throw new Error('ZPID not found');
32const zpid = zpidMatch[1];
33
34function formatAddress(address: string): string {
35 return address.replace(/,/g, '').replace(/\s+/g, '-').replace(/-{2,}/g, '-').trim();
36}
37
38const formattedAddress = formatAddress(address);
39const finalUrl = `https://www.zillow.com/homedetails/${formattedAddress}/${zpid}_zpid/`;
40
41const detailScraperInput = {
42 extractBuildingUnits: 'all',
43 propertyStatus: 'FOR_SALE',
44 startUrls: [
45 {
46 url: finalUrl,
47 method: 'GET',
48 },
49 ],
50};
51
52const detailRun = await Actor.call('maxcopell/zillow-detail-scraper', detailScraperInput);
53if (!detailRun.defaultDatasetId) throw new Error('No default dataset ID from the detail scraper.');
54
55const detailDataset = await Dataset.open(detailRun.defaultDatasetId);
56const detailItems = await detailDataset.getData();
57
58await Actor.pushData({
59 inputAddress: address,
60 detailData: detailItems.items[0],
61});
62
63await Actor.exit();