यहां तक कि "टेरी" आईटी-कर्मचारी के जीवन में, कभी-कभी ऐसा क्षण आता है जब आपको न केवल अपनी गली से बाहर निकलने की जरूरत होती है, बल्कि अपने आप को निवास के एक नए स्थान पर स्थानांतरित कर देता है। ऐसे मामलों में, एक साधारण व्यक्ति खुद को इंटरनेट के साथ उत्पन्न करता है और उपयुक्त विकल्पों की तलाश में रियल एस्टेट साइटों को छान-बीन करता है जो मानचित्र पर चिह्नित, लिखित या मुद्रित किए जाते हैं, और फिर व्यवस्थित रूप से फ़ोन किए जाते हैं। यदि चक्र का अंत आता है, और कार्य अभी तक पूरा नहीं हुआ है -
goto line 1
... और किसी स्तर पर व्यक्ति ऊब गया है और वह एजेंसी में जाता है।
इसलिए मेरे जीवन में यह एक चाल के लिए समय था, लेकिन इस तरह की नियमित गतिविधि के पीछे कई दिन बिताने के बाद, मुझे याद आया कि
आँख बंद करके दाढ़ी रखने से
यैंडेक्स.पैप्स जैसी अद्भुत सेवा होती है, और उनके पास एक समान अद्भुत
एपीआई है । एक सुबह बैठने और PHP और XPath में सबसे सरल हड़पने वाले के साथ सब कुछ संयोजित करने के बाद, मुझे ऐसा रंगीन नक्शा मिला, जहाँ आप अलग-अलग मार्करों के साथ किसी भी मानदंड का उपयोग करके वस्तुओं (अपार्टमेंट) को चिह्नित कर सकते हैं, या बस एक नज़र के साथ मूल्यांकन कर सकते हैं कि उनमें से कौन वांछित स्थान के करीब है ( मेरे मामले में यह एक मेट्रो था):

