/** * loopnet.com需要美国ip才能访问,所以使用代理服务器 * 免费代理:http://www.xicidaili.com/wt/ * @param $url * @return mixed * @throws FunFangException */ public static function parseLoopnetProperty($url) { if (!$url) { return null; } $dataSourceId = 1000; $html = new \simple_html_dom(); $httpClient = new GuzzleHttp\Client(); try { $content = $httpClient->get($url, ['proxy' => 'tcp://108.61.218.68:8888', 'timeout' => 30])->getBody()->getContents(); } catch (GuzzleHttp\Exception\RequestException $e) { throw new FunFangException("访问 {$url} 时出错!" . $e->getMessage()); } $html->load($content); //对该页面进行简单的检查,判断是否有DataId $dataIdWrapper = $html->find('.property-timestamp', 0); if (!$dataIdWrapper) { throw new FunFangException('您输入的URL可能不正确,解析失败!'); } $dataId = $dataIdWrapper->find('td', 0)->plaintext; $dataId = str_replace(' ', '', $dataId); $dataId = str_replace('ListingID:', '', $dataId); if (!$dataId) { throw new FunFangException('未找到房源ID!'); } //先从数据库中查找 if ($dataId) { $record = Property::where('DataSourceId', $dataSourceId)->where('DataId', $dataId)->first(); if ($record) { return $record; } } //如果数据库中没有记录,从html中解析并保存到数据库 //只采集特定类型房源 $record = new Property(); $record->DataSourceId = $dataSourceId; $record->DataId = trim($dataId); $record->ReferenceUrl = $url; $propertyTds = $html->find('.property-data', 0)->find('td'); for ($i = 0; $i < count($propertyTds); $i = $i + 2) { $dataType = trim($propertyTds[$i]->plaintext); $dataValue = trim($propertyTds[$i + 1]->plaintext); if (StringUtil::equalsIgnoreCase('Price', $dataType)) { //价格 $record->ListPrice = str_replace(',', '', str_replace('$', '', $dataValue)); } else { if (StringUtil::equalsIgnoreCase('Property Type', $dataType)) { //房产类型 //指定采集的房源类型 $specTypes = ['Multifamily', 'Office', 'Industrial', 'Land', 'Residential Income']; if (!in_array($dataValue, $specTypes)) { throw new FunFangException('暂不采集该类型的房源!'); } $propertyTypeEnum = Util::getPropertyTypeEnum($dataValue); if ($propertyTypeEnum) { $record->PropertyType = $propertyTypeEnum['name']; $record->PropertyTypeEnum = $propertyTypeEnum['value']; } } else { if (StringUtil::equalsIgnoreCase('Lot Size', $dataType)) { //土地面积 $lotSqFt = str_ireplace('AC', '', $dataValue); $lotSqFt = str_replace(' ', '', $lotSqFt); $lotSqFt = $lotSqFt * 43560; $record->LotSqFt = $lotSqFt; } else { if (StringUtil::equalsIgnoreCase('Building Size', $dataType)) { //建筑面积 $structureSqFt = str_ireplace('SF', '', $dataValue); $structureSqFt = str_ireplace(' ', '', $structureSqFt); $structureSqFt = str_ireplace(',', '', $structureSqFt); $record->StructureSqFt = $structureSqFt; } } } } } $addressStr = $html->find('.basic-info', 0)->find('h1', 0)->plaintext; $addressStr = str_replace('·', '', $addressStr); $addressRes = $httpClient->get('http://maps.googleapis.com/maps/api/geocode/json?address=' . $addressStr); $addressJson = json_decode($addressRes->getBody()->getContents()); if ($addressJson->status == 'OK') { $addressObj = GoogleGeoHelper::getAddress($addressJson->results); } if ($addressObj) { $record->State = $addressObj->state; $record->County = $addressObj->county; $record->City = $addressObj->city; $record->Address = "{$addressObj->streetNumber} {$addressObj->street}"; $record->PostalCode = $addressObj->postalCode; //$record->Location = DB::raw("GeomFromText('POINT($addressObj->lng $addressObj->lat)')"); $record->Location = "{$addressObj->lng},{$addressObj->lat}"; } $record->Description = $html->find('.description', 0)->find('.row', 1)->plaintext; //描述 $photos = $html->find('.carousel-wrapper', 0)->find('.carousel-inner', 0)->find('img'); //照片 $photoUrls = []; foreach ($photos as $photo) { if ($photo->src) { array_push($photoUrls, $photo->src); } else { array_push($photoUrls, $photo->getAttribute('lazy-src')); } } $record->PhotoUrls = implode(',', $photoUrls); $record->save(); $html->clear(); $newRecord = Property::find($record->Id); return $newRecord; }
/** * 通过MLSID或第三方网站URL获取房源 * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string * @throws \Exception */ public function fetch(Request $request) { $this->validate($request, ['type' => 'required', 'q' => 'required']); //搜索内容 $q = trim($request->q); //判断搜索类型 if ($request->type == 0) { //MLSID $model = Property::where('MLSNumber', $q)->first(); if ($model) { //return view('property._detail', ['record' => $record]); $view = view('property._detail', ['record' => $model]); return response()->json(['model' => $model, 'view' => $view]); } throw new Exception('未找到!'); } else { if ($request->type == 1) { //第三方网站URL $domain = UrlUtil::getMainDomain($q); if (StringUtil::equalsIgnoreCase($domain, 'loopnet.com')) { $model = Util::parseLoopnetProperty($q); $view = view('property._detail', ['model' => $model])->render(); return response()->json(['model' => $model, 'view' => $view]); } else { if (StringUtil::equalsIgnoreCase($domain, 'newhomesource.com')) { $model = Util::parseNewhomesourceProperty($q); $view = view('property._detail', ['model' => $model])->render(); return response()->json(['model' => $model, 'view' => $view]); } else { throw new Exception('您输入的网站URL暂不支持!'); } } } else { throw new Exception('搜索类型错误!'); } } }