23
GetDayHours = {
(GetElement {
Select.DayHours
} {
Gather.HoursDay
})
}
GetDetailItem = {
(GetElement {
Select.DetailItem
} {
Gather.AriaLabel
})
}
GetElement = {
\selector gatherer.{
\expectedValue.{
selector
gatherer -> actualValue
(Sequence.Guard {
(@Core.Equal {
expectedValue
} {
actualValue
})
})
Gather.Text
}
}
}
Main = {
(Browser.Load {
"https://www.google.com/ncr"
})
Setup -> { startingUrl maxPages clickDelay }
(Browser.Load {
startingUrl
})
(Browser.Wait {
clickDelay
})
(Sequence.Take {
maxPages
} {
(State.TurnPages {
(Browser.Wait {
clickDelay
})
Select.NextButton
} {
(Sequence.Annotate {
"Did not find the return button"
} {
(Sequence.Require {
Select.ReturnButton
})
})
Browser.Click
(Browser.Wait {
clickDelay
})
})
})
Select.BusinessLink
Browser.Navigate
(@Core.Unit #{
name: {
(Sequence.Annotate {
"Did not find the name"
} {
(Sequence.Require {
Select.Name
})
})
}
rating: {
Select.Rating
}
reviewCount: {
Select.ReviewCount
Gather.Number
}
price: {
Select.Price
}
address: {
(GetDetailItem {
"Address"
})
}
website: {
(GetDetailItem {
"Website"
})
}
phone: {
(GetDetailItem {
"Phone"
})
}
mondayHours: {
(GetDayHours {
"Monday"
})
}
tuesdayHours: {
(GetDayHours {
"Tuesday"
})
}
wednesdayHours: {
(GetDayHours {
"Wednesday"
})
}
thursdayHours: {
(GetDayHours {
"Thursday"
})
}
fridayHours: {
(GetDayHours {
"Friday"
})
}
saturdayHours: {
(GetDayHours {
"Saturday"
})
}
sundayHours: {
(GetDayHours {
"Sunday"
})
}
})
}
Setup = {
(@Core.Unit #{
startingUrl: {
"https://www.google.com/maps/search/pizza/@-13.5347332,-71.9875415,15z/data=!3m1!4b1!4m2!2m1!6e5"
}
maxPages: {
4
}
clickDelay: {
1000
}
})
}
TurnPages = \nextButton goBack.{
(State.Up goBack)
(Sequence.Do {
(Sequence.First nextButton)
Browser.Navigate
(State.Up goBack)
})
}
Main
name
String
rating
String
reviewCount
String
price
String
address
String
website
String
phone
String
mondayHours
String
tuesdayHours
String
wednesdayHours
String
thursdayHours
String
fridayHours
String
saturdayHours
String
sundayHours
String
BusinessLink
{
"id2": {
"val": ""
},
"id3": {
"val": ""
},
"class3": {
"section-result-text-content": true
},
"classes1": {
"val": "section-result-title-container"
},
"class2": {
"section-result-header": true
},
"classes": {
"val": "section-result-title"
},
"color": {
"val": "rgb(0, 0, 0)"
},
"tag3": {
"val": "DIV"
},
"classes3": {
"val": "section-result-text-content"
},
"class": {
"section-result-title": true
},
"class1": {
"section-result-title-container": true
},
"childrenLen": {
"val": 2
},
"visible": {
"val": true
},
"tag": {
"val": "H3"
},
"id": {
"val": ""
},
"id1": {
"val": ""
},
"indexes": {
"1": 3,
"2": 1
},
"tag2": {
"val": "DIV"
},
"font": {
"val": "Roboto, Arial, sans-serif"
},
"tag1": {
"val": "DIV"
},
"classes2": {
"val": "section-result-header"
},
"_tolerance": {
"val": 0.044
}
}
DayHours
{"childrenLen":{"val":0},"color":{"val":"rgb(0, 0, 0)"},"class1":{"widget-pane-info-open-hours-row-interval":true},"tag3":{"val":"TR"},"classes":{"val":""},"class2":{"widget-pane-info-open-hours-row-data":true},"class3":{"widget-pane-info-open-hours-row-row":true,"section-info-hoverable":true},"colIndex":{"val":1},"id2":{"val":""},"tag2":{"val":"TD"},"id3":{"val":""},"indexes":{"0":0,"1":1,"2":3},"tag1":{"val":"UL"},"tag":{"val":"LI"},"font":{"val":"Roboto, Arial, sans-serif"},"classes2":{"val":"widget-pane-info-open-hours-row-data"},"id1":{"val":""},"classes3":{"val":"widget-pane-info-open-hours-row-row section-info-hoverable"},"id":{"val":""}}
DetailItem
{"childrenLen":{"val":9},"color":{"val":"rgb(0, 0, 0)"},"class1":{"section-info-action-button":true},"tag3":{"val":"DIV"},"classes":{"val":"section-info-line"},"class2":{"section-info":true,"section-info-hoverable":true},"class":{"section-info-line":true},"id2":{"val":""},"visible":{"val":true},"tag2":{"val":"DIV"},"id3":{"val":""},"indexes":{"0":1,"1":1},"tag1":{"val":"DIV"},"tag":{"val":"DIV"},"font":{"val":"Roboto, Arial, sans-serif"},"id1":{"val":""},"id":{"val":""}}
Name
{
"id2": {
"val": ""
},
"id3": {
"val": ""
},
"classes1": {
"val": ""
},
"color": {
"val": "rgb(0, 0, 0)"
},
"tag3": {
"val": "DIV"
},
"class": {
"GLOBAL__gm2-headline-5": true
},
"childrenLen": {
"val": 0
},
"visible": {
"val": true
},
"tag": {
"val": "H1"
},
"id": {
"val": ""
},
"id1": {
"val": ""
},
"indexes": {
"0": 1,
"1": 1
},
"tag2": {
"val": "DIV"
},
"font": {
"val": "\"Google Sans\", Roboto, Arial, sans-serif"
},
"tag1": {
"val": "DIV"
},
"_tolerance": {
"val": 0.044
}
}
NextButton
{
"prevText": {
"val": ""
},
"tag2": {
"val": "DIV"
},
"class1": {
"n7lv7yjyC35__right": true
},
"id1": {
"val": ""
},
"id2": {
"val": ""
},
"tag3": {
"val": "DIV"
},
"tag": {
"val": "BUTTON"
},
"id3": {
"val": ""
},
"visible": {
"val": true
},
"text": {
"val": ""
},
"classes1": {
"val": "n7lv7yjyC35__right"
},
"color": {
"val": "rgb(112, 117, 122)"
},
"font": {
"val": "Roboto, Arial, sans-serif"
},
"class": {
"n7lv7yjyC35__button": true
},
"tag1": {
"val": "DIV"
},
"indexes": {
"0": 1,
"1": 1,
"2": 0
},
"childrenLen": {
"val": 1
},
"id": {
"val": "n7lv7yjyC35__section-pagination-button-next"
},
"_tolerance": {
"val": 0.044
}
}
Price
{
"childrenLen": {
"val": 0
},
"color": {
"val": "rgba(0, 0, 0, 0.54)"
},
"classes": {
"val": ""
},
"class3": {
"section-rating-term": true
},
"id2": {
"val": ""
},
"visible": {
"val": true
},
"prevText": {
"val": ""
},
"tag2": {
"val": "SPAN"
},
"id3": {
"val": ""
},
"indexes": {
"0": 1,
"1": 0,
"2": 1
},
"tag1": {
"val": "SPAN"
},
"classes1": {
"val": ""
},
"tag": {
"val": "SPAN"
},
"font": {
"val": "Roboto, Arial, sans-serif"
},
"classes2": {
"val": ""
},
"id1": {
"val": ""
},
"classes3": {
"val": "section-rating-term"
},
"id": {
"val": ""
},
"_tolerance": {
"val": 0.044
}
}
Rating
{"id2":{"val":""},"id3":{"val":""},"class3":{"section-rating-line":true},"classes1":{"val":""},"classes":{"val":"section-star-display"},"color":{"val":"rgba(0, 0, 0, 0.54)"},"tag3":{"val":"DIV"},"classes3":{"val":"section-rating-line"},"class":{"section-star-display":true},"childrenLen":{"val":0},"visible":{"val":true},"tag":{"val":"SPAN"},"id":{"val":""},"id1":{"val":""},"indexes":{"0":0,"1":0,"2":0},"tag2":{"val":"SPAN"},"font":{"val":"Roboto, Arial, sans-serif"},"tag1":{"val":"SPAN"},"classes2":{"val":""},"_tolerance":{"val":0.044}}
ReturnButton
{
"id2": {
"val": ""
},
"id3": {
"val": ""
},
"class3": {
"widget-pane-content": true,
"scrollable-y": true
},
"class2": {
"widget-pane-content-holder": true
},
"classes": {
"val": "section-back-to-list-button blue-link noprint"
},
"color": {
"val": "rgb(66, 133, 244)"
},
"tag3": {
"val": "DIV"
},
"class": {
"section-back-to-list-button": true,
"blue-link": true,
"noprint": true
},
"childrenLen": {
"val": 1
},
"visible": {
"val": false
},
"tag": {
"val": "BUTTON"
},
"id": {
"val": ""
},
"id1": {
"val": ""
},
"tag2": {
"val": "DIV"
},
"font": {
"val": "Roboto, Arial, sans-serif"
},
"tag1": {
"val": "DIV"
},
"classes2": {
"val": "widget-pane-content-holder"
},
"_tolerance": {
"val": 0.044
}
}
ReviewCount
{
"childrenLen": {
"val": 0
},
"color": {
"val": "rgba(0, 0, 0, 0.54)"
},
"classes": {
"val": "widget-pane-link"
},
"class": {
"widget-pane-link": true
},
"class3": {
"section-rating-term": true
},
"id2": {
"val": ""
},
"visible": {
"val": true
},
"tag2": {
"val": "SPAN"
},
"id3": {
"val": ""
},
"indexes": {
"0": 0,
"1": 0,
"2": 1
},
"tag1": {
"val": "SPAN"
},
"classes1": {
"val": ""
},
"tag": {
"val": "BUTTON"
},
"font": {
"val": "Roboto, Arial, sans-serif"
},
"classes2": {
"val": ""
},
"id1": {
"val": ""
},
"classes3": {
"val": "section-rating-term"
},
"id": {
"val": ""
},
"_tolerance": {
"val": 0.044
}
}
AriaLabel
return function(element, global) {
return element.children[0].getAttribute('aria-label');
};
true
false
HoursDay
return function(element, global) {
return element.closest('td').previousElementSibling.innerText.trim();
};
true
false
HTML
var result = function (element) {
return element.nodeType === 1 ? element.outerHTML : element.nodeValue;
};
result.noCache = false;
return result;
true
true
Link
var result = function (element) {
var upperTag = function (element) {
return element.tagName ? element.tagName.toUpperCase() : element.tagName;
};
var linkOf = function (element) {
return element && element.href && (element.protocol === "http:" || element.protocol === "https:" || element.protocol == "file:" || element.protocol == "ftp:") ? element.href : null;
};
var original = element;
while (element && (!element.tagName || upperTag(element) !== 'A'))
element = element.parentNode;
var result = linkOf(element);
if (!result) {
if (original.children.length == 1) {
var child = original.children[0];
if (upperTag(child) === 'A') {
result = linkOf(child);
if (!result) {
if (child.children.length == 1) {
child = child.children[0];
if (upperTag(child) === 'A')
result = linkOf(child);
}
}
}
}
}
return result;
};
result.noCache = false;
return result;
false
true
Number
var result = function (element) {
var getText = function () {
return element.nodeType === 1 ? element.innerText : element.nodeValue;
};
var regex = /-?(?=[1-9]|0(?!\d))[\d\,]+(\.\d+)?/;
var first = regex.exec(getText(element));
return first && first.length ? first[0] : null;
};
result.noCache = false;
return result;
false
true
OwnText
var result = function (element) {
var text = [].reduce.call(element.childNodes || [], (a, b) => a + (b.nodeType === 3 ? b.textContent : ''), '');
return text.trim();
};
result.noCache = false;
return result;
false
true
Path
var result = function (element) {
return window.___getPath(element);
};
result.noCache = false;
return result;
false
true
Src
var result = function (element) {
return element.src || "";
};
result.noCache = false;
return result;
false
true
Tag
var result = function (element) {
var upperTag = function (element) {
return element.nodeType === 1 ? element.tagName.toUpperCase() : "HS-NODE";
};
return upperTag(element);
};
result.noCache = false;
return result;
false
true
Text
var result = function (element) {
var text = element.nodeType === 1 ? element.innerText : element.nodeValue;
return text ? text.trim() : "";
};
result.noCache = false;
return result;
true
true
URL
var result = function (element) {
return element.ownerDocument.defaultView.location.href;
};
result.noCache = false;
return result;
false
true
Value
var result = function (element) {
return element.value || element.getAttribute('value');
};
result.noCache = false;
return result;
false
true
childrenLen
var result = function (element) {
return { val: element.nodeType === 1 ? element.children.length : 0 };
};
result.score = 0.7; // Default
return result;
false
true
class
var result = function (element) {
if (element.nodeType !== 1)
element = element.parentElement;
var result = {};
var list = element.classList;
var len = list.length;
for (var i = 0; i < len; i++)
result[list[i]] = true;
return result;
};
result.score = 0.73;
return result;
false
true
class1
var result = window.___makeRelatedGatherer('class', function (element) {
return element.parentNode;
});
result.score = 0.87;
return result;
false
true
class2
var result = window.___makeRelatedGatherer('class', function (element) {
return element.parentNode.parentNode;
});
result.score = 0.87;
return result;
false
true
class3
var result = window.___makeRelatedGatherer('class', function (element) {
return element.parentNode.parentNode.parentNode;
});
result.score = 0.9;
return result;
false
true
classes
var result = function (element) {
if (element.nodeType !== 1)
element = element.parentElement;
return { val: typeof element.className === 'string' ? element.className : null };
};
result.score = 0.91;
return result;
false
true
classes1
var result = window.___makeRelatedGatherer('classes', function (element) {
return element.parentNode;
});
result.score = 0.95;
return result;
false
true
classes2
var result = window.___makeRelatedGatherer('classes', function (element) {
return element.parentNode.parentNode;
});
result.score = 0.95;
return result;
false
true
classes3
var result = window.___makeRelatedGatherer('classes', function (element) {
return element.parentNode.parentNode.parentNode;
});
result.score = 0.81;
return result;
false
true
colIndex
var result = function (element) {
var maxUp = 5;
function closestTd(element) {
for (var up = 0; up < maxUp; up++) {
if (!element) return null;
if (/^t[dh]$/i.test(element.nodeName))
return element;
element = element.parentNode;
}
return null;
}
function colSpan(col) {
return parseInt((col && col.nodeType == 1 && /^t[dh]$/i.test(element.nodeName)) ? (col.getAttribute('colSpan') || 1) : 0);
}
function endIndex(element) {
var colPos = colSpan(element);
while (element) {
element = element.previousSibling;
colPos += colSpan(element);
}
return colPos;
}
element = closestTd(element);
if (element)
return { val: endIndex(element.previousSibling) };
else
return {};
};
result.score = 0.7; // Default
return result;
false
true
color
var result = function (element) {
if (element.nodeType !== 1)
element = element.parentElement;
return { val: window.getComputedStyle(element).color };
};
result.score = 1;
return result;
false
true
font
var result = function (element) {
if (element.nodeType !== 1)
element = element.parentElement;
return { val: window.getComputedStyle(element)['font-family'] };
};
result.score = 1;
return result;
false
true
header
var result = function header(element) {
var upperTag = function (element) {
return element.tagName ? element.tagName.toUpperCase() : element.tagName;
};
var getColumnIndex = function (e) {
var maxLevels = 3;
while (e && upperTag(e) !== 'TD' && maxLevels > 0) {
e = e.parentElement;
maxLevels--;
}
if (e && upperTag(e) === 'TD') {
var index = 0;
while ((e = e.previousElementSibling)) {
index += e.colSpan || 1;
}
return index;
}
else
return -1;
};
var colIndex = getColumnIndex(element);
if (colIndex !== -1) {
while (element && upperTag(element) !== 'TABLE')
element = element.parentElement;
if (element && upperTag(element) === 'TABLE') {
var tds = element.querySelectorAll('th,td');
var index = 0;
var latest = null;
for (var td of tds) {
if (index > colIndex)
return { val: (latest.innerText || "").trim() };
latest = td;
index += td.colSpan || 1;
}
}
}
return {};
};
result.score = 0.9;
return result;
false
true
id
var result = function (element) {
if (element.nodeType !== 1)
element = element.parentElement;
return { val: element.id };
};
result.score = 0.98;
return result;
false
true
id1
var result = window.___makeRelatedGatherer('id', function (element) {
return element.parentNode;
});
result.score = 0.91;
return result;
false
true
id2
var result = window.___makeRelatedGatherer('id', function (element) {
return element.parentNode.parentNode;
});
result.score = 0.91;
return result;
false
true
id3
var result = window.___makeRelatedGatherer('id', function (element) {
return element.parentNode.parentNode.parentNode;
});
result.score = 0.88;
return result;
false
true
indexes
var result = function (element) {
function getElementIndex(node) {
var index = 0;
while ((node = node.previousSibling)) {
index++;
}
return index;
}
var result = {};
var level = 0;
var levels = 3;
while (element && level < levels) {
result[level] = getElementIndex(element);
level++;
element = element.parentElement
}
return result;
};
result.score = 0.86;
return result;
false
true
names
var result = function (element) {
function getElementName(node) {
return node.nodeType === 1 ? (node.name || node.getAttribute('name')) : null;
}
var result = {};
var level = 0;
var levels = 3;
while (element && level < levels) {
var name = getElementName(element);
if (name) result[level] = name;
level++;
element = element.parentElement
}
return result;
};
result.score = 0.75;
return result;
false
true
prevText
var result = function (element) {
var maxDepth = 0;
var maxLength = 128;
while (element && !element.previousElementSibling && maxDepth > 0) {
element = element.parentElement;
maxDepth--;
}
if (element && element.previousElementSibling) {
var fullText = element.previousElementSibling.innerText;
if (fullText.length < maxLength)
return { val: fullText };
}
return null;
};
result.score = 0.7; // Default
return result;
false
true
tag
var result = function (element) {
var upperTag = function (element) {
return element.nodeType === 1 ? element.tagName.toUpperCase() : "HS-NODE";
};
return { val: upperTag(element) };
};
result.score = 1;
return result;
false
true
tag1
var result = window.___makeRelatedGatherer('tag', function (element) {
return element.parentNode;
});
result.score = 1;
return result;
false
true
tag2
var result = window.___makeRelatedGatherer('tag', function (element) {
return element.parentNode.parentNode;
});
result.score = 1;
return result;
false
true
tag3
var result = window.___makeRelatedGatherer('tag', function (element) {
return element.parentNode.parentNode.parentNode;
});
result.score = 1;
return result;
false
true
text
var result = function (element) {
if (element.nodeType !== 1)
return null;
if (window.___textTags.has(element.tagName.toUpperCase()))
return null;
var text = element.innerText;
if (text.length > 64)
return null;
return { val: text };
};
result.score = 0.1;
return result;
false
true
visible
var result = function (element) {
if (element.nodeType !== 1)
element = element.parentElement;
return { val: element.offsetParent !== null };
};
result.score = 1;
return result;
false
true
false
*://*.doubleclick.net/*
*://*.amazon-adsystem.com/*
*://*.google-analytics.com/*
*://*.googlesyndication.com/*
*://*.advertising.com/*
*://*.imrworldwide.com/*
*://*.quantserve.com/*
*://*.googleadservices.com/*
*://*.scorecardresearch.com/*
ac3df7fc51034d01ae5ed0b2337892ee
NqSX1Uiv2dYCgbkYsnUjGFrY8Zf7HUo7Jxn6I1irs2EVK/grgd36gWCp7M7DcdKHg0Mu+slkjJU3odVqd3fpgau93mlNqtiWrJFENgmJdY5APFQtPHqfotg9oKRy2uXDwtvn0rBQOat1rvsGhW5P8wm8BSJMyvkRjCMQH+uxDKHX4MdSzIPIl4YkUv9+kJ4+vG4KUVLvrRXjxFxVEGUcpHNXgnUc/JYad2otrw6LJoXB5z6AimUppastkPzGMyL9xXYx8rGFJEAKkhllFTJLWk3rlC8K1gw5f2GDXVWzznL1ho4IhVVViuOIJpEyNsbftIjI/E5ecbvZ/zSLiDcWWQ==