欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Python爬取分析全國12個(gè)城市4萬(wàn)條房?jì)r(jià)信息,告訴你該怎樣買(mǎi)房?

打開(kāi)幸福里,查看更多圖片

作者 | 月小水長(cháng)

責編 | 伍杏玲

通過(guò)分頁(yè)、線(xiàn)程池、代理池等技術(shù),快速爬取鏈家網(wǎng)近4萬(wàn)條在售二手房信息,速度可達 10000 條 / 5 分鐘。

通過(guò)對二手房作數據分析,得到北上廣深等(新)一線(xiàn)城市四地房?jì)r(jià)的縱向比較,同時(shí)對各個(gè)城市各個(gè)區的房?jì)r(jià)做橫向對比,并將對比結果可視化出來(lái)。

主要用到的庫或模塊包括 Requests、PyQuery、ThreadPoolExecutor、JSON、Matplotlib、PyEcharts。

環(huán)境:Widnows10、Python3.5、Pycharm2018。

數據抓取

爬蟲(chóng)架構設計

通過(guò)分析鏈家網(wǎng)的 URL ,不難發(fā)現,每一個(gè)城市的鏈家網(wǎng)的基本格式是:

城市名簡(jiǎn)拼 ”.lianjia.com“

所以整個(gè)爬蟲(chóng)最外層應該是遍歷一個(gè)保存城市簡(jiǎn)拼的列表,拼接得到一個(gè)個(gè)起始 URL,根據這些 URL 爬取對應城市的鏈家網(wǎng)。

針對每一個(gè)城市的鏈家網(wǎng)而言,首先得到該城市在售二手房的總套數,由于每一頁(yè)顯示的套數是 30,由總套數整除以30再加上1可以得到總頁(yè)數,但是由于最大可瀏覽頁(yè)數為 100,所以我們這里得加個(gè)判斷,如果總頁(yè)數大于 100 的話(huà),令總頁(yè)數等于 100。

分析具體城市的鏈家網(wǎng)每一頁(yè)的 URL, 以北京為例,我們可以發(fā)現第 N 頁(yè)的 URL 是:

bj.lianjia.com/ershoufang/pg{N},由此我們可以通過(guò)以下代碼來(lái)得到每一頁(yè)的 URL:

for i in range(total_page): page_url = 'bj.lianjia.com/ershoufang/pg{}'.format(i 1)

本來(lái)得到每一頁(yè)的 URL 后,我們可以得到該頁(yè)上 30 套房的房?jì)r(jià)信息和詳情頁(yè) URL,但是頁(yè)面上沒(méi)有房子所在區的信息。

我們只能再向下請求訪(fǎng)問(wèn)詳情頁(yè) URL,從而提取出我們想要的所有數據。

綜上所述,我們可以將整個(gè)框架從上往下分為四層,如下圖所示:

基于上述思路,在寫(xiě)代碼的時(shí)候,可以分層從上往下實(shí)現,方便調試。

第一層 & 第二層:獲取總套數

根據城市簡(jiǎn)拼得到起始 URL,并得到總套數,為分頁(yè)做準備。

def get_list_page_url(city): start_url = 'https://{}.lianjia.com/ershoufang'.format(city) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } try: response = requests.get(start_url, headers=headers) # print(response.status_code, response.text) doc = pq(response.text) total_num = int(doc('.resultDes .total span').text()) total_page = total_num // 30   1 # 只能訪(fǎng)問(wèn)到前一百頁(yè) if total_page > 100: total_page = 100 page_url_list = list() for i in range(total_page): url = start_url   '/pg'   str(i   1)   '/' page_url_list.append(url) #print(url) return page_url_list except: print('獲取總套數出錯,請確認起始URL是否正確') return None

第三層:根據起始 URL 得到分頁(yè) URL

def get_detail_page_url(page_url): global detail_list headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', 'Referer': 'https://bj.lianjia.com/ershoufang' } try: response = requests.get(page_url,headers=headers,timeout=3) doc = pq(response.text) i = 0 detail_urls = list() for item in doc('.sellListContent li').items(): i = 1 print(i) if i == 31: break child_item = item('.noresultRecommend') if child_item == None: i -= 1 detail_url = child_item.attr('href') detail_urls.append(detail_url) return detail_urls except: print('獲取列表頁(yè)' page_url '出錯')

第四層

本層做的是具體解析,解析使用的是 PyQuery 庫,支持 CSS 選擇器且比 Beautiful Soup 方便。僅僅需要下面幾行代碼就幫助我們獲得了目標數據:

response = requests.get(url=detail_url, headers=headers, proxies=proxies)#detail_url 是得到的詳情頁(yè) URLdetail_dict = dict()doc = pq(response.text)unit_price = doc('.unitPriceValue').text()unit_price = unit_price[0:unit_price.index('元')]title = doc('h1').text()area = doc('.areaName .info a').eq(0).text().strip()url = detail_url

多線(xiàn)程爬取

由于待爬取的數據量巨大,使用單線(xiàn)程速度太慢,最開(kāi)始采用了第三方庫 ThreadPool 來(lái)實(shí)現多線(xiàn)程,后來(lái)了解到 Python3.5 的內置包 concurrent.futures,使用里面的 ThreadPoolExecutor 來(lái)實(shí)現多線(xiàn)程,速度又提升了 20% 以上。

p = ThreadPoolExecutor(30)for page_url in page_url_list: p.submit(get_detail_page_url, page_url).add_done_callback(detail_page_parser)p.shutdown()

第 1 行通過(guò)構造函數新建了線(xiàn)程池對象,最大可并發(fā)線(xiàn)程數指定為 30,如不指定,其默認值是 CPU 數的 5 倍,第 2、3 行依次把爬取的任務(wù)提交到線(xiàn)程池中,并設置回調函數,這里的回調函數拿到的是一包含 get_detail_page_url 返回值的對象。

并把這個(gè)對象作為回調函數的參數 res,先把返回的res得到一個(gè)結果,即在前面加上一個(gè)res.result(),這個(gè)結果就是 get_detail_page_url 的返回值。

IP 代理池

由于爬取的數量大,同時(shí)由于多線(xiàn)程提高了速度,鏈家網(wǎng)會(huì )拒絕訪(fǎng)問(wèn),這時(shí)可通過(guò)代理 IP 來(lái)訪(fǎng)問(wèn),這里使用已經(jīng)有的輪子,源碼鏈接附在文末。

下載后新開(kāi)一個(gè) Pycharm 視窗運行該項目,然后我們可以用下面的方式來(lái)獲取可用的代理 IP:

def get_valid_ip(): url = 'http://localhost:5000/get' try: ip = requests.get(url).text return ip except: print('請先運行代理池')

然后通過(guò)參數設置使用代理 IP:

proxies = { 'http': 'http://' get_valid_ip(),}response = requests.get(url=detail_url, headers=headers, proxies=proxies)

數據保存

采用 JSON文件形式保存數據,每個(gè)城市保存一個(gè) JSON 文件,文件名為該城市簡(jiǎn)拼。

def save_data(data,filename): with open(filename '.json', 'w', encoding='utf-8') as f: f.write(json.dumps(data, indent=2, ensure_ascii=False))

稍等一會(huì )兒,所有數據就保存在本地了:

本爬蟲(chóng)所爬數據僅為本人測試,嚴禁商用。

數據分析

數據整合

在這里做一些求同地區房?jì)r(jià)最大值、最小值、平均值,以及數據格式統一化的工作:

def split_data(): global region_data region_data = dict() for region in dic_data.keys(): # 最大值、最小值、平均值 region_data[region] = {'max':dic_data[region][0],'min':dic_data[region][0],'average':0} for per_price in dic_data[region]: if per_price > region_data[region]['max']: region_data[region]['max'] = per_price if per_price < region_data[region]['min']: region_data[region]['min'] = per_price region_data[region]['average'] = per_price region_data[region]['average'] /= len(dic_data[region]) # 保留兩位小數 region_data[region]['average'] = round(region_data[region]['average'],2)

數據可視化

將分析結果通過(guò) Matplotlib 直觀(guān)的體現出來(lái),該部分的代碼如下:

def data_viewer(): label_list = region_data.keys() # 橫坐標刻度顯示值 max = [] min = [] average = [] for label in label_list: max.append(region_data[label].get('max')) min.append(region_data[label].get('min')) average.append(region_data[label].get('average')) x = range(len(max)) ''' 繪制條形圖 left: 長(cháng)條形中點(diǎn)橫坐標 height: 長(cháng)條形高度 width: 長(cháng)條形寬度,默認值0 .8 label: 為后面設置legend準備 ''' rects1 = plt.bar(x=x, height=max, width=0.25, alpha=0.8, color='red', label='最大值') rects2 = plt.bar(x=[i   0.25 for i in x], height=average, width=0.25, color='green', label='平均值') rects3 = plt.bar(x=[i   0.5 for i in x], height=min, width=0.25, color='blue', label='最小值') #plt.ylim(0, 50) # y軸取值范圍 plt.ylabel('房?jì)r(jià)/元') ''' 設置x軸刻度顯示值 參數一:中點(diǎn)坐標 參數二:顯示值 ''' plt.xticks([index   0.2 for index in x], label_list) plt.xlabel('地區') plt.legend() for rect in rects1: height = rect.get_height() plt.text(rect.get_x()   rect.get_width() / 2, height 1, str(height), ha='center', va='bottom') for rect in rects2: height = rect.get_height() plt.text(rect.get_x()   rect.get_width() / 2, height   1, str(height), ha='center', va='bottom') for rect in rects3: height = rect.get_height() plt.text(rect.get_x()   rect.get_width() / 2, height   1, str(height), ha='center', va='bottom') plt.show()

結果如下:

限于篇幅,其他城市的圖就不放了。

再來(lái)看全國主要一線(xiàn)城市二手房房?jì)r(jià)有序條形圖:

可以看出,北京、上海、深圳的房?jì)r(jià)大致在同一水平線(xiàn),而廈門(mén)位于第四,廣州在第六,最后看一下房?jì)r(jià)地域圖:

最后看一下房?jì)r(jià)地域圖這是基于 JavaScript 的可交互動(dòng)態(tài)圖,放截圖挺別扭的,我已經(jīng)把它放在我的網(wǎng)上了,感興趣的可以點(diǎn)擊在線(xiàn)觀(guān)看。

作者簡(jiǎn)介:月小水長(cháng),某 985 計算機學(xué)院在校生,熟悉 C 、Java、Python 等多種語(yǔ)言,有大型軟件項目開(kāi)發(fā)經(jīng)驗,致力于安卓、計算機視覺(jué)、爬蟲(chóng)、數據可視化開(kāi)發(fā),同時(shí)也是業(yè)余的前端愛(ài)好者。微信公眾號:inspurer源碼:https://github.com/Python3Spiders/LianJiaSpider.git動(dòng)態(tài)圖展示:https://inspurer.github.io/fang_price_city.html
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
項目實(shí)戰:爬App數據
python3 爬蟲(chóng) 零基礎快速上手(爬蟲(chóng)示例)
今天來(lái)聊聊求職需要的 Python 技能
【Python爬蟲(chóng)】:使用動(dòng)態(tài)IP代理進(jìn)行反反爬蟲(chóng)
requests查看網(wǎng)頁(yè)源碼
requests.get()參數
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久