首页 > 编程语言 >Python网络爬虫——福州小区信息的抓取和数据分析

Python网络爬虫——福州小区信息的抓取和数据分析

时间:2022-12-23 19:11:31浏览次数:64  
标签:10 plt 余量 Python 爬虫 抓取 df print import

一、选题的背景

为了能够充分了解福州当地小区的房价信息,并能够充分了解小区的位置,为每个人不同的需求,选择不同价位的房源,并通过其成交量进行参考和选择,以及剩余量爬取的信息包括小区名,小区链接,详细地址,交通,价格,物业类型,物业价格,面积,户数,车位数,容积率,绿化率,物业公司,开发商。

二、设计方案

1、主题式爬虫名称:福州小区信息

2、题式网络爬虫爬取内容与数据特征分析

爬取内容:小区名、地理位置、联系人、每平方价格、在售余量。

3、题式网络爬虫设计方案概述

方案概述:利用request进行访问请求

解析网页内容,这里使用BeatifulSoup.text()进行网页解析。

数据存储,利用open()函数创建表格模板、wirtelines()函数进行输出存储。

(1)思路

查看网页结构。查看网页爬取内容的位置。取出数据。遍历数据。数据存储。

(2)技术难点

异常处理。网页内容读取。数据便利。数据批量存储整体系统设计。

三、实现步骤及代码

1.首先明确要爬取的网站,

这边选择爬取的url是:福州小区信息_福州小区大全|排行榜(福州链家) (lianjia.com)

 

 

 

2.查看网站源码(f12)

 

 3.分析结构,寻到信息

明确代码位置

<div class=’title”></div>

<div class="district"></div>

<div class=’agentName’></div>

<div class=’’totalPrice”></div>

<div class="totalSellCount"”></div>

 

 

 

 

 

代码设计

(1)爬虫代码

# 导入相关库

import requests

import json

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import matplotlib

import seaborn as sns

from scipy.optimize import leastsq

from PIL import Image

from mpl_toolkits.mplot3d import Axes3D

from bs4 import BeautifulSoup

 

#需要爬取的网站的url

url = 'https://fz.lianjia.com/xiaoqu/'   

#爬虫伪装

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

#设置超时时间

r = requests.get(url,timeout = 30,headers = headers)

r.encoding = 'utf-8'

html = r.text

#print(html)

# 获取源代码

soup = BeautifulSoup(html, 'lxml')

# 构造Soup的对象

#print(soup.prettify())

 

# 创建列表,需要5条数据,创建5个列表

a = []

b = []

c = []

d = []

e = []

 

for g in soup.find_all(class_="title"):

    # for语句查找标签

    a.append(g.get_text().strip())

for g in soup.find_all(class_="district"):

    # for语句查找标签

    b.append(g.get_text().strip())

for g in soup.find_all(class_="agentName"):

    # for语句查找标签

    c.append(g.get_text().strip())

for g in soup.find_all(class_="totalPrice"):

    d.append(g.get_text().split())

for g in soup.find_all(class_="totalSellCount"):

    e.append(g.get_text().split())

data = [a,b,c,d,e]

print(data)

 

结果如下

 

 

(2)发现有许多杂乱信息(最后5行爬取到不需要的信息,故优化代码)

只爬取前30行,并且直接对数据进行了清洗,删掉了单位等不必要信息

 

 

 

# 导入相关库

 

import requests

 

import json

 

import pandas as pd

 

import numpy as np

 

import matplotlib.pyplot as plt

 

import matplotlib

 

import seaborn as sns

 

from scipy.optimize import leastsq

 

from PIL import Image

 

from mpl_toolkits.mplot3d import Axes3D

 

from bs4 import BeautifulSoup

 

 

 

#需要爬取的网站的url

 

url = 'https://fz.lianjia.com/xiaoqu/'   

 

#爬虫伪装

 

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

 

#设置超时时间

 

r = requests.get(url,timeout = 30,headers = headers)

 

r.encoding = 'utf-8'

 

html = r.text

 

#print(html)

 

# 获取源代码

 

soup = BeautifulSoup(html, 'lxml')

 

# 构造Soup的对象

 

#print(soup.prettify())

 

 

 

# 创建列表,需要5条数据,创建5个列表

 

a = []

 

b = []

 

c = []

 

d = []

 

e = []

 

 

 

for g in soup.find_all(class_="title")[:30]:

 

    # for语句查找标签

 

    a.append(g.get_text().strip())

 

for g in soup.find_all(class_="district"):

 

    # for语句查找标签

 

    b.append(g.get_text().strip())

 

for g in soup.find_all(class_="agentName"):

 

    # for语句查找标签

 

    c.append(g.get_text().strip())

 

for g in soup.find_all(class_="totalPrice"):

 

    d.append(g.get_text().split('元')[0].strip('['))

 

