爬取链家二手房房价数据存入mongodb并进行分析

实验目的

1.使用python将爬虫数据存入mongodb;
2.使用python读取mongodb数据并进行可视化分析。

实验原理

MongoDB是文档数据库,采用BSON的结构来存储数据。在文档中可嵌套其他文档类型,使得MongoDB具有很强的数据描述能力。本节案例使用的数据为链家的租房信息,源数据来自于链家网站,所以首先要获取网页数据并解析出本案例所需要的房源信息,然后将解析后的数据存储到MongoDB中,最后基于这些数据进行城市租房信息的查询和聚合分析等。

实验环境

OS:Windows 10
Python3
MongoDB:v4.4

实验步骤

一、使用python将爬虫数据存入mongodb

1.爬取数据

分析租房信息首先要获取原始的二手房房源数据,本例使用python爬虫技术获取链家网页的二手房楼盘信息。如图所示,对房源信息进行分析需要获取房源所在区域、小区名、房型、面积、具体位置、价格等信息。
在这里插入图片描述

定义了三个函数依次实现此过程:

import requests
import re
import threading
import pandas as pd
from lxml import etree
# 全部信息列表
count=list()#生成1-10页url
def url_creat():#基础urlurl = 'https://gl.lianjia.com/ershoufang/pg{}/'#生成前10页url列表links=[url.format(i) for i in range(1,11)]return links#对url进行解析
def url_parse(url):headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9','Accept-Encoding': 'gzip, deflate, br','Accept-Language': 'zh-CN,zh;q=0.9','Cache-Control': 'no-cache','Connection': 'keep-alive','Cookie': 'lianjia_uuid=7e346c7c-5eb3-45d9-8b4f-e7cf10e807ba; UM_distinctid=17a3c5c21243a-0c5b8471aaebf5-6373267-144000-17a3c5c21252dc; _smt_uid=60d40f65.47c601a8; _ga=GA1.2.992911268.1624510312; select_city=370200; lianjia_ssid=f47906f0-df1a-49e2-ad9b-648711b11434; CNZZDATA1253492431=1056289575-1626962724-https%253A%252F%252Fwww.baidu.com%252F%7C1626962724; CNZZDATA1254525948=1591837398-1626960171-https%253A%252F%252Fwww.baidu.com%252F%7C1626960171; CNZZDATA1255633284=1473915272-1626960625-https%253A%252F%252Fwww.baidu.com%252F%7C1626960625; CNZZDATA1255604082=1617573044-1626960658-https%253A%252F%252Fwww.baidu.com%252F%7C1626960658; _jzqa=1.4194666890570963500.1624510309.1624510309.1626962867.2; _jzqc=1; _jzqy=1.1624510309.1626962867.2.jzqsr=baidu|jzqct=%E9%93%BE%E5%AE%B6.jzqsr=baidu; _jzqckmp=1; _qzjc=1; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2217a3c5c23964c1-05089a8de73cbf-6373267-1327104-17a3c5c23978b3%22%2C%22%24device_id%22%3A%2217a3c5c23964c1-05089a8de73cbf-6373267-1327104-17a3c5c23978b3%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%22%2C%22%24latest_referrer_host%22%3A%22www.baidu.com%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%2C%22%24latest_utm_source%22%3A%22baidu%22%2C%22%24latest_utm_medium%22%3A%22pinzhuan%22%2C%22%24latest_utm_campaign%22%3A%22wyyantai%22%2C%22%24latest_utm_content%22%3A%22biaotimiaoshu%22%2C%22%24latest_utm_term%22%3A%22biaoti%22%7D%7D; Hm_lvt_9152f8221cb6243a53c83b956842be8a=1624510327,1626962872; _gid=GA1.2.134344742.1626962875; Hm_lpvt_9152f8221cb6243a53c83b956842be8a=1626962889; _qzja=1.1642609541.1626962866646.1626962866646.1626962866647.1626962872770.1626962889355.0.0.0.3.1; _qzjb=1.1626962866646.3.0.0.0; _qzjto=3.1.0; _jzqb=1.3.10.1626962867.1; srcid=eyJ0Ijoie1wiZGF0YVwiOlwiNzQ3M2M3OWQyZTQwNGM5OGM1MDBjMmMxODk5NTBhOWRhNmEyNjhkM2I5ZjNlOTkxZTdiMDJjMTg0ZGUxNzI0NDQ5YmZmZGI1ZjZmMDRkYmE0MzVmNmNlNDIwY2RiM2YxZTUzZWViYmQwYmYzMDQ1NDcyMzYwZTQzOTg3MzJhYTRjMTg0YjNhYjBkMGMyZGVmOWZiYjdlZWQwMDcwNWFkZmI5NzA5MjM1NmQ1NDg0MzQ3NGIzYjkwY2IyYmEwMjA2NjBjMjI2OWRjNjFiNDE3ZDc1NGViNjhlMzIzZmI0MjFkNzU5ZGNlMzAzMDhlNDAzYzIzNjllYWFlMzYxZGYxYjNmZmVkNGMxYTk1MmQ3MGY2MmJhMTQ1NWI4ODIwNTE5ODI2Njg2MmVkZTk4OWZiMDhjNTJhNzE3OTBlNDFiZDQzZTlmNDNmOGRlMTFjYTAwYTRlZTZiZWY5MTZkMTcwN1wiLFwia2V5X2lkXCI6XCIxXCIsXCJzaWduXCI6XCI3ZjI1NWI1ZlwifSIsInIiOiJodHRwczovL3FkLmxpYW5qaWEuY29tL2Vyc2hvdWZhbmcvMTAzMTE2MDkzOTU5Lmh0bWwiLCJvcyI6IndlYiIsInYiOiIwLjEifQ==','Host': 'qd.lianjia.com','Pragma': 'no-cache','Referer': 'https://qd.lianjia.com/','sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"','sec-ch-ua-mobile': '?0','Sec-Fetch-Dest': 'document','Sec-Fetch-Mode': 'navigate','Sec-Fetch-Site': 'same-origin','Sec-Fetch-User': '?1','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'}response=requests.get(url=url,headers=headers).texttree=etree.HTML(response)#ul列表下的全部li标签li_List=tree.xpath("//*[@class='sellListContent']/li")#创建线程锁对象lock = threading.RLock()#上锁lock.acquire()for li in li_List:#标题title=li.xpath('./div/div/a/text()')[0]#网址link=li.xpath('./div/div/a/@href')[0]#位置postion=li.xpath('./div/div[2]/div/a/text()')[0]+li.xpath('./div/div[2]/div/a[2]/text()')[0]#类型types=li.xpath('./div/div[3]/div/text()')[0].split(' | ')[0]#面积area=li.xpath('./div/div[3]/div/text()')[0].split(' | ')[1]area=area[:-2]#房屋信息info=li.xpath('./div/div[3]/div/text()')[0].split(' | ')[2:-1]info=''.join(info)#房屋年份year=li.xpath('./div/div[3]/div/text()')[0].split(' | ')[5]numbers = re.sub("\D", "",year) # 匹配连续的数字year=''.join(numbers)#房屋装修情况renovation=li.xpath('./div/div[3]/div/text()')[0].split(' | ')[3]#总价count_price=li.xpath('.//div/div[6]/div/span/text()')[0]#单价angle_price=li.xpath('.//div/div[6]/div[2]/span/text()')[0]angle_price=re.sub("\D", "",angle_price)#只保留数字dic={'标题':title,"位置":postion,'房屋类型':types,'面积(平米)':area,"单价(元/平)":angle_price,'总价(万)':count_price,'年份':year,'精/简装':renovation,'介绍':info,"网址":link}print(dic)#将房屋信息加入总列表中count.append(dic)#解锁lock.release()
def run():links = url_creat()#多线程爬取for i in links:x=threading.Thread(target=url_parse,args=(i,))x.start()x.join()#将全部房屋信息转化为exceldata=pd.DataFrame(count)data.to_excel('桂林房屋信息.xlsx',index=False)
if __name__ == '__main__':run()