मुझे तुरंत यह कहना चाहिए कि मेरे लिए यह एक अपार्टमेंट खोजने का पहला अनुभव है और इसलिए मुझे कुछ समान करने वाली सेवा के बारे में पता नहीं है - हालांकि, खोज के कई दिनों के बाद, मुझे माध्यमिक अचल संपत्ति बाजार में ऐसा कुछ नहीं मिला। और मैंने पाया होगा - इस पोस्ट को लिखने का कोई कारण नहीं होगा, इसलिए हम जल्द से जल्द जारी रखेंगे, जब तक कि एक हबल्यूजर ने अपना वजनदार "nya" नहीं डाला होगा ...
धरनेवाला
हम रियल एस्टेट बुलेटिन वेबसाइट से जानकारी लेंगे: उनके पास फ़िल्टर की एक गुच्छा के साथ एक सुविधाजनक खोज है, लेकिन एक नक्शे के बिना, जो मेरे जैसे लोगों के लिए बहुत समस्याग्रस्त है जो हर गली को एक कीप के रूप में नहीं जानते हैं।
साइट में प्रिंट मोड में एक पृष्ठ पर सभी खोज परिणामों (300 से अधिक नहीं) को देखने की क्षमता है - यह वह है जो हम उपयोग करेंगे। URL का यह रूप है:
http:
मान लीजिए कि हमें वांछित फ़िल्टर परिणामों वाला एक पृष्ठ मिलता है। इससे अपार्टमेंट की सूची कैसे प्राप्त करें? आमतौर पर मैं इस समस्या को नियमित रूप से हल करता हूं, लेकिन इस साइट में कुछ विशेष HTML संरचना है, इसलिए यह XPath (
W3Schools ) का उपयोग करना आसान हो गया। इसकी मदद से, तालिका में पंक्तियों की एक सूची प्राप्त करना आसान है (
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL.; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url..($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset=> <title>Map grabber</title> <script src= type=></script> <script src=></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id=></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker=>. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL.; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url..($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset=> <title>Map grabber</title> <script src= type=></script> <script src=></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id=></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker=>. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL.; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url..($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset=> <title>Map grabber</title> <script src= type=></script> <script src=></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id=></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker=>. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL.; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url..($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset=> <title>Map grabber</title> <script src= type=></script> <script src=></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id=></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker=>. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL.; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url..($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset=> <title>Map grabber</title> <script src= type=></script> <script src=></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id=></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker=>. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL.; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url..($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset=> <title>Map grabber</title> <script src= type=></script> <script src=></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id=></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker=>. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL.; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url..($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset=> <title>Map grabber</title> <script src= type=></script> <script src=></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id=></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker=>. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)
), - , , DOMNode
.
:
// . $all = array(); $baseURL = 'http://www.bn.ru/zap_fl.phtml?print=printall&'; // , . $empty = iconv('utf-8', 'cp1251', ' 0'); // . foreach ((array) $_REQUEST['region'] as $region) { $url = $baseURL."region$region=$region&"; // ... // , 300 - // , 300. foreach (range(0, 10000, 1000) as $price0) { $reqURL = $url."price1=$price0&price2=".($price0 + 999); // - . . $data = dl($reqURL); if (!strpos($data, $empty)) { // . $offers = parse($data); $all = array_merge($all, $offers); } // . usleep(200000); } }
dl() cURL file_get_contents()
- , , .
parse() HTML .
function parse($html) { // DOMDocument, UTF-8 ( , // ). $html = '<?xml encoding="UTF-8">'.iconv('cp1251', 'utf-8', $html); $doc = new DOMDocument('1.0', 'utf-8'); @$doc->loadHTML($html) or die('loadHTML: '.$html); // . $xpath = new DOMXPath($doc); // , - // () , . $nodes = $xpath->query('//table[@class="results"]/tr[th[@class="head_kvart"] or td[@width or @class="tooltip"]]'); // . $results = array(); // (, ) - // . $roomCount = 1; // $nodes - - (tr). foreach ($nodes as $row) { // - , .. $cells = array(); $cell = $row->firstChild; while ($cell) { $cell->nodeType == XML_ELEMENT_NODE and $cells[] = trim($cell->nodeValue); $cell = $cell->nextSibling; } if (count($cells) == 1) { // - // . . $roomCount = (int) reset($cells); } else { $cells[0] = $roomCount; // colspan - // . if (count($cells) == 10) { array_splice($cells, 6, 1, array(0, '', $cells[6], '')); } // , . $html = $row->ownerDocument->saveXML($row); if (preg_match('~<a href="([^"]+)~u', $html, $match)) { array_unshift($cells, 'http://www.bn.ru'.$match[1]); } else { array_unshift($cells, ''); } // , . $keys = array('url', 'rooms', 'address', 'floors', 'houseType', 'area', 'areaLiving', 'areaKitchen', 'toilet', 'price', 'conditions', 'seller', 'phone', 'notes'); $result[] = array_combine($keys, $cells); } } return $result; }
, - $all
. - . :
array( 'url' => 'http://www.bn.ru/detail/flats/xxxxxx.html?from=search', 'rooms' => 1, 'address' => '7 ., xxx', 'floors' => '1\\5', 'houseType' => '', 'area' => '30', 'areaLiving' => '18.3', 'areaKitchen' => '6', 'toilet' => ' ', 'price' => '3100', 'conditions' => ' ', 'seller' => 'xxxxx ', 'phone' => '(965) xxxxxxx', 'notes' => ' ', )
HTML .:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Map grabber</title> <script src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU" type="text/javascript"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <style> html, body, .#map { margin: 0; padding: 0; } #map { width: 100%; height: 800px; } </style> </head> <body> <div id="map"></div> </body> </html>
jQuery , .
, . JavaScript :
// . var coords = [] // . var info = [] <?foreach ($all as $offer) {?> coords.push('-, <?=$offer['address']?>') info.push(<?=json_encode($offer, JSON_UNESCAPED_UNICODE)?>) <?}?> ymaps.ready(init);
- init()
. MultiGeocoder
API ; ( coords ), ( ), .
function init() { // -: var map = new ymaps.Map('map', { center: [59.932666, 30.329596], zoom: 13, behaviors: ['default', 'scrollZoom'], }) // : map.controls .add('zoomControl', {left: 5, top: 5}) .add('mapTools', {left: 35, top: 5}) // . (new MultiGeocoder({boundedBy: map.getBounds()})) .geocode(coords) .then( function (res) { // . for (var i = 0; i < res.geoObjects.getLength(); i++) { var cells = info[i] // - // , . var text = '<p>' + $('<b>').append( $('<a>') .attr({href: cells.url, target: '_blank'}) .text(cells.address) )[0].outerHTML + '</p>' // - , . var geo = res.geoObjects.get(i) // . info[i].geo = geo // . geo.properties.set('balloonContentBody', text) } // . map.geoObjects.add(res.geoObjects) }, function (err) { alert(err) } ) return map }
. . , .
?..
, , . ! , , , .
JavaScript , . , . , , , - , , - , .
- . ( API ):
// [ [_, _], ... ]. var markers = [] // <p data-marker="twirl#redDotIcon">. // twirl#redDotIcon - (preset) . $('p[data-marker] input').val(function (i, value) { var marker = $(this).parent().attr('data-marker') value = $.trim(value) value && markers.push([marker, value]) return value }) // (. init()). cells - {price: 123, rooms: 2, ...}. $.each(info, function (i, cells) { var colored = false for (var i = 0; i < markers.length && !colored; i++) { var item = markers[i] var func = new Function('cells', 'return ' + item[1]); // - , . if (func(cells)) { cells.geo.options.set('preset', item[0]) // . colored = true } } // - . colored || cells.geo.options.set('preset', 'twirl#blueIcon') })
, , -, !
, . , .
UPD: Gist . , :)