运用python爬58二手房数据
- 导入用到的模块 xlwt, xlrd, time, requests,etree
import xlwt, xlrd, time, requests
from lxml import etree
- `创建工作薄,设置保存的数据,
def __init__(self):
self.cj = xlwt.Workbook() # 创建工作薄
self.fzsj = self.cj.add_sheet(u'58房子数据', cell_overwrite_ok=True) # 命名table
self.Title = [u'编号', u'介绍', u'户型', u'面积/平方米', u'朝向', u'楼层', u'地址', u'价格/万', u'平方价格'] # 创建标题
for i in range(0, len(self.Title)):
# 最后一个参数设置样式
self.fzsj.write(0, i, self.Title[i])
# Excel保存位置
self.cj.save('D:/房子信息.xls')
- 爬区网页上的数据
def getUrl(self):
#循环爬取各页上的数据
for i in range(1,11): #爬10页
url = 'https://lishui.58.com/ershoufang/pn{}'.format(i)
self.pashuju_58(url)
# 测试链接
print(url)
# 给循环加延迟(这里加延迟主要是为了防止代理ip失效)
time.sleep(3)
- 判断url是否为空,为空跳出循环
if url is None:
return None
- 写爬取前的准备
# 打开Excel文件
data = xlrd.open_workbook('D:/房子信息.xls')
# 通过索引顺序获取table,因为初始化时只创建了一个table,因此索引值为0
table = data.sheets()[0]
# 获取行数 ,下次从这一行开始
hang = table.nrows
# 使用代理IP
proxies = {'http': 'http://60.179.201.207:3000'}
# 伪装头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'}
# 响应
respon = requests.get(url, headers=headers, proxies=proxies).text
# 打印
# htmlText = respon.text
# 实例化
xp = etree.HTML(respon)
- 运用xpath拿取数据 使用list列表存储数据
li_list = xp.xpath('//ul[@class="house-list-wrap"]/li') # 提取相同的前缀
gs = 0
for li in li_list:
data = []
# 解析
biaoti = li.xpath('./div[2]/h2/a/text()')[0]
# zhuangxiu 4页以前可用,以后的网页代码已经改变
# zhuangxiu = li.xpath('./div[2]/h2/i[1]/i[1]/text()')[0]
huxinhuxin = li.xpath('./div[2]/p[1]/span[1]/text()')[0]
mianji = li.xpath('./div[2]/p[1]/span[2]/text()')[0]
chaoxiang = li.xpath('./div[2]/p[1]/span[3]/text()')[0]
louceng = li.xpath('./div[2]/p[1]/span[4]/text()')[0]
dizhi = li.xpath('./div[2]/p[2]/span/a/text()')[0]
jiage = li.xpath('./div[3]/p/b/text()')[0]
pfjiage = li.xpath('./div[3]/p[2]/text()')[0]
# 拼装成一个列表
data.append(hang + gs) # 为每条书添加序号
data.append(biaoti)
data.append(huxinhuxin)
data.append(mianji.replace('㎡',''))
data.append(chaoxiang)
data.append(louceng)
data.append(dizhi)
data.append(jiage)
data.append(pfjiage.replace("元/㎡",""))
# print("-----------------")
# print(pfjiage.replace("元/㎡",""))
- 记录并保存数据
for i in range(len(data)):
self.fzsj.write(hang + gs, i, data[i])
gs += 1 # 记录行数增量
print(biaoti, huxinhuxin, mianji, chaoxiang, louceng, dizhi, jiage, pfjiage)#查看
self.cj.save('D:/房子信息.xls')
# 给爬数据的循环加延迟
time.sleep(3)
8.运行
if __name__ == "__main__":
dbBook = pashuju()
dbBook.getUrl()
结果展示
8.下面献上全部代码
import xlwt, xlrd, time, requests
from lxml import etree
class pashuju(object):
def __init__(self):
self.cj = xlwt.Workbook() # 创建工作薄
self.fzsj = self.cj.add_sheet(u'58房子数据', cell_overwrite_ok=True) # 命名table
self.Title = [u'编号', u'介绍', u'户型', u'面积/平方米', u'朝向', u'楼层', u'地址', u'价格/万', u'平方价格'] # 创建标题
for i in range(0, len(self.Title)):
# 最后一个参数设置样式
self.fzsj.write(0, i, self.Title[i]) # , self.set_style('Times new Roman', 220, True)
# Excel保存位置
self.cj.save('D:/房子信息.xls')
def getUrl(self):
#循环爬取各页上的数据
for i in range(1,11): #爬10页
url = 'https://lishui.58.com/ershoufang/pn{}'.format(i)
self.pashuju_58(url)
# 测试链接
print(url)
# 给循环加延迟
time.sleep(3)
def pashuju_58(self, url):
if url is None:
return None
# 打开Excel文件
data = xlrd.open_workbook('D:/房子信息.xls')
# 通过索引顺序获取table,因为初始化时只创建了一个table,因此索引值为0
table = data.sheets()[0]
# 获取行数 ,下次从这一行开始
hang = table.nrows
# 使用代理IP
proxies = {'http': 'http://60.179.201.207:3000'}
# 伪装头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'}
# 响应
respon = requests.get(url, headers=headers, proxies=proxies).text
# # 打印
# htmlText = respon.text
# 实例化
xp = etree.HTML(respon)
li_list = xp.xpath('//ul[@class="house-list-wrap"]/li') # 提取相同的前缀
gs = 0
for li in li_list:
data = []
# 解析
biaoti = li.xpath('./div[2]/h2/a/text()')[0]
# zhuangxiu 4页以前可用,以后的网页代码已经改变
# zhuangxiu = li.xpath('./div[2]/h2/i[1]/i[1]/text()')[0]
huxinhuxin = li.xpath('./div[2]/p[1]/span[1]/text()')[0]
mianji = li.xpath('./div[2]/p[1]/span[2]/text()')[0]
chaoxiang = li.xpath('./div[2]/p[1]/span[3]/text()')[0]
louceng = li.xpath('./div[2]/p[1]/span[4]/text()')[0]
dizhi = li.xpath('./div[2]/p[2]/span/a/text()')[0]
jiage = li.xpath('./div[3]/p/b/text()')[0]
pfjiage = li.xpath('./div[3]/p[2]/text()')[0]
# 拼装成一个列表
data.append(hang + gs) # 为每条书添加序号
data.append(biaoti)
data.append(huxinhuxin)
data.append(mianji.replace('㎡',''))#这里爬取的时候就进行数据,将单位替换为空
data.append(chaoxiang)
data.append(louceng)
data.append(dizhi)
data.append(jiage)
data.append(pfjiage.replace("元/㎡",""))#这里爬取的时候就进行数据,将单位替换为空
# print("-----------------")
# print(pfjiage.replace("元/㎡",""))
# 写入数据到execl中
for i in range(len(data)):
self.fzsj.write(hang + gs, i, data[i])
gs += 1 # 记录行数增量
print(biaoti, huxinhuxin, mianji, chaoxiang, louceng, dizhi, jiage, pfjiage)
self.cj.save('D:/房子信息.xls')
# 给循环加延迟
time.sleep(3)
if __name__ == "__main__":
dbBook = pashuju()
dbBook.getUrl()
数据清洗
-
清洗前
-
运用的清洗代码
import pandas as pd
import numpy as np
#打开链接下excel下的表
daoru=pd.read_excel('D:/房子信息.xls', sheet_name='58房子数据')
#修改索引(id不符合)
suoyin=pd.DataFrame(daoru.values,index=np.arange(1,len(daoru)+1),columns=np.array(['编号','介绍','户型','面积/平方米','朝向','楼层','地址','价格/万','平方价格']))
# 设置行不限制数量,不然会中间有省略号,数据会看不到
pd.set_option('display.max_rows',None)
# 设置列不限制数量,不然会中间有省略号,数据会看不到
pd.set_option('display.max_columns',None)
# 控制台输出的列数超过100换行,防止数据表格会折回来
pd.set_option('display.width',1000)
#设置数据展示宽度
pd.set_option('display.width',None)
# 这两个参数的默认设置都是False 将这些函数绑定到一个可调用的函数中,并使用它作为在pd中公开的函数。 规范布局
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
#清理重复数据
# subset是根据字段去除重复,多个字段就写成列表形式,默认是所有列
# keep first就是保留第一个,last就是最后
#inplace 默认为False,不直接进行修改
qingchu = suoyin.drop_duplicates(subset="介绍", keep='first', inplace=False)
# 重建索引 删除缺失值的列 qingchu.reset_index(drop=True , inplace=True)
qingchu.to_excel('D:/数据清洗.xls',encoding='utf-8',index=None)
print(qingchu)
3.清洗后
画折线图
- 直接附上代码
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
zhexiantu = pd.read_excel('D:/数据清洗.xls')
#设置画布的大小
plt.figure(figsize=[20,10],dpi=270)
#设置网格线
plt.grid()
#导入数据
y_jiage=zhexiantu['价格/万']
plt.plot(y_jiage,label='价格')#,color="blue
#设置刻度线
plt.xticks(np.arange(0,600,100))
plt.yticks(np.arange(0,1400,100))
#设置 x,y,标图
plt.xlabel('房子编号')
plt.ylabel('房子价格')
plt.title('丽水房价折线图')
#生存样板防止更新丢失
plt.legend()
#保存图片
plt.savefig("丽水房子分析折线图.jpg")
#生成图片
plt.show()
.
画饼图
import pandas as pd
import matplotlib.pyplot as plt
bingtu = pd.read_excel('D:/数据清洗.xls')
jiage=bingtu['价格/万']
jg_0=[0]
jg_50=[0]
jg_100=[0]
jg_200=[0]
jg_300=[0]
jg_400=[0]
jg_500=[0]
jg_600=[0]
jg_1000=[0]
for i in range(0,len(jiage)):
if jiage[i] >= 1000:
jg_1000[0] += 1
elif jiage[i] >= 600:
jg_600[0] += 1
elif jiage[i] >= 500:
jg_500[0] += 1
elif jiage[i] >= 400:
jg_400[0] += 1
elif jiage[i] >= 300:
jg_300[0] += 1
elif jiage[i] >= 200:
jg_200[0] += 1
elif jiage[i] >= 100:
jg_100[0] += 1
elif jiage[i] >= 50:
jg_50[0] += 1
else:
jg_0[0] += 1
labels = ['0-50W','0-100W', '100W-200W', '200W-300W', '300W-400W', '400W-500W', '500W-600W', '600W-1000W','1000W+']
x = [jg_0,jg_50,jg_100,jg_200,jg_300,jg_400,jg_500,jg_600,jg_1000]
#凸出
explode = (0.3,0.2,0.05,0.05,0.05,0.25,0.4,0.5,0.6)
#设置画布的大小
plt.figure(figsize=[8,6],dpi=270)
# 绘制饼图
plt.pie(x,labels=labels,autopct='%1.1f%%',
textprops = {'fontsize':14, 'color':'k'},
explode=explode,radius = 3.1
,labeldistance=1.2,
wedgeprops = {'linewidth': 0.5, 'edgecolor':'red'}
,pctdistance=0.83)
plt.rcParams['legend.fontsize']=14
plt.axis('equal')
#保存图片
plt.savefig("丽水房子价格饼图.jpg")
#标题
plt.title(' 丽水房价饼图')
plt.show()