爬虫细节参考:【Python爬虫项目】链家房屋信息抓取(超详细适合新手练习附源码)

2.数据清洗

爬出下来的数据存在空缺的情况,并需要去除部分信息【不清洗也可以】
使用python进行数据清洗。首先读取数据

import pandas as pd
data = pd.read_excel("桂林房屋信息.xlsx")
data.head(5)
#data.info()

在这里插入图片描述

去掉标题、介绍和网址列,去掉年份为空的行

data_db=data[["位置","房屋类型","面积(平米)","单价(元/平)","总价(万)","年份","精/简装"]].dropna()
data_db["年份"]=data_db["年份"].astype('int')#年份变成整型
data_db = data_db.sort_values(by="年份", ascending=False)#按年份进行排序
data_db

在这里插入图片描述

3.数据存储

将清洗好的数据存储到mongodb中:将数据转换成字典列表形式,通过insert_many方法写入

import pandas as pd
from pymongo import MongoClient# 创建MongoDB客户端
client = MongoClient('localhost', 27017) # 根据自己的配置修改主机名和端口号
db = client['lianjia'] # 选择或创建数据库
collection = db['ershoufang'] # 选择或创建集合# 读取DataFrame数据
# 转换DataFrame为字典列表形式
documents = data_db.to_dict(orient='records')# 向集合中插入文档
collection.insert_many(documents)print("Data stored in MongoDB successfully!")

成功写入
在这里插入图片描述

二、使用 python 读取 mongodb 数据并进行可视化分析

房源数据进行存储后,需要进行数据分析,比如获取不同年份房价(单价)的最小值和最大值,并以条形图的形式展示出来。
1.以统计不同年份的房价为例,使用 MongoDB 聚合管道技术对数据进行分组计算,如下代码片段对房源的不同年份进行分组聚合:

db = client['lianjia'] # 选择数据库
col= db['ershoufang'] # 选择集合
# 使用 $group 操作对文档分组和聚合
pipeline = [{"$group": {"_id": "$年份","MinPrice": {"$min": "$单价(元/平)"} ,"MaxPrice": {"$max" : "$单价(元/平)"}}}
] 
# 执行聚合操作
price = list(col.aggregate(pipeline))
# 打印分组和聚合结果
for doc in price:print(doc)

在这里插入图片描述

出现了问题:

#这样提取的不了“_id”字段到列表year中
year =[]
for doc in price:year.append(doc["_id"])

也就是nongodb聚合出来的结果python不能直接提取到列表,这个问题我也不知道如何解决。。。
大佬们若知道还请评论区告知一声。

所以,比较笨拙的办法为,把聚合的结果先存储到新的集合中:

 db.ershoufang.aggregate( [ {$group:{"_id":"$年份","MinPrice":{"$min":"$单价(元/平)"},"MaxPrice":{"$max":"$单价(元/平)"}}},{ $sort : { "_id" : 1 } },{"$out":{"db":"lianjia","coll":"tongji"}}])

其中,{ $sort : { “_id” : 1 } }为按照_id字段排序,即为按照年份排序, {“$out”:{“db”:“lianjia”,“coll”:“tongji”}} 为把聚合结果作文新文档存放在数据库lianjia的集合tongji中。

在这里插入图片描述

这样就可以提取文档的字段到列表中了,进行下一步:绘图。

2.基于聚合统计出的数据使用 python 绘制条形图,使用到 matplotlib 库,具体代
码如下:

import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import jsoncol2= db['tongji'] # 选择集合
year =[]
Min_Price =[]
Max_Price =[]
#获取聚合后的数据并插入 year ,Min_Price,Max_Price,用于纵横坐标显示。
for doc in col2.find():year.append(doc["_id"])Min_Price.append(doc["MinPrice"])Max_Price.append(doc["MaxPrice"])
# 设置中文字体和负号正常显示
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
# 创建一个新的画布并指定大小为10x6英寸
plt.figure(figsize=(16, 8))
x=year
#绘制条形图 :条形中点横坐标;height:长条形高度;width:长条形宽度,默认值0.8;label:为后面设置 legend 准备
rects1=plt.bar(x,height=Min_Price,width=0.4,alpha=0.8,color='red', label="最低房价")
rects2=plt.bar([i + 0.4 for i in x],height=Max_Price, width=0.4, color='green', label="最高房价")
plt.ylim(0,max(Max_Price)+1000) # y 轴取值范围
plt.legend(loc="upper left", prop={"size": 12, })  # 显示图例  设置图例的大小和方向
#设置两个柱状图数据显示
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")
plt.ylabel("单价")
#设置 x 轴刻度显示值;参数一:中点坐标;参数二:显示值
plt.xticks([index + 0.2 for index in x],year)
plt.xlabel("年份")
plt.title("桂林二手房房价")#显示条形图
plt.show()

结果如图所示
在这里插入图片描述
一些容易出现的问题:
1.数据类型问题:爬虫阶段下载的数据可能是文本类型的或者带单位,数据分析需要改为浮点型或者整型,当然也可以在下载的时候处理好
2.下载的数据若要以年份进行排序,需要提前处理,否则画图会出现问题。

参考资料:《NoSQL数据库原理与应用》,主编:王爱国、许桂秋。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/695541.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IP地址定位可以精确到哪里

IP地址定位能够精确到的位置级别取决于多种因素,包括IP地址的分配方式、数据库的质量和更新频率、用户的移动性等。一般而言,IP地址定位可以精确到市级,甚至可以达到街道级别 https://www.ip66.net/?utm-sourceLJ&utm-keyword?1146 但需…

LeetCode494. Target Sum——01背包

文章目录 一、题目二、题解 一、题目 You are given an integer array nums and an integer target. You want to build an expression out of nums by adding one of the symbols ‘’ and ‘-’ before each integer in nums and then concatenate all the integers. For …

大数据在电商领域的典型应用

大数据作为一种新兴的信息技术,是无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。 大数据技术是指在数据获取、存储、管理、…

程序媛的mac修炼手册-- 如何彻底卸载Python

啊,前段时间因为想尝试chatgpt的API,需要先创建一个python虚拟环境来安装OpenAI Python library. 结果,不出意外的出意外了,安装好OpenAI Python library后,因为身份认证问题,根本就没有获取API key的权限…

Shader基础的简单实现(基于URP渲染)

一个模型是很多个顶点组成,顶点数据中包含坐标、法线、切线、UV坐标、顶点颜色等等组成。 URP(Universal Render Pipeline)通用渲染管线,是Unity在2019.3版本之后推出的一种新的渲染管线。传统的渲染管线在渲染多光源的情况,是把每一个主要光…

C语言第二十八弹---整数在内存中的存储

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 目录 1、整数在内存中的存储 2、大小端字节序和字节序 2.1、什么是大小端? 2.2、为什么有大小端? 2.3、练习 2.3.1、练习1 2.3.2、练习2 2.…

Java 注解机制解密并发编程的时间之谜:揭开Happens-Before的神秘面纱

优质博文:IT-BLOG-CN 一、简介 为什么需要happens-before原则: 主要是因为Java内存模型 , 为了提高CPU效率,通过工作内存Cache代替了主内存。修改这个临界资源会更新work memory但并不一定立刻刷到主存中。通常JMM会将编写的代码…

Pytorch 复习总结 2

Pytorch 复习总结,仅供笔者使用,参考教材: 《动手学深度学习》Stanford University: Practical Machine Learning 本文主要内容为:Pytorch 线性神经网络。 本文以机器学习中的两大基本问题 —— 回归和分类为例,介绍…

【数据结构初阶 6】二叉树:堆的基本操作 + 堆排序的实现

文章目录 🌈 Ⅰ 二叉树的顺序结构🌈 Ⅱ 堆的概念与性质🌈 Ⅲ 堆的基本操作01. 堆的定义02. 初始化堆03. 堆的销毁04. 堆的插入05. 向上调整堆06. 堆的创建07. 获取堆顶数据08. 堆的删除09. 向下调整堆10. 判断堆空 🌈 Ⅳ 堆的基本…

【selenium】八大元素定位方式|xpath css id name...

目录 一、基础元素定位 二、cssSelector元素定位——通过元素属性定位 三、xpath元素定位——通过路径 1 、xpath绝对定位 (用的不多) 缺点:一旦页面结构发生变化(比如重新设计时,路径少两节)&#x…

从计网的角度讲明白什么是网关

网关(Gateway)又称网间连接器、协议转换器。网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关的结构也和路由器类似,不同的是互连层。网关既可以用于广域网互连,也可以用于局域网互连…

JDBC实现连接池

简单上手 使用 JDBC 来执行 SQL 查询和更新操作 import java.sql.*;public class Main {public static void main(String[] args) {String url "jdbc:mysql://localhost:3306/your_database_name";String username "your_username";String password &…

vs2015零基础编译zlib从失败到成功

本博文源于笔者不断尝试从0编译zlib到能够将文件打包成zip的一个简单过程,其中包含了如何下载zlib,如何编译zlib,如何使用zlib等。内容堪比教科书级别,可以收藏,可以自用,希望博文能帮助到读者。 1、下载z…

Protocol Buffers v21.12 安装 ( linux 系统 )

下载 Protocol Buffers v21.12 Protocol Buffers v21.12 解压 tar zxvf protobuf-cpp-3.21.12.tar.gz执行 进入解压目录,执行下面configure可执行程序,目的是监测安装环境,生成makefile ./configure执行完后可以检查是否生成makefile文件 构…

Unity单元测试

Unity单元测试是一个专门用于嵌入式单元测试的库, 现在简单讲下移植以及代码结构. 源码地址: GitHub - ThrowTheSwitch/Unity: Simple Unit Testing for C 1.我们只需要移植三个文件即可: unity.c, unity.h, unity_internals.h 2.然后添加需要测试的函数. 3.在main.c中添加…

Swift基础知识:23.Swift析构过程

在 Swift 中,析构过程是指在一个类的实例被释放之前进行的清理操作。通常,这些清理操作包括释放实例所持有的资源、取消订阅通知、关闭文件等。Swift 使用析构器(deinitializer)来实现析构过程,它类似于构造器&#xf…

公司文件防泄密管理系统

公司文件防泄密管理系统是一种综合性的解决方案,旨在确保企业文件的安全性和保密性,防止内部员工或外部攻击者非法获取、泄露或篡改敏感信息。 PC端:https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是关于…

【JavaEE】_form表单构造HTTP请求

目录 1. form表单的格式 1.1 form表单的常用属性 1.2 form表单的常用搭配标签:input 2. form表单构造GET请求实例 3. form表单构造POST请求实例 4. form表单构造法的缺陷 对于客户端浏览器,以下操作即构造了HTTP请求: 1. 直接在浏览器…

IDM下载器2024中文版主要功能、使用场景、优点、缺点介绍

软件分析师眼中的IDM(Internet Download Manager) IDM绿色下载如下: https://wm.makeding.com/iclk/?zoneid34275 一、主要功能 高速下载:利用多线程技术和文件分块下载策略,显著提高下载速度。断点续传:即使在下载…

【Linux】MySQL数据库的使用

【Linux】MySQL数据库的使用 一、访问MySQL数据库二、创建及删除库和表1、创建新的库2、创建新的表3、删除一个数据表4、删除一个数据库 三、管理表中的数据记录1、插入数据记录2、查询数据记录3、修改数据记录4、删除数据记录 四、数据库用户授权1、授予权限2、查看权限3、撤销…