for g in soup.find_all(class_="totalSellCount"):

 

    e.append(g.get_text().split('套')[0])

 

data = [a,b,c,d,e]

 

print(data)

 

 

 

 结果如下

 

 

 

(3)数据收集,导出为文件

import pandas as pd

df = pd.DataFrame(data, index=["小区名","地理位置", "联系人", "每平方价格", "在售余量"])

 

# 使用工具使其可视化

print(df.T)

 

# 将所得数据进行可视化

 

test= "福州小区信息.xlsx"

# 将数据保存在新的文本中

 

df.T.to_excel(test)

df = pd.DataFrame(pd.read_excel('福州小区信息.xlsx'))

 

 

结果如下

 

 

(4)数据分析删除无用数据

 

# 数据清洗

 

print('\n====各列是否有缺失值情况如下:====')

 

print(df.isnull().sum())

 

# 返回0,表示没有空值

 

print(df.duplicated())

 

# 检查是否有重复值

 

print(df.isnull())

 

# 返回无缺失值

 

print(df.isna().head())

 

print(df.describe())

 

# 用describe()命令显示描述性统计指标

 

结果如下

 

 

 

 

(5)绘制直线图

代码如下

 

 

 

import matplotlib.pyplot as plt

 

import matplotlib

 

 

 

# 将默认字体改为中文字体

 

plt.rcParams['font.sans-serif'] = ['SimHei']

 

# 解决负号不正常显示的问题

 

matplotlib.rcParams['axes.unicode_minus'] = False

 

 

 

# 绘制第一张直线图

 

 

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

#x的值

 

x =  df.小区名[:10]

 

#y的值

 

y = df.在售余量[:10]

 

bar_width = 0.3

 

plt.plot(x, y)

 

plt.xlabel("小区名")

 

plt.ylabel("在售余量(套)")

 

plt.title('各小区空闲房源分析')

 

plt.show()

 

 

 

# 绘制第二张直线图

 

 

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

#x的值

 

x = df.小区名[:10]

 

#y的值

 

y = df.每平方价格[:10]

 

plt.plot(x, y)

 

plt.xlabel("小区名")

 

plt.ylabel("每平方价格(元/m)")

 

plt.title('各小区每平方价格分析')

 

plt.show()

结果如下

 

 

 

 

(6)饼图

代码如下

 

 

 

 # 绘制第一张饼图

 

plt.figure(figsize=(7, 7))

 

    # 标签名

 

labels = df.小区名[:10]

 

    # 构造数据

 

data = df.在售余量[:10]

 

 

 

    # 绘制图形

 

plt.pie(data, labels=labels, autopct='%1.1f%%')

 

plt.title('各小区剩余量占比')

 

plt.show()

 

 

 

 # 绘制第二张饼图

 

plt.figure(figsize=(7, 7))

 

    # 标签名

 

labels = df.小区名[:10]

 

    # 构造数据

 

data = df.每平方价格[:10]

 

 

 

    # 绘制图形

 

plt.pie(data, labels=labels, autopct='%1.1f%%')

 

plt.title('各小区房源每平方价格占比')

 

plt.show()

 

结果如下

 

 

 

 

 

(7)画散点图和建立回归方程

代码如下

 

def rc():

 

# 画散点图和建立回归方程

 

    # 设置中文字体

 

    plt.rcParams['font.sans-serif'] = ['SimHei']

 

 

 

    # 嵌套函数

 

    # 需要拟合的函数func,指定函数的形状

 

    def func1(p, x):

 

        a, b, c = p

 

        return a * x * x + b * x + c

 

 

 

    # 偏差函数

 

    def error1(p, x, y):

 

        return func1(p, x) - y

 

 

 

    # 画样本图像

 

    plt.scatter(df.每平方价格[:10], df.在售余量[:10])

 

 

 

    # 设置样本数据

 

    X = df.每平方价格[:10] / 10000

 

    Y = df.在售余量[:10] / 10000

 

    plt.figure(figsize=(8, 6))

 

 

 

    # 设置函数拟合参数

 

    p0 = [1, 15, 20]

 

 

 

    # 进行最小二乘拟合

 

    para = leastsq(error1, p0, args=(X, Y))

 

    a, b, c = para[0]

 

 

 

    # 读取结果

 

    print('a=', a, 'b=', b, 'c=', c)

 

    print("求解的拟合直线为:")

 

    print("y=" + str(round(a, 2)) + "x*x" + str(round(b, 2)) + "x+" + str(round(c, 2)))

 

 

 

    # 画拟合曲线

 

    plt.scatter(X, Y, color='green', label='样本数据', linewidth=2)

 

    x = np.linspace(1, 15, 20)

 

    y = a * x * x + b * x + c

 

    plt.plot(x, y, color='red', label='拟合曲线', linewidth=2)

 

    plt.legend()

 

    plt.title('')

 

    plt.grid()

 

    plt.show()

 

 

 

