Yandex.Maps APIを使用して住宅問題を解決します

「テリー」なIT従業員でさえ、通りから逃げ出すだけでなく、新しい居住地に完全に転身する必要があるときが来ることがあります。 このような場合、普通の人がインターネットで武装し、地図上にマークされ、書き出されるか、印刷された後、体系的に電話をかけられる適切なオプションを探して不動産サイトを探します。 サイクルの終わりが来て、タスクがまだ完了していない場合- goto line 1



ます...そしてある段階で退屈し、代理店に行きます。



だから、私の人生では動きがありましたが、そのような日常的な活動の背後に数日を費やした後、私はblindを盲目的に身に着けることがYandex.Mapsのような素晴らしいサービスを持ち、等しく素晴らしいAPIを持っていることを思い出しました。 ある朝座ってすべてをPHPとXPathの最も単純なグラバーと組み合わせた後、さまざまなマーカーを使用して任意の基準に従ってオブジェクト(アパート)をマークしたり、目的の場所に近いものを一目で評価したりできるカラフルなマップを取得しました(で私の場合は地下鉄でした):



スクリリオンショット







私にとって、これはアパートを見つける最初の経験であるため、同様のことをするサービスについては知らないかもしれませんが、数日間検索した後、二次不動産市場ではこのようなものは見つかりませんでした。 そして、私は見つけたでしょう-この投稿を書く理由はなかっただろうので、habrayuzerの一人が彼の重い「にゃ」を挿入するまで、できるだけ早く続けます...



グラバー



不動産速報のウェブサイトから情報を取得します:彼らは多くのフィルターで便利な検索を行いますが、地図はありません。これはすべての道を記念品として知らない私のような人々にとって非常に問題です。



このサイトには、印刷モードで1ページにすべての検索結果(300以下)を表示する機能があります。これを使用します。 URLの形式は次のとおりです。

 http://www.bn.ru/zap_fl.phtml?print=printall&_
      
      







目的のフィルター結果を含むページを取得するとします。 それからアパートのリストを取得するには? 通常、この問題は定期的に解決しますが、このサイトには特別な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."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."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."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."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."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."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."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 . , :)







All Articles