實現爬蟲、數據分析及可視化


1、 實現爬蟲

步驟

  1. 數據所在的url

  2. 發送網絡請求

  3. 數據的解析(我們需要的數據)

  4. 數據的保存

下面分步進行詳細的實現

(完整代碼放在最后)

1.1、數據所在的url

爬取的網站:https://gl.lianjia.com/zufang/

  • 分析需要爬取的數據是否是靜態數據,查看網頁源碼

    # URL地址
    url = 'https://gl.lianjia.com/zufang/'

    發現我們需要爬取的數據(地區、戶型、面積等)是靜態的

    image-20211030112057112

    image-20211030112109944

     

  • 構建一個請求頭,進行偽裝,偽裝成一個瀏覽器用戶。

    因為要是不寫的話,訪問某些網站的時候會被認出來爬蟲,顯示錯誤,錯誤代碼。

    # 請求頭,鍵值對形式
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30'}

    獲得請求頭的方式:

    在URL下按下F12,打開開發者工具,來到網絡(network),可以看到該頁面的所有的網絡請求,我們隨意點擊一個,找到標頭下的User-Agent,它的內容就是我們需要的,其他的那些是瀏覽器自帶的、可以不管。

    image-20211030112857062

     

1.2、發送網絡請求

  • 導入發送網絡請求的模塊,使用其來發送請求

    import requests

    下載該模塊的依賴,在控制台中輸入pip install requests

    image-20211030123902008

  • 實現發送請求,帶上請求頭。使用response接收返回值

    # 發送網絡請求
    response = requests.get(url=url, headers=headers)

    # print(response) # 響應碼為200代表成功
    # html_data = response.text # 這是網頁源碼
    # print(html_data)   # 可以打印到控制台看看是否和網頁源碼一致

至此,response是我們拿到的網頁的所有數據。下面就是對其進行解析,獲得我們需要的數據

 

1.3、數據的解析

  • 導入數據解析模塊(步驟和上面一樣)

    import parsel

    pip install parsel

 

轉換數據類型

將其轉為一個對象,才可以用於解析

selector = parsel.Selector(html_data)

這里使用xpath解析,進行數據的采集

分析我們需要采集的數據(地區、小區、戶型、面積、價格、朝向、出租方式等)

image-20211030132312231

 

使用以下方法需要對html 、css有一定的了解。也可以直接搬過去使用

# 將其轉為一個對象
selector = parsel.Selector(html_data)

lis = selector.xpath('//div[@class="content__list"]/div')   # 定位到每一條信息的標簽
for li in lis:
   detail_hire = li.xpath('.//div/p/a/text()').get()  # 出租方式
   detail_hire = detail_hire.strip()[0:2]  # 去除前后空格,截取出租方式

   detail_url = 'https://gl.lianjia.com' + li.xpath('.//a/@href').get()  # 租房詳情地址,需要拼接
   detail_area = li.xpath('.//div/p[2]/text()[5]').get().strip()    # 出租面積
   detail_direction = li.xpath('.//div/p[2]/text()[6]').get().strip()  # 朝向
   detail_type = li.xpath('.//div/p[2]/text()[7]').get().strip()  # 戶型
   detail_region = li.xpath('.//div/p[2]/a[2]/text()').get()  # 地區
   detail_village = li.xpath('.//div/p[2]/a[3]/text()').get()  # 小區
   detail_rent = li.xpath('.//div/span/em/text()').get()  # 租金

   # 運行,看是否能打印出結果
   print(detail_hire, detail_region, detail_village, detail_area,
         detail_direction, detail_type, detail_rent, detail_url, sep=' | ')

 

1.4、數據的保存

# 數據的保存,第一個參數:保存的文件名 ; a:追加寫,   
with open('租房網(桂林)數據.csv', mode='a', encoding='UTF-8', newline='') as f:
   csv_write = csv.writer(f)
   csv_write.writerow([detail_hire, detail_region, detail_village, detail_area, detail_direction, detail_type, detail_rent, detail_url])

 

到這里,完成了一個頁面的采集,那如何完成這100 多頁的采集?