rc()

 

结果如下

 

 

 

 

 

(8)绘制垂直柱状图

代码如下:

 

 import seaborn as sns

 

 

 

# 将默认字体改为中文字体

 

plt.rcParams['font.sans-serif'] = ['SimHei']

 

# 解决负号不正常显示的问题

 

matplotlib.rcParams['axes.unicode_minus'] = False

 

 

 

# 绘制第一张垂直柱状图

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

sns.regplot(df.在售余量, df.在售余量)

 

 

 

plt.rcParams['axes.unicode_minus'] = False

 

# 用来正常显示负号

 

 

 

plt.bar(df.在售余量, df.在售余量, label="余量与每平方米价格柱状图1")

 

 

 

plt.show()

 

 

 

# 绘制第二张垂直柱状图

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

sns.regplot(df.在售余量, df.每平方价格)

 

 

 

plt.rcParams['axes.unicode_minus'] = False

 

# 用来正常显示负号

 

 

 

plt.bar(df.在售余量, df.每平方价格, label="余量与每平方米价格柱状图2")

 

 

 

plt.show()

 

 

 

 结果如下

 

 

 

三、实现步骤及代码

 

# 导入相关库

 

import requests

 

import json

 

import pandas as pd

 

import numpy as np

 

import matplotlib.pyplot as plt

 

import matplotlib

 

import seaborn as sns

 

from scipy.optimize import leastsq

 

from PIL import Image

 

from mpl_toolkits.mplot3d import Axes3D

 

from bs4 import BeautifulSoup

 

 

 

#需要爬取的网站的url

 

url = 'https://fz.lianjia.com/xiaoqu/'   

 

#爬虫伪装

 

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

 

#设置超时时间

 

r = requests.get(url,timeout = 30,headers = headers)

 

r.encoding = 'utf-8'

 

html = r.text

 

#print(html)

 

# 获取源代码

 

soup = BeautifulSoup(html, 'lxml')

 

# 构造Soup的对象

 

#print(soup.prettify())

 

 

 

# 创建列表,需要5条数据,创建5个列表

 

a = []

 

b = []

 

c = []

 

d = []

 

e = []

 

 

 

#因为后面发现,30之后是空数据,所以只取前30

 

for g in soup.find_all(class_="title")[:30]:  

 

    # for语句查找标签

 

    a1=g.get_text().strip()

 

    a.append(a1)

 

for g in soup.find_all(class_="district"):

 

    # for语句查找标签

 

    b1=g.get_text().strip()

 

    b.append(b1)

 

for g in soup.find_all(class_="agentName"):

 

    # for语句查找标签

 

    c1=g.get_text().strip()

 

    c.append(c1)

 

for g in soup.find_all(class_="totalPrice"):

 

    #取消掉单位,删除[

 

    d1=g.get_text().split('元')[0].strip('[')

 

    d.append(d1)

 

for g in soup.find_all(class_="totalSellCount"):

 

    #将套删掉

 

    e1=g.get_text().split('套')[0]   

 

    e.append(e1)

 

data = [a,b,c,d,e]

 

print(data)

 

 

 

import pandas as pd

 

df = pd.DataFrame(data, index=["小区名","地理位置", "联系人", "每平方价格", "在售余量"])

 

 

 

# 使用工具使其可视化

 

print(df.T)

 

 

 

# 将所得数据进行可视化

 

 

 

test= "福州小区信息.xlsx"

 

# 将数据保存在新的文本中

 

 

 

df.T.to_excel(test)

 

df = pd.DataFrame(pd.read_excel('福州小区信息.xlsx'))

 

 

 

# 数据清洗

 

print('\n====各列是否有缺失值情况如下:====')

 

print(df.isnull().sum())

 

# 返回0,表示没有空值

 

print(df.duplicated())

 

# 检查是否有重复值

 

print(df.isnull())

 

# 返回无缺失值

 

print(df.isna().head())

 

print(df.describe())

 

# 用describe()命令显示描述性统计指标

 

 

 

 

 

import matplotlib.pyplot as plt

 

import matplotlib

 

 

 

# 将默认字体改为中文字体

 

plt.rcParams['font.sans-serif'] = ['SimHei']

 

# 解决负号不正常显示的问题

 

matplotlib.rcParams['axes.unicode_minus'] = False

 

 

 

# 绘制第一张直线图

 

 

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

#x的值

 

x =  df.小区名[:10]

 

#y的值

 

y = df.在售余量[:10]

 

bar_width = 0.3

 

plt.plot(x, y)

 

plt.xlabel("小区名")

 

plt.ylabel("在售余量(套)")

 

