链家全国房价数据分析 : 数据获取

最近一直在看论文,也有很久没有coding了,感觉对爬虫的技术有些生疏,我觉得即使现在手头没有在做这方面的东西,经常爬点对技术保鲜还是很重要的。所以这次我打算爬链家的房价数据,目的主要是对爬虫和Python的东西作一个巩固,然后做一个分析。

以链家广州为例查看网页结构,可以看到它是下图这样的:

看起来内容元素的结构十分清晰,分类很好,都是我们想要的东西。

链家对爬虫的容忍度挺高的,不会封IP,也没有要求登录,是我们练手的好题材(不过大家要适可而止,人家的服务器也不是无底洞)

我的环境:Python 3.6,jupyter notebook

爬虫主要有两个部分:下载模块和解析模块。

下载模块

在之前写爬虫的时候,我发现下载模块的代码重复度很高,无论对什么网址,需要解决的东西大致有三个:

  1. User-Agent,用来模拟浏览器,爬虫本质上是一个下载器,需要通过加入一些浏览器的标识信息使得服务器以为这是一个来自浏览器的请求。
  2. IP代理,大部分的反爬虫策略都是通过屏蔽IP地址来限制爬虫的,当同一个IP短时间内访问过于频繁,就会被认为是爬虫,从而返回403 forbidden的结果。一般来说,免费IP代理都很垃圾,不是很慢就是不能用,天下没有免费的午餐,建议使用付费IP代理。
  3. Cookie,对于一些需要登录才可以查看的网页(微博,豆瓣等),需要从浏览器获取上次成功登录的cookie,携带这个cookie去访问,才能通过。

    我把这些常用代码写成了一个类(这些代码在这里),但是我们这次用不到,所以我只从中摘取了一部分:
import requests
from lxml import etree
import random
import json
import pandas as pd
from pandas.io.json import json_normalize
import math
import re# 随机获取一个UserAgent
def getUserAgent():UA_list = ["Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36","Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) App leWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53","Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ;  QIHU 360EE)","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Maxthon/3.0)","Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Mozilla/5.0 (Macintosh; U; IntelMac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1Safari/534.50","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1","Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6","Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6","Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5","Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3","Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3","Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3","Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3","Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24","Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"]return random.choice(UA_list)# 使用requests获取HTML页面
def getHTML(url):global invalid_ip_countheaders = {'User-Agent': getUserAgent(),'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',}try:web_data=requests.get(url,headers=headers,timeout=20)#超时时间为20秒status_code=web_data.status_coderetry_count=0while(str(status_code)!='200' and retry_count<5):print('status code: ',status_code,' retry downloading url: ',url , ' ...')web_data=requests.get(url,headers=headers,timeout=20)status_code=web_data.status_coderetry_count+=1if str(status_code)=='200':return web_data.content.decode('utf-8')else:return "ERROR"except Exception as e:print(e)return "ERROR"

解析模块

通常在解析网页之前,第一个需要分析的地方就是怎么才能拿到下一页的链接。

  1. 我们可以检查“下一页”按钮,提取每个页面的“下一页”中的链接,从而得到下一页的url
  2. 我们可以不断点击第1页,第2页,第3页,观察浏览器的地址栏有没有什么规律,通过修改url模板来得到下一页
  3. 我们可以使用浏览器的调试功能,在点击下一页的时候进行网络抓包,看看浏览器的请求是什么,比如Chrome我们就可以按F12打开开发人员工具:

我们很幸运的看到了在每翻一页的时候浏览器向服务器发送了这样一条请求:

https://gz.fang.lianjia.com/loupan/pg2/?_t=1

把它输入浏览器地址栏可以看到返回了一整篇的代码:

没错这正是我们想要的!

仔细观察可以发现,这不是什么乱码,这是下一页网页的内容,它现在是使用Json格式返回了,浏览器根据网址的模板将数据填充上去渲染就成了我们所看到的页面了,我们现在可以直接拿到这些原始数据,也就意味着省去了从网页中解析的步骤,多么的方便。

