利用高德API++Python解決租房問題

      網友投稿 1113 2022-05-30

      一、課程介紹

      1. 課程背景

      課程來自一段租房血淚史(夸張):事情是這樣的,筆者是接著念大四準備考研,而室友是應屆畢業在找工作,說白了就是都沒有錢,于是打算合租。因為窮所以不可能找有門店的的中介,只能看看趕集、58、和一些租房APP。期間需要考慮兩個人的通勤范圍來選地段,由于對交通的不熟悉,只有選擇自己附近的較貴的地段,花了很多時間閱覽趕集或者58里的個人房源信息,然而個人房源信息中仍充斥著大量中介,抱著一點希望打了幾個電話,得到的回答都是這個價位根本租不到,再高點也租不到(大都與發布的房源信息不符)。最后終于還是在宿舍關閉前一個星期租到一個性價比還可以的隔斷。畢竟隔斷還是不方便的,所以打算在室友找到工作后換一個新地方,于是就有了這個租房腳本和課程。

      相信也有不少的應屆畢業生可能會遭遇同樣的境況,希望這門課能真的幫到大家,也許不光是在租房子方面。推薦閱讀知乎上的一個問題:你有哪些用計算機技能解決生活問題的經歷?

      總結一下租房難的癥結:

      沒錢。

      小中介發布的價位一般都是假的,會浪費你很多時間。

      對交通路線不熟悉以致于選擇面窄。

      如果是多人,得同時考慮多人的通勤時間。

      本課程將解決的問題:

      學習了技術,增長了知識,就能找到好工作,找到好工作就能有錢。

      這次選的房源信息來自58的品牌公寓館,所以沒有那種小中介,價位就我和我室友來說可以接受。其實可以做個分類器過濾趕集上的中介來找低價個人房源的,有需要的同學可以試一下。

      通勤范圍在地圖上圈出,解決了對交通路線不熟悉的問題

      本課程是單人版的,但代碼中只要刪掉一個語句就能當多人用了(但是路徑規劃的功能是只能給一個人用)。如果是直接拿來多人用的話,還是開多個頁面比較好。

      最終效果圖如下:

      由于沒做前端兼容,導致右上角崩了。自用的小工具其實也不用整多好看,效率第一。

      如圖,劃出來的大片藍***塊就是距離工作地點一小時車程內的區域。藍色的標記就是房源,點擊后會自動給出路徑規劃和房源地址。紅色標記(不是"終")是工作地點,在圖里被擋住了。工作地點的輸入框有自動補完的功能,也是很方便的。至于房源文件我們會通過編寫Python腳本在抓取房源信息后生成。

      2. 課程知識點

      本課程項目完成過程中,我們將學習:

      requests、BeautifulSoup、csv?等庫的簡單使用

      高德地圖 Javascript API 的使用

      二、實驗環境

      打開終端,進入?Code?目錄,創建?rent_proj?文件夾, 并將其作為我們的工作目錄。

      $?cd?Code $?mkdir?rent_proj?&&?cd?rent_proj

      安裝需要的庫:

      $?sudo?apt-get?install?python-bs4

      三、實驗原理

      實驗中會用到三個文件:crawl.py,rent.csv與index.html,其中rent.csv由crawl.py生成,是房源文件。crawl.py是一個非常簡單的爬取網頁的腳本。index.html是最重要的顯示地圖的部分。實現的流程大致如下:

      我為什么不把js代碼和css代碼從index.html中分出來呢,寫腳本怎么順手怎么來就好。

      代碼沒有難度,主要就是看看幾個API如何使用,下面給出文檔鏈接:

      高德 JavaScript API 幫助文檔

      高德 JavaScript API 示例中心

      Requests: HTTP for Humans

      Beautiful Soup 4.2.0 文檔

      csv — CSV 文件的讀寫

      四、實驗步驟

      1. 分析頁面

      先分析一下我們需要爬取的頁面:http://bj.58.com/pinpaigongyu/

      選擇好目標價位:

      打開查看器:

      審查元素,分頁上的 1 2 3 4 5 隨便選一個:

      大致了解了它的路徑規則:/pingpaigongyu/pn/{page}/minprice={min_rent}_{max_rent}

      對比第一頁和第一千頁:

      經過觀察,決定將頁面有無.list元素來作為是否已讀取完所有房源的判斷條件。

      看一下頁面能夠提供給我們什么信息:

      框框圈出的信息對我們來說已經足夠了。當然房源的具體經緯度也可以點進去查看代碼得到:

      簡便起見每一個房源就只記錄以下信息:[房源名稱,地址,月租,房源url地址]。

      其中地址直接取房源名稱里的小區名,有的房源第二列是公寓名而不是小區名,那就只能取第一列作為地址了,有些公寓如果合并第一列第二列地圖上會搜不到。

      利用高德API+Python解決租房問題

      2. 編寫Python腳本

      在工作目錄下創建crawl.py文件,這里先直接給出全部代碼。

      #-*-?coding:utf-8?-*-from?bs4?import?BeautifulSoupfrom?urlparse?import?urljoin import?requests import?csv url?=?"http://bj.58.com/pinpaigongyu/pn/{page}/?minprice=2000_4000"#已完成的頁數序號,初時為0page?=?0csv_file?=?open("rent.csv","wb")? csv_writer?=?csv.writer(csv_file,?delimiter=',')while?True: ????page?+=?1 ????print?"fetch:?",?url.format(page=page) ????response?=?requests.get(url.format(page=page)) ????html?=?BeautifulSoup(response.text) ????house_list?=?html.select(".list?>?li")????#?循環在讀不到新的房源時結束 ????if?not?house_list:????????break ????for?house?in?house_list: ????????house_title?=?house.select("h2")[0].string.encode("utf8") ????????house_url?=?urljoin(url,?house.select("a")[0]["href"]) ????????house_info_list?=?house_title.split()????????#?如果第二列是公寓名則取第一列作為地址 ????????if?"公寓"?in?house_info_list[1]?or?"青年社區"?in?house_info_list[1]: ????????????house_location?=?house_info_list[0]????????else: ????????????house_location?=?house_info_list[1] ????????house_money?=?house.select(".money")[0].select("b")[0].string.encode("utf8") ????????csv_writer.writerow([house_title,?house_location,?house_money,?house_url]) csv_file.close()

      鑒于爬的量不大所以就簡單處理了。

      csv一般用作表格文件,直接用文本編輯器打開也可讀,行與行之間就是換行來隔開,列與列之間就是用逗號(也可指定其它字符)隔開,Python標準庫中的csv庫就是用來讀寫csv文件的。

      這里只需要寫csv文件:

      #導入csvimport?csv#?打開rent.csv文件csv_file?=?open("rent.csv","wb")? #?創建writer對象,指定文件與分隔符csv_writer?=?csv.writer(csv_file,?delimiter=',') #?寫一行數據csv_writer.writerow([house_title,?house_location,?house_money,?house_url])#關閉文件csv_file.close()

      requests是一個對使用者非常友好的http庫,看一遍Quickstart就能基本掌握它的使用。

      用到它的地方也就僅僅兩句:

      #?抓取目標頁面response?=?requests.get(url.format(page=page)) #?獲取頁面正文response.text

      Beautiful Soup是一個用來解析html或者xml文件的庫,支持元素選擇器,使用起來也非常方便:

      #?創建一個BeautifulSoup對象html?=?BeautifulSoup(response.text) #?獲取class=list的元素下的所有li元素house_list?=?html.select(".list?>?li") #?得到標簽包裹著的文本house.select("h2")[0].string.encode("utf8") #?得到標簽內屬性的值house.select("a")[0]["href"]

      由于讀取到的鏈接路徑是相對路徑,所以需要urljoin得到完整的url地址。

      urljoin(url,?house.select("a")[0]["href"])

      實驗樓環境中文粘貼進去會變成???,這樣的話幾個公寓房源的位置就不能確定了,不過不影響做實驗。

      講解完畢,運行代碼python crawler.py:

      可能要1分半鐘,可以先去玩一局掃雷。

      筆者用自己的電腦跑差不多是20多秒。

      此時目錄下已生成了rent.csv:

      注意如果你太頻繁地抓取頁面IP可能會被屏蔽,那樣就抓不到頁面而是直接報錯了。如果抓取不成功的話,可以使用這個文件繼續接下來的實驗:

      $?wget?https://labfile.oss.aliyuncs.com/courses/599/rent.csv

      3. 設計頁面

      頁面大框架可直接從示例中心復制:高德 JavaScript API 示例中心

      這里先給出全部的設計代碼,新建index.html復制粘貼下面的代碼:

      ???? ???? ???? ????畢業生租房 ???? ???? ???? ????????????

      ????????
      ???????? ???????????? ???????????? ?????????????????公交+地鐵??????????? ??????????????????????地鐵????????????
      ????????
      ???????? ???????????? ???????????? ???????????????? ????????????
      ????????
      ???? ???? ????

      講解一下部分代碼:

      這一句中你會看到key這個參數,它需要你注冊高德的開發者用戶,創建應用才能得到,由于 JS API 不像它家的 Web API 一樣有流量限制,所以這個key大可隨意使用。

      房源: ????????????

      添加標尺,參考帶功能控件的地圖。

      var?scale?=?new?AMap.Scale();map.addControl(scale);

      一些需要放到全局的變量:

      //公交到達圈對象var?arrivalRange?=?new?AMap.ArrivalRange(); //經度,緯度,時間(用不到),通勤方式(默認是地鐵+公交)var?x,?y,?t,?vehicle?=?"SUBWAY,BUS"; //工作地點,工作標記var?workAddress,?workMarker;//房源標記隊列var?rentMarkerArray?=?[]; //多邊形隊列,存儲公交到達的計算結果var?polygonArray?=?[];//路徑規劃var?amapTransfer;

      信息窗體的使用,在房源標記被點擊時彈出,參考給多個點添加信息窗體。

      //信息窗體對象var?infoWindow?=?new?AMap.InfoWindow({????offset:?new?AMap.Pixel(0,?-30) });//在房源標記被點擊時打開rentMarker.on('click',?function(e)?{????//鼠標移到標記上會顯示標記content屬性的內容 ????infoWindow.setContent(e.target.content);????//在標記的位置打開窗體 ????infoWindow.open(map,?e.target.getPosition()); });

      地址補完的使用,參考輸入提示后查詢。

      var?auto?=?new?AMap.Autocomplete({????//通過id指定輸入元素 ????input:?"work-location"}); ????//添加事件監聽,在選擇補完的地址后調用workLocationSelectedAMap.event.addListener ????(auto,?"select",?workLocationSelected);function?workLocationSelected(e)?{???? ????//更新工作地點,加載公交到達圈 ????workAddress?=?e.poi.name; ????loadWorkLocation(); }

      loadWorkLocation的實現,這部分包含了地理編碼的內容,參考正向地理編碼(地址-坐標)。

      function?loadWorkLocation()?{????//首先清空地圖上已有的到達圈 ????delWorkLocation();???? ????var?geocoder?=?new?AMap.Geocoder({????????city:?"北京",????????radius:?1000 ????}); ????geocoder.getLocation(workAddress,?function(status,?result)? ????{????????if?(status?===?"complete"?&&?result.info?===?'OK')?{????????? ???????var?geocode?=?result.geocodes[0]; ????????????x?=?geocode.location.getLng(); ????????????y?=?geocode.location.getLat();????????????//加載工作地點標記 ????????????loadWorkMarker(x,?y);????????????//加載60分鐘內工作地點到達圈 ????????????loadWorkRange(x,?y,?60,?"#3f67a5",?vehicle);????????????//地圖移動到工作地點的位置 ????????????map.setZoomAndCenter(12,?[x,?y]); ????????} ????}) }

      loadWorkRange的實現,在地圖上繪制到達圈,參考:公交到達圈。

      function?loadWorkRange(x,?y,?t,?color,?v)?{ ????arrivalRange.search([x,?y],?t,?function(status,?result)?{?????? ??????if?(result.bounds)?{?????????? ????????for?(var?i?=?0;?i?

      載入房源信息功能的實現。由于安全問題,瀏覽器想要得到文件在系統內的位置就得用上一些奇技淫巧,這里還是算了,偷一下懶,因為房源文件跟index.html在同一個文件夾下,所以我們只要得到文件名就足夠了。

      function?importRentInfo(fileInfo)?{???? var?file?=?fileInfo.files[0].name; ????loadRentLocationByFile(file); }

      我們使用一個集合來記錄所有的房源地址。

      function?loadRentLocationByFile(fileName)?{????//先刪除現有的房源標記 ????delRentLocation();????//所有的地點都記錄在集合中 ????var?rent_locations?=?new?Set();????//jquery操作 ????$.get(fileName,?function(data)?{ ????????data?=?data.split("\n"); ????????data.forEach(function(item,?index)?{ ????????????rent_locations.add(item.split(",")[1]); ????????}); ????????rent_locations.forEach(function(element,?index)?{???????? ????????????//加上房源標記 ????????????addMarkerByAddress(element); ????????}); ????}); }

      addMarkerByAddress的實現參考:按起終點名稱規劃路線與點標記。

      注意其中這一句會被顯示在信息窗體上。鏈接指向58品牌公寓館的搜索頁面,搜索的地址就是點標記(房源)的地址

      rentMarker.content?=?"

      房源:

      5. 效果演示

      可直接下載最終代碼使用:

      $?wget?http://labfile.oss.aliyuncs.com/courses/599/index.html

      輸入python -m SimpleHTTPServer 3000打開服務器,瀏覽器訪問localhost:3000查看效果:

      首先選擇工作地點:

      劃出了一小時內的通勤范圍:

      北京堵車太猖狂,可能還是地鐵保險:

      導入房源文件:

      導入后:

      選擇一處房源,會自動幫你規劃路徑:

      選中房源地址跳轉到目標頁面:

      五、總結

      多多利用網上的各種開放平臺與API能讓你的編程事半功倍,甚至這可能改變一個人的生活,影響到一個人的一生也說不定。這種說法聽起來似乎太夸張,但是就拿高考報志愿舉例吧,選什么學校,什么專業,可能就是一個決策導致了人生的截然不同。信息不對等或是缺乏對信息的分析都是很吃虧的。互聯網時代,信息唾手可得,但是呢,我花大把時間看到的都不是我想要的,即使在看個人房源還是得自己排除一堆中介。我不是常常出門所以對交通不熟,把這些信息都查一遍又得花大量的時間。還好現在有了各種好的平臺與開放接口,只需要你有一點點編程技能和一個想要實現什么東西的想法,一切就都不一樣了。

      這個項目有很多可以改進的部分,比如房源信息的選取過于簡單,房間的面積也應該納入考慮。比如可以做成在地圖上顯示具體的房源信息,每個標記都只標記唯一的房源。比如房源信息為什么要存文件呢,也可以存數據庫里。比如爬取房源的效率太低,可以改用scrapy或者以自己的方式進行優化。比如只爬取一個網站會不會房源太少,也可以多找幾處,把豆瓣的租房貼,各個大學的論壇也算進去,也許能真正解決租房難的問題呢。

      六、參考資料

      高德 JavaScript API 幫助文檔

      高德 JavaScript API 示例中心

      Requests: HTTP for Humans

      Beautiful Soup 4.2.0 文檔

      csv — CSV 文件的讀寫

      本項目的完整代碼及demo,可在實驗樓查看并在線完成,立即【開始實驗】

      更多Python經典項目:Python全部 - 課程

      本文轉載自異步社區。

      API Python

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:連續兩年入選Gartner?云數據庫管理系統魔力象限?
      下一篇:一對一語音聊天系統源碼APP獨特的優勢
      相關文章
      亚洲精品乱码久久久久66| 亚洲av高清在线观看一区二区| 亚洲国产精品无码久久青草| 亚洲精品中文字幕无码A片老| 亚洲人6666成人观看| 亚洲综合一区二区| 337p日本欧洲亚洲大胆精品555588| 亚洲AV福利天堂一区二区三| 久久亚洲免费视频| 亚洲国产天堂久久综合网站| 久久91亚洲精品中文字幕| 亚洲AV无码日韩AV无码导航| 亚洲国产精品VA在线看黑人| 久久亚洲成a人片| 亚洲ⅴ国产v天堂a无码二区| 99久久精品国产亚洲| 亚洲精品福利视频| 亚洲色欲或者高潮影院| 亚洲人成电影青青在线播放| 亚洲va久久久久| 亚洲另类无码专区首页| 亚洲av片在线观看| 亚洲国产精品嫩草影院久久| 国产亚洲成人在线播放va| 亚洲欧洲无码AV电影在线观看 | 亚洲中文字幕无码一区| 亚洲日韩小电影在线观看| 日韩亚洲人成在线综合日本| 久久久久久亚洲AV无码专区| 亚洲欧洲日产专区| 亚洲成年网站在线观看| 亚洲AV香蕉一区区二区三区| 免费观看亚洲人成网站| 老司机亚洲精品影视www| 亚洲国产精品高清久久久| 亚洲视频手机在线| 最新亚洲卡一卡二卡三新区| 午夜在线亚洲男人午在线| 亚洲精品无码永久中文字幕| 亚洲视频精品在线| 亚洲va精品中文字幕|