plt.title('各小区空闲房源分析')

 

plt.show()

 

 

 

# 绘制第二张直线图

 

 

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

#x的值

 

x = df.小区名[:10]

 

#y的值

 

y = df.每平方价格[:10]

 

plt.plot(x, y)

 

plt.xlabel("小区名")

 

plt.ylabel("每平方价格(元/m)")

 

plt.title('各小区每平方价格分析')

 

plt.show()

 

 

 

 # 绘制第一张饼图

 

plt.figure(figsize=(7, 7))

 

    # 标签名

 

labels = df.小区名[:10]

 

    # 构造数据

 

data = df.在售余量[:10]

 

 

 

    # 绘制图形

 

plt.pie(data, labels=labels, autopct='%1.1f%%')

 

plt.title('各小区剩余量占比')

 

plt.show()

 

 

 

 # 绘制第二张饼图

 

plt.figure(figsize=(7, 7))

 

    # 标签名

 

labels = df.小区名[:10]

 

    # 构造数据

 

data = df.每平方价格[:10]

 

 

 

    # 绘制图形

 

plt.pie(data, labels=labels, autopct='%1.1f%%')

 

plt.title('各小区房源每平方价格占比')

 

plt.show()

 

 

 

def rc():

 

# 分析两组数据并画散点图和建立回归方程

 

    # 设置中文字体

 

    plt.rcParams['font.sans-serif'] = ['SimHei']

 

 

 

    # 嵌套函数

 

    # 需要拟合的函数func,指定函数的形状

 

    def func1(p, x):

 

        a, b, c = p

 

        return a * x * x + b * x + c

 

 

 

    # 偏差函数

 

    def error1(p, x, y):

 

        return func1(p, x) - y

 

 

 

    # 画样本图像

 

    plt.scatter(df.每平方价格[:10], df.在售余量[:10])

 

 

 

    # 设置样本数据

 

    X = df.每平方价格[:10] / 10000

 

    Y = df.在售余量[:10] / 10000

 

    plt.figure(figsize=(8, 6))

 

 

 

    # 设置函数拟合参数

 

    p0 = [1, 15, 20]

 

 

 

    # 进行最小二乘拟合

 

    para = leastsq(error1, p0, args=(X, Y))

 

    a, b, c = para[0]

 

 

 

    # 读取结果

 

    print('a=', a, 'b=', b, 'c=', c)

 

    print("求解的拟合直线为:")

 

    print("y=" + str(round(a, 2)) + "x*x" + str(round(b, 2)) + "x+" + str(round(c, 2)))

 

 

 

    # 画拟合曲线

 

    plt.scatter(X, Y, color='green', label='样本数据', linewidth=2)

 

    x = np.linspace(1, 15, 20)

 

    y = a * x * x + b * x + c

 

    plt.plot(x, y, color='red', label='拟合曲线', linewidth=2)

 

    plt.legend()

 

    plt.title('')

 

    plt.grid()

 

    plt.show()

 

 

 

rc()

 

 

 

import seaborn as sns

 

 

 

# 将默认字体改为中文字体

 

plt.rcParams['font.sans-serif'] = ['SimHei']

 

# 解决负号不正常显示的问题

 

matplotlib.rcParams['axes.unicode_minus'] = False

 

 

 

# 绘制第一张垂直柱状图

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

sns.regplot(df.在售余量, df.在售余量)

 

 

 

plt.rcParams['axes.unicode_minus'] = False

 

# 用来正常显示负号

 

 

 

plt.bar(df.在售余量, df.在售余量, label="余量与每平方米价格柱状图1")

 

 

 

plt.show()

 

 

 

# 绘制第二张垂直柱状图

 

# 图画比例

 

plt.figure(figsize=(20,10))

 

sns.regplot(df.在售余量, df.每平方价格)

 

 

 

plt.rcParams['axes.unicode_minus'] = False

 

# 用来正常显示负号

 

 

 

plt.bar(df.在售余量, df.每平方价格, label="余量与每平方米价格柱状图2")

 

plt.show()

 

四、总结

 

爬虫这个名词第一次出现在我的印象中是学习中国大学MOOC里面的python语言程序设计慕课,那时候我对爬虫并不了解,也没有学习的兴趣。最近在看一些有关信息安全的书,发现网上的数据对我们来说很重要,于是对爬虫产生了一定的兴趣。本次爬虫达到了我的预期目标,希望我可以一直坚持下去。用爬虫爬取网站,需要听取网站的爬虫协议,有的可以爬,有的不能爬。在网站的域名后面加上robots.txt。如果出现404,可以随心所欲爬取。这就是我觉得我爬虫需要改进的地方。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:10,plt,余量,Python,爬虫,抓取,df,print,import
From: https://www.cnblogs.com/577599-/p/17001348.html

相关文章