image-20211030154154799

 

點擊翻頁,找規律,發現url是有規律的。

那么我們將頁面的規律構建出來,便可以實現循環查詢了

image-20211030154112617

 

那我們只需要在最外層加循環,改變url的路徑即可。

因為是只有100頁,所以范圍設置為101

image-20211030162009499

image-20211030162032471

image-20211030162201582

 

會出現亂碼,百度搜索如何解決csv亂碼問題

處理一下文檔,因為沒有添加標題欄,可以打開爬取好的文件手動加上。方便后面進行數據處理,你也可以嘗試使在代碼中添加

出租方式,地區,小區,出租面積,朝向,戶型,租金,租房詳情地址

image-20211031182114424

 

完整代碼

爬取一頁數據的完整代碼

import csv
import requests
import parsel

# URL地址
url = 'https://gl.lianjia.com/zufang/pg1'
# 請求頭,鍵值對形式
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30'}

# 發送網絡請求
response = requests.get(url=url, headers=headers)
# print(response) # 響應碼為200代表成功

html_data = response.text # 這是網頁源碼
# print(html_data) # 可以打印到控制台看看是否和網頁源碼一致

# 將其轉為一個對象
selector = parsel.Selector(html_data)

lis = selector.xpath('//div[@class="content__list"]/div') # 定位到每一條信息的標簽
for li in lis:
detail_hire = li.xpath('.//div/p/a/text()').get() # 出租方式
detail_hire = detail_hire.strip()[0:2] # 去除前后空格,截取出租方式

detail_url = 'https://gl.lianjia.com' + li.xpath('.//a/@href').get() # 租房詳情地址,需要加上前綴
detail_area = li.xpath('.//div/p[2]/text()[5]').get().strip() # 出租面積
detail_direction = li.xpath('.//div/p[2]/text()[6]').get().strip() # 朝向
detail_type = li.xpath('.//div/p[2]/text()[7]').get().strip() # 戶型
detail_region = li.xpath('.//div/p[2]/a[2]/text()').get() # 地區
detail_village = li.xpath('.//div/p[2]/a[3]/text()').get() # 小區
detail_rent = li.xpath('.//div/span/em/text()').get()# 租金

print(detail_hire, detail_region, detail_village, detail_area,
detail_direction, detail_type, detail_rent, detail_url, sep=' | ')

# 數據的保存,a追加寫
with open('租房網(桂林)數據.csv', mode='a', encoding='UTF-8', newline='') as f:
csv_write = csv.writer(f)
csv_write.writerow([detail_hire, detail_region, detail_village, detail_area, detail_direction, detail_type, detail_rent, detail_url])

 

爬取該站點的全部(區別只是多了一層循環)

import csv
import requests
import parsel

for page in range(1, 101):
# URL地址
print(f'\n=================正在爬取第{page}頁的數據=======================')
url = f'https://gl.lianjia.com/zufang/pg{page}'
# 請求頭,鍵值對形式
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30'}

# 發送網絡請求
response = requests.get(url=url, headers=headers)
# print(response) # 響應碼為200代表成功

html_data = response.text # 這是網頁源碼
# print(html_data) # 可以打印到控制台看看是否和網頁源碼一致

# 將其轉為一個對象
selector = parsel.Selector(html_data)

lis = selector.xpath('//div[@class="content__list"]/div') # 定位到每一條信息的標簽
for li in lis:
detail_hire = li.xpath('.//div/p/a/text()').get() # 出租方式
detail_hire = detail_hire.strip()[0:2] # 去除前后空格,截取出租方式

detail_url = 'https://gl.lianjia.com' + li.xpath('.//a/@href').get() # 租房詳情地址,需要加上前綴
detail_area = li.xpath('.//div/p[2]/text()[5]').get().strip() # 出租面積
detail_direction = li.xpath('.//div/p[2]/text()[6]').get().strip() # 朝向
detail_type = li.xpath('.//div/p[2]/text()[7]').get().strip() # 戶型
detail_region = li.xpath('.//div/p[2]/a[2]/text()').get() # 地區
detail_village = li.xpath('.//div/p[2]/a[3]/text()').get() # 小區
detail_rent = li.xpath('.//div/span/em/text()').get() # 租金