所以我们就通过这个网址模板逐页发送请求,然后使用json包进行解析。

我们打算最后把它存成pandas的CSV文件,这样方便我们后续进行分析,所以就不考虑数据库了。
代码如下:

"""
传入的city是一个元组:(城市名,城市url)
"""
def getDetail(city):url=city[1]print('searching city: ',city[0],'...')url='https:'+url+'/loupan/'print('url is: ',url) #拼接成完整urlhtml=getHTML(url) #下载网页selector=etree.HTML(html)"""获取最大页数"""try:maxPage=selector.xpath('//div[@class="page-box"]/@data-total-count')maxPage=math.ceil(int(maxPage[0])/10)except Exception as e:maxPage=1print('max page is: ',maxPage)df=pd.DataFrame() # 初始化dataframefor page in range(1,maxPage+1):print('fecthing page',page,'...')url=url+str(page)+'/?_t=1' #构造每一页的urlresult=json.loads(getHTML(url)) #获取网页内容df_iter=json_normalize(result['data']['list']) #格式化为dataframedf=df.append(df_iter) #将每一页的数据拼接file_path='./loupan/'+city[0]+'.csv'df.to_csv(file_path,index=False,encoding='utf-8')

现在只是一个特定城市的代码,那么说好的全国呢?
链家对于全国的城市的列表在首页的底部:

通过解析这些元素可以获得背后的每个城市的链接
代码如下:

# 获取全国所有的已知城市
url='https://gz.fang.lianjia.com/loupan/pg1/'
html=getHTML(url)
selector=etree.HTML(html)
cities_url_template=selector.xpath('//div[@class="city-change animated"]/div[@class="fc-main clear"]//ul//li/div//a/@href')
cities_name=selector.xpath('//div[@class="city-change animated"]/div[@class="fc-main clear"]//ul//li/div//a/text()')
cities=list(zip(cities_name,cities_url_template))
for city in cities:#city 是一个元组 (城市名,城市url)getDetail(city)

执行上面的代码,大概十几分钟就可以爬完全国的新房房价数据了:

仅仅爬新房的话,数据量有点小,因为你可以看到有些城市的房源也就个位数,没多少新房,倒是二手房的数量在每个城市都比较多,我们接下来打算再爬二手房的信息。

二手房

再爬二手房的时候就没这么幸运了,通过观察浏览器的抓包轨迹可以发现,所有的请求相应都是直接将网页返回,而不是返回json字段了。真是令人脑壳疼,那就意味着我们不能偷懒,而是必须老老实实解析网页了。

下载模块跟新房的那部分代码是一样的,所以这次我们只需要考虑解析的部分就好了。

首先要确定的是我们需要什么数据。我打算提取以下几个可能有用的类别:

  1. 名称
  2. 链接
  3. 房屋信息
  4. 楼层
  5. 房龄
  6. 地区
  7. 关注的人
  8. 标签
  9. 总价
  10. 单位面积价格

因为通过分析页面我发现,其实你在网页上看的时候划分的整整齐齐的元素,是很难一个一个直接解析出来的,比如标签,一个房子可以打很多个标签,可是在解析的时候,是把页面上所有的房子一起解析的,无法做到逐个房子处理。所以有一些数据只好先放在一起,随后再进行进一步处理。

所以整体思路是这样的:

通过首页找到全国各个城市二手房的网址 -> 进入一个特定城市的首页 -> 获取最大页数 -> 爬取每一页的名称、链接、房屋信息等 -> 构造一个dataframe,保存成文件

代码如下:

def get_ershoufang(city):print('getting city:',city[0])print('url: ',city[1])names=[]links=[]houseInfo=[]floor=[]age=[]district=[]concern=[]tags=[]total_price=[]unit_price=[]city_link=city[1]html=getHTML(city_link)selector = etree.HTML(html)try:maxpage_str = selector.xpath('//div[@class = "page-box house-lst-page-box"]/@page-data')maxpage = maxpage_str[0].split(',')[0].split(':')[1]maxpage = int(maxpage)except:maxpage = 1print('max page is : ',maxpage)for page in range(1,maxpage):print('fetching page ',page,'...')link = city_link+'pg'+str(page)+'/'html = getHTML(link)selector = etree.HTML(html)lis=selector.xpath('//ul[@class = "sellListContent"]//li[@class = "clear LOGCLICKDATA"]')for li in lis:names.append(li.xpath('./div[@class="info clear"]/div[@class="title"]/a/text()')[0])links.append(li.xpath('./div[@class="info clear"]/div[@class="title"]/a/@href')[0])positions.append(li.xpath('./div[@class="info clear"]/div[@class="address"]/div[@class="houseInfo"]/a/text()')[0])try:houseInfo.append(' '.join(li.xpath('./div[@class="info clear"]/div[@class="address"]/div[@class="houseInfo"]//text()'))[1:-1])except:houseInfo.append('None')try:floor.append(li.xpath('./div[@class="info clear"]/div[@class="flood"]/div[@class="positionInfo"]//text()')[0])except:floor.append('None')try:age.append(li.xpath('./div[@class="info clear"]/div[@class="flood"]/div[@class="positionInfo"]//text()')[2])except:age.append('None')try:district.append(li.xpath('./div[@class="info clear"]/div[@class="flood"]/div[@class="positionInfo"]//text()')[-1])except:district.append('None')try:concern.append(li.xpath('./div[@class="info clear"]/div[@class="followInfo"]//text()')[0])except:concern.append('None')try:tags.append('_'.join(li.xpath('./div[@class="info clear"]/div[@class="followInfo"]/div[@class="tag"]//text()')))except:tags.append('None')try:if city[0]=='北京二手房':total_price.append(' '.join(li.xpath('./div[@class="info clear"]/div[@class="followInfo"]/div[@class="priceInfo"]/div[@class="totalPrice"]//text()')))else:total_price.append(' '.join(li.xpath('./div[@class="info clear"]/div[@class="priceInfo"]/div[@class="totalPrice"]//text()')))except:total_price.append('None')try:if city[0]=='北京二手房':unit_price.append(' '.join(li.xpath('./div[@class="info clear"]/div[@class="followInfo"]/div[@class="priceInfo"]/div[@class="unitPrice"]//text()')))else:unit_price.append(li.xpath('./div[@class="info clear"]/div[@class="priceInfo"]/div[@class="unitPrice"]//text()')[0])except:unit_price.append('None')df_data={'name':names,'link':links,'position':positions,'house_info':houseInfo,'floor':floor,'age':age,'district':district,'concern':concern,'tags':tags,'total_price':total_price,'unit_price':unit_price}df=pd.DataFrame(df_data)df.to_csv('./ershoufang/'+city[0]+'.csv',index=False,encoding='utf-8')

爬取全国所有二手房城市的链接代码:

# 获取全国所有的城市
url='https://gz.lianjia.com/ershoufang/'
html=getHTML(url)
selector=etree.HTML(html)
city_name=selector.xpath('//div[@class="link-list"]/div[1]/dd//a/text()')
city_links=selector.xpath('//div[@class="link-list"]/div[1]/dd//a/@href')
cities=list(zip(city_name,city_links)) #('北京' , 'https://bj.lianjia.com/ershoufang/')
for city in cities:get_ershoufang(city)

由于数据比较多,这段代码要跑的更久一点,大概一个多小时吧?因为中间断过,一共多久我也不记得了。
结果如图:

以上便是爬虫的部分,数据分析的部分在链家全国房价数据分析 : 数据分析及可视化

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

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

相关文章

上海二手房网站

文章目录 简介git总体架构开发目录 简介 业务目标&#xff1a;实现上海二手房全量数据动态更新、统计、汇总展示&#xff0c;了解二手房变化趋势。 技术目标&#xff1a;前端到后端技术的demo。前身&#xff1a;租房网站。毕业2年需求变更&#xff1a;租房->买房… git 前…

上海的二手房价有所下跌,现在你们的工资够买间厕所了吗?Python帮你分析上海的二手房价

前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 作者&#xff1a;林小呆 仪表板展示 项目背景 去面试的时候被问上海二手房的一些情况&#xff0c;作为一个土著&#xff0c;我只知道上海这个区…

上海二手房价数据分析

目的:本篇给大家介绍一个数据分析的初级项目,目的是通过项目了解如何使用Python进行简单的数据分析。 数据源:博主通过爬虫采集的安X客上海二手房数据,由于能力问题,只获取了2160条数据。 数据初探 首先导入要使用的科学计算包numpy,pandas,可视化matplotlib,seaborn im…

NBA球员投篮数据可视化

最近看了公众号「Crossin的编程教室」的一篇文章。 是有关于NBA球员出手数据的可视化案例&#xff0c;原文链接如下。 个人感觉比较有趣&#xff0c;所以想着自己也来实现一波。 总体上来说差不多&#xff0c;可能就是美观点吧... / 01 / 篮球场 从网上找的篮球场尺寸图&#x…

利用Python进行NBA比赛数据分析

利用Python进行NBA比赛数据分析 一、实验介绍 1.1 内容简介 不知道你是否朋友圈被刷屏过nba的某场比赛进度或者结果&#xff1f;或者你就是一个nba狂热粉&#xff0c;比赛中的每个进球&#xff0c;抢断或是逆转压哨球都能让你热血沸腾。除去观赏精彩的比赛过程&#xff0c;我们…

2021年常规赛NBA球员数据分析

项目介绍&#xff1a; 1、数据来源&#xff1a; 1&#xff09;数据来源腾讯体育NBA数据&#xff0c;爬虫解析三个JS网页解析获得数据&#xff0c;共有150个球员和22个指标&#xff0c;整理后数据最终如下图格式 2&#xff09;球队队徽来自网络 3&#xff09;球队地理位置的经…

kaggle:NBA球员投篮数据分析与可视化(一)

作为数据科学领域的金字招牌&#xff0c;kaggle已成为世界上最受欢迎的数据科学竞赛平台。在kaggle上&#xff0c;每个竞赛题下都藏匿着大批来自世界各地并且身怀绝技的数据科学家。作为一种众包模式&#xff0c;kaggle通过收取部分佣金将企业的数据挖掘问题发布在平台上并设立…

实例:【基于机器学习的NBA球员信息数据分析与可视化】

文章目录 一、项目任务二、代码实现及分析1. 导入模块2. 导入文件并对文件信息进行整体探测3. 数据预处理3.1 查看数据集信息3.2 数据清洗与转换3.3 数据去重 4. 数据可视化4.1 数据相关性4.2 球员数据分析 5. 基于逻辑回归的球员分类5.1 数据重定义5.2 划分数据集与验证集5.3 …

利用Python预测NBA比赛结果

关注「实验楼」&#xff0c;每天分享一个项目教程 NBA总决赛正在火热上演&#xff0c;而有数据的地方就有预测&#xff0c;本教程就教你使用Python预测NBA比赛的结果。 正文共&#xff1a;3240 字 预计阅读时间&#xff1a;8 分钟‍ 一、实验介绍 1.1 内容简介 不知道你是否…

PayPal,Stripe,Square轮询支付系统

轮询展示 展示我们轮询的页面 轮询套餐 根据不同的用户和需求&#xff0c;可以选择不同的套餐 普通版 1500元 1年 1个用户 支持Paypal/Stripe 不限制A站个数 不限制B站个数 不限制提交模式 订单管理 物流管理 风控管理 必要的网站数据处理 24小时远程协助 开始…

使用chatgpt过掉邮生活滑块记录 ob+wasm print参数

****## 邮生活滑块记录 地址 &#xff1a;‘aHR0cHM6Ly95b3VzaGVuZ2h1by4xMTE4NS5jbi93eC8jL2xheGluUmVnaXN0P3VzZXJJZD0yMTA1NTQ2MTYxOSZhY3Rpdml0eUlkPTI4MiZydWxlSWQ9Mjg’ 如图 如上图 大概就这点参数 基本都是前面请求拿的 除了print enmiid 。。。。。。 结果&#xff1…

连续支付(周期扣款)功能开发及注意事项

最近有一个版本需求&#xff0c;需要接入周期扣款做连续会员的功能&#xff0c;没想到这一做就是小半个月&#xff0c;趟了很多坑&#xff0c;所以觉得有必要记录一下 1.周期扣款总体设计 在支付宝和微信中&#xff08;非苹果支付&#xff09;&#xff0c;周期扣款的流程主要有…

证监会计算机类笔试上岸经验,公务员考试笔试166分上岸经验(全干货)

原标题&#xff1a;公务员考试笔试166分上岸经验(全干货) 一、考前自审 1、具备公务员考试需要的相关知识结构与基本素质(70%)。包括政治素质(理解和掌握国家大政方针与政策)&#xff0c;基本科学素质&#xff0c;常识&#xff0c;阅读理解能力&#xff0c;语言功底&#xff0c…

行政职业能力测试软件,公务员行政职业能力测试考试宝典

公务员行政职业能力考试宝典是一款通用的考试练习软件&#xff0c;丰富的题库&#xff0c;包含历年真题和模拟试题&#xff0c;有时间就可以开启刷题模式&#xff0c;对于错误的题目可以进行错题重做、解题思路介绍、统计分析等&#xff0c;达到熟练的程度&#xff0c;大大提高…

一政网是真实助公考上岸的吗?

在当下的经济时代&#xff0c;需要不断的学习&#xff0c;不断的提升自我。报考公务员考试成为了不二选择。报考公务员考试成为了毕业生、在职员工、宝妈等等众多不同类型人的最佳选择。但是公务员考试的难度大&#xff0c;想要公考一次上岸&#xff0c;那么就必需选择报班学习…

2021四川紧急选调/国考备考策略----申论/行测(2020.8.22号开始)

文章目录 1 申论1.1 申论题型1.2 申论备考策略1.3 申论做题顺序及复习阶段 2 行测备考2.1 行测题型2.2 行测备考策略 3 参考资料 1 申论 1.1 申论题型 申论部分一共有五大题型(归纳概括、提出措施、综合分析、公文写作、大作文) 1.2 申论备考策略 这五个题型在国考中是一样…

公务员考试要求及流程梳理

背景 虽然我不考, 但考公这么热门, 在信息层面不能落伍. 本文以 浙江2023省考 (考试时间在2022年12月) 为例, 主要梳理 怎么报名, 选职位, 考试科目与题型, 录用流程等. 为什么考公/考编这么热 因为当下的社会环境对员工太不友好了: 工作强度大, 精神压力大, 还有硬性比例淘…

基于JavaWeb的事业单位公务员招考信息发布平台-考务考试报名系统

本文介绍了使用Java技术开发公务员招考信息发布平台的设计与实现过程&#xff0c;首先对实现该系统的技术进行分析&#xff0c;说明选择Java和MySQL数据库的必要性&#xff0c;然后对公务员招考信息发布平台的需求进行分析。并接着对系统进行设计&#xff0c;包括架构设计、功能…

OpenAI发布了GPT的最新一代版本ChatGPT-4

今日凌晨&#xff0c;OpenAI发布了GPT的最新一代版本ChatGPT-4&#xff0c;相比上一代&#xff0c;其AI能力再度提升&#xff0c;同时支持输入的内容不再仅限于文字&#xff0c;而且支持图像内容的输入&#xff0c;成为一个能够理解照片的人工智能。 其AI能力的恐怖之处体现在哪…

chatgpt赋能python:Python循环暂停和继续的方法

Python循环暂停和继续的方法 Python是一种高级编程语言&#xff0c;在编程中使用循环结构非常常见。很多情况下&#xff0c;我们需要在循环中暂停或者继续执行。在本文中&#xff0c;我们将介绍如何在Python中实现循环暂停和继续的方法。 循环暂停和继续的意义 在Python编程…