# print(detail_hire, detail_region, detail_village, detail_area, detail_direction, detail_type, detail_rent, detail_url, sep=' | ')

# 數據的保存,a追加寫
with open('租房網(桂林)數據all.csv', mode='a', encoding='UTF-8', newline='') as f:
csv_write = csv.writer(f)
csv_write.writerow([detail_hire, detail_region, detail_village, detail_area, detail_direction, detail_type, detail_rent, detail_url])

 

2、數據分析及可視化

步驟

探索性數據分析流程:

  1. 安裝數據分析及可視化的工具

  2. 獲取原始數據(即爬蟲爬到的代碼,可以是excel或者數據庫)

  3. 數據處理

  4. 數據可視化

  5. 分析、得出結論

 

2.1、Jupyter Notebook工具安裝

這里使用工具Jupyter Notebook對數據進行可視化分析

Jupyter Notebook的安裝(結合該教程:https://www.jianshu.com/p/91365f343585

補充幾點:

我是使用pip命令安裝

在使用安裝命令的時候需要管理員權限,所以我們按下win+x,選擇管理員的控制台

image-20211031133704563

然后再執行把pip升級到最新版本

  • Python 3.x

pip3 install --upgrade pip
  • Python 2.x

pip install --upgrade pip
  • 注意:老版本的pip在安裝Jupyter Notebook過程中或面臨依賴項無法同步安裝的問題。因此強烈建議先把pip升級到最新版本。

同樣的也是在這里執行Jupyter Notebook的安裝命令,加上 -i 表示使用鏡像, 后面接着鏡像地址,我這里是阿里雲的,如果不使用鏡像下載,下載會很慢。上面的命令也可以使用鏡像

pip install jupyter      
pip install jupyter -i https://mirrors.aliyun.com/pypi/simple (推薦使用鏡像)

image-20211031134052163

然后等執行完畢,再pycharm的控制台或者管理員控制台中輸入

jupyter notebook

就能自動打開jupyter notebook了,如圖,安裝成功

image-20211031134309090

新建一個操作窗口

image-20211031165535029

導入工具,在新窗口的命令行中執行,先下載依賴,在控制台中執行

pip install pandas -i https://mirrors.aliyun.com/pypi/simple

pip install pyecharts -i https://mirrors.aliyun.com/pypi/simple
import pandas as pd			
from pyecharts.charts import *

 

到這里,完成了數據分析的前期准備

 

2.2、導入原始數據

df = pd.read_csv(r'D:\learningappDataSave\python\homework\com\yong\pc\租房網(桂林)數據all.csv',engine='python')
df.head() # 查看前五條
# df # 查看全部

image-20211031182321492

2.3、數據處理

1、查看數據類型

df.dtypes

數據類型是因為我們在爬取的時候加上了單位,所以都是object(字符串)類型。如果不加,那有可能是其他類型,比如int

2、查看表格丟失數據

df.isnull()

image-20211031182522279

對應的數據丟失為true,否則為false

 

但這樣並不直觀,對他進行一個求和統計,能更清楚的看到缺失情況

3、刪除重復值

df.drop_duplicates(inplace=True)

輸出結果為空,說明無重復值

 

2.4、數據可視化

要求:計算桂林各個地區的不同戶型的:

  • 平均價格

  • 最低價格

  • 最高價格

並進行可視化

  • 不同戶型價格前25%中不同地區的占比並進行可視化。

  • 結合桂林實際情況和獲取的數據,分析不同地區租金最高的小區。

思路:

  1. 統計出桂林的地區數量

  2. 在每個地區統計出該地區的不同戶型的三種價格

 

1、總體分析(多做的一部分,滿足要求的在戶型分析)

統計每個區的房源數量(第一條表示七星區有555套房源)

df.groupby('地區').count()

image-20211031185516675

結果分析:

臨桂區的房源數量是最多的,靈川是最少的。

而且最多地區的房源數量是最少的8倍多。

可推測地區人口分布的情況

  • 統計每個地區的平均租金價格

df_means = df.groupby('地區')['租金'].mean()
df_means

image-20211031183056560

可視化:

獲取x軸:df_means.index.tolist()

image-20211031184046591

y軸同理

畫出x、y軸。y軸可添加多個

bar = (
Bar()
.add_xaxis(df_means.index.tolist())
.add_yaxis('平均值',df_means.values.astype('int64').tolist())
.add_yaxis('房源數量',df_counts['租金'].values.tolist())
)
bar.render_notebook()

image-20211031185437116

結果分析:

秀峰區的房源數量不多,但是平均租金最高。

臨桂區的房源數量少,租金反而是最低的。

可以推測消費水平

  • 最低價格最高價格

bar = (
Bar()
.add_xaxis(df_means.index.tolist())
.add_yaxis('租金最大值',df.groupby('地區')['租金'].max().values.astype('int64').tolist())
.add_yaxis('租金最小值',df.groupby('地區')['租金'].min().values.astype('int64').tolist())
)
bar.render_notebook()

image-20211031214156429

結果分析:

房源的最高價和最低價相差最大的是七星區

七星區房源的最高價是幾個區中最高的

靈川房源的最低價是幾個區中最低的

秀峰區房源的最低價是幾個區中最高的

推測秀峰區最低住房消費水平是幾個區中最高的,靈川是最低的,七星區住房消費水平都有,要高有高,要低有低。

 

2、戶型分析

  • 計算桂林各個地區的不同戶型的平均價格、最低價格和最高價格並進行可視化

  • 不同戶型價格前25%中不同地區的占比並進行可視化。

思路:

  1. 統計出桂林的地區數量

  2. 在每個地區統計出該地區的不同戶型的三種價格

 

統計出不同地區的不同戶型

df.groupby(['地區','戶型']).count()

image-20211031220341999

 

因為這里有146個數據,說明x軸會有146.如果將平均值、最大值、最小值放在一張圖中會看不清楚。

image-20211031221832557

將其拆開了。。。

 

不同地區、不同戶型的平均值

bar = (
Bar()
.add_xaxis(df.groupby(['地區','戶型']).count().index.tolist())
.add_yaxis('租金平均值',df.groupby(['地區','戶型'])['租金'].mean().values.astype('int64').tolist())
)
bar.render_notebook()

image-20211031222013997

 

最大值

image-20211031222640004

最小值

image-20211031222705560

 

不同戶型價格前25%中不同地區的占比並進行可視化。

 

 

分析不同地區租金最高的小區

根據地區分組,求出每個地區租金最高的小區(小區可能包含多個房源)

 

每個地區租金最低的小區

df.groupby('地區')['小區','租金'].max()

 

image-20211101110153009

 

大概知道每個區的哪一片區域的消費水平比較高

每個地區租金最低的小區

image-20211101110101401

 

大概知道每個區的哪一片區域的消費水平比較高

2.5、分析得出結論

結果分析:

臨桂區的房源數量是最多的,靈川是最少的。

而且最多地區的房源數量是最少的8倍多。

可推測地區人口分布的情況

 

結果分析:

秀峰區的房源數量不多,但是平均租金最高。

臨桂區的房源數量少,租金反而是最低的。

可以推測消費水平

 

結果分析:

房源的最高價和最低價相差最大的是七星區

七星區房源的最高價是幾個區中最高的

靈川房源的最低價是幾個區中最低的

秀峰區房源的最低價是幾個區中最高的

推測秀峰區最低住房消費水平是幾個區中最高的,靈川是最低的,七星區住房消費水平都有,要高有高,要低有低。

 

可以根據小區的租房金額來推測該區域的消費水平

 

 

參考資料

爬取數據:https://www.bilibili.com/video/BV13N411o7GQ?from=search&seid=11800879190972678496&spm_id_from=333.337.0.0

數據分析及可視化:https://www.bilibili.com/video/BV1xP4y1x7wp?spm_id_from=333.999.0.0

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM