赞
踩
最近在学习用Python进行数据分析、机器学习,基本都是用现成数据集进行模型训练及验证,想用一些实际数据看一下效果,于是想到用Python尝试抓取一些实际数据。
目标:爬取链家网北京二手房房价、位置、面积等数据
环境:Python3.5.2,Anaconda4.2.0
首先,导入所需要的库,主要有urllib.request、BeautifulSoup、Pandas、Numpy、re。
from urllib.request import urlopen
from bs4 import BeautifulSoup
import pandas as pd
import numpy as np
import re
首先,了解一下目标网站的URL结构,例如 https://bj.lianjia.com/ershoufang/dongcheng/pg2/
例如,我们要抓取北京各个区二手房频道,所以前面城市、频道名称不会变,属于固定部分;后面的城区要遍历北京各个区(东城、西城、朝阳…),页码需要在1-所选城区总页数间变化,属于可变部分。将URL分为两部分,前面的固定部分赋值给url,后面的可变部分用双层for循环遍历,外层循环遍历城区,内层循环遍历所选城区的页面。其中,需要获取所选城区包含的总页数,提取div标签中class=page-box fr的第一个子标签属性page-data的值。
chengqu={'dongcheng':'东城区','xicheng':'西城区','chaoyang':'朝阳区','haidian':'海淀区','fengtai':'丰台区','shijingshan':'石景山区', 'tongzhou':'通州区','changping':'昌平区','daxing':'大兴区','shunyi':'顺义区','fangshan':'房山区'}
for cq in chengqu.keys():
url='https://bj.lianjia.com/ershoufang/'+cq+'/' #组成所选城区的URL
html=urlopen(url)
bsObj=BeautifulSoup(html) #解析抓取的页面内容
total_page=re.sub('\D','',bsObj.find('div','page-box fr').contents[0].attrs['page-data'])[:-1] #获取所选城区总页数
print ('total_page',total_page)
for j in np.arange(1,int(total_page)+1):
page_url=url+'pg'+str(j) #组成所选城区页面的URL
然后,使用BeautifulSoup对页面进行解析。
page_html=urlopen(page_url)
page_bsObj=BeautifulSoup(page_html)
接着,提取页面中的关键信息进行提取,主要对房屋信息、房屋位置、总价和单价进行提取。
依次把页面div标签中class为houseInfo、positionInfo、totalPrice、unitPrice的部分提取出来,用get_text()获取对应标签中的信息,其中houseInfo、positionInfo包含房屋的多种属性,用split()对其进行分列,只选取了houseInfo包含6个属性且positionInfo包含3个属性的数据。另外,对于单价用get_text()后得到“单价100748元/平米”,包含了文本和数字,用re.sub()正则匹配出数字部分。最后,依次把提取到的信息添加到对应列表中。
info=bsObj.findAll("div",{"class":"houseInfo"}) position_info=bsObj.findAll("div",{"class":"positionInfo"}) totalprice=bsObj.findAll("div",{"class":"totalPrice"}) unitprice=bsObj.findAll("div",{"class":"unitPrice"}) house_loc=[] #房屋所在小区 house_type=[] #房屋户型 house_area=[] #房屋面积 house_direction=[] #房屋朝向 house_decorating=[] #房屋装修 house_lift=[] #有无电梯 house_floor=[] #房屋楼层 house_year=[] #建造年份 house_position=[] #房屋位置 t_price=[] #房屋总价 u_price=[] #房屋单价 for i_info,i_pinfo,i_tp,i_up in zip(info,position_info,totalprice,unitprice): if len(i_info.get_text().split('/'))==6 and len(i_pinfo.get_text().split('/'))==3: #分列houseinfo并依次获取房屋所在小区、户型、面积、朝向、装修、有无电梯各字段 house_loc.append(i_info.get_text().split('/')[0]) house_type.append(i_info.get_text().split('/')[1]) house_area.append(i_info.get_text().split('/')[2][:-2]) house_direction.append(i_info.get_text().split('/')[3].replace(' ','')) house_decorating.append(i_info.get_text().split('/')[4]) house_lift.append(i_info.get_text().split('/')[5]) #分列positioninfo并依次获房屋楼层、建造年份、位置各字段 house_floor.append(i_pinfo.get_text().split('/')[0]) house_year.append(i_pinfo.get_text().split('/')[1][:5]) house_position.append(i_pinfo.get_text().split('/')[2]) #获取房屋总价和单价 t_price.append(i_tp.span.string) u_price.append(re.sub('\D','',i_up.get_text()))
将提取的数据导入pandas之中生成数据表。
#将数据导入pandas之中生成数据表
house_data=pd.DataFrame()
house_data[u'城区']=[chengqu[cq]]*len(house_loc)
house_data[u'小区名称']=house_loc
house_data[u'房型']=house_type
house_data[u'面积']=house_area
house_data[u'朝向']=house_direction
house_data[u'装修']=house_decorating
house_data[u'有无电梯']=house_lift
house_data[u'楼层']=house_floor
house_data[u'建造年份']=house_year
house_data[u'位置']=house_position
house_data[u'总价']=t_price
house_data[u'单价']=u_price
print (house_data)
将数据存入到csv中,便于后续分析。
house_data.to_csv('house_bj.csv', mode='a', header=False,encoding='gb2312',index=None)
总共提取到北京11个区28560条二手房信息。
最后,附上完整代码~~
from urllib.request import urlopen from bs4 import BeautifulSoup import pandas as pd import numpy as np import re chengqu={'dongcheng':'东城区','xicheng':'西城区','chaoyang':'朝阳区','haidian':'海淀区','fengtai':'丰台区','shijingshan':'石景山区', 'tongzhou':'通州区','changping':'昌平区','daxing':'大兴区','shunyi':'顺义区','fangshan':'房山区'} for cq in chengqu.keys(): url='https://bj.lianjia.com/ershoufang/'+cq+'/' #组成所选城区的URL html=urlopen(url) bsObj=BeautifulSoup(html) total_page=re.sub('\D','',bsObj.find('div','page-box fr').contents[0].attrs['page-data'])[:-1] #获取所选城区总页数 print ('total_page',total_page) for j in np.arange(1,int(total_page)+1): page_url=url+'pg'+str(j) #组成所选城区页面的URL #print (page_url) page_html=urlopen(page_url) page_bsObj=BeautifulSoup(page_html) info=bsObj.findAll("div",{"class":"houseInfo"}) position_info=bsObj.findAll("div",{"class":"positionInfo"}) totalprice=bsObj.findAll("div",{"class":"totalPrice"}) unitprice=bsObj.findAll("div",{"class":"unitPrice"}) house_loc=[] #房屋所在小区 house_type=[] #房屋户型 house_area=[] #房屋面积 house_direction=[] #房屋朝向 house_decorating=[] #房屋装修 house_lift=[] #有无电梯 house_floor=[] #房屋楼层 house_year=[] #建造年份 house_position=[] #房屋位置 t_price=[] #房屋总价 u_price=[] #房屋单价 for i_info,i_pinfo,i_tp,i_up in zip(info,position_info,totalprice,unitprice): if len(i_info.get_text().split('/'))==6 and len(i_pinfo.get_text().split('/'))==3: #分列houseinfo并依次获取房屋所在小区、户型、面积、朝向、装修、有无电梯各字段 house_loc.append(i_info.get_text().split('/')[0]) house_type.append(i_info.get_text().split('/')[1]) house_area.append(i_info.get_text().split('/')[2][:-2]) house_direction.append(i_info.get_text().split('/')[3].replace(' ','')) house_decorating.append(i_info.get_text().split('/')[4]) house_lift.append(i_info.get_text().split('/')[5]) #分列positioninfo并依次获房屋楼层、建造年份、位置各字段 house_floor.append(i_pinfo.get_text().split('/')[0]) house_year.append(i_pinfo.get_text().split('/')[1][:5]) house_position.append(i_pinfo.get_text().split('/')[2]) #获取房屋总价和单价 t_price.append(i_tp.span.string) u_price.append(re.sub('\D','',i_up.get_text())) #将数据导入pandas之中生成数据表 house_data=pd.DataFrame() house_data[u'城区']=[chengqu[cq]]*len(house_loc) house_data[u'小区名称']=house_loc house_data[u'房型']=house_type house_data[u'面积']=house_area house_data[u'朝向']=house_direction house_data[u'装修']=house_decorating house_data[u'有无电梯']=house_lift house_data[u'楼层']=house_floor house_data[u'建造年份']=house_year house_data[u'位置']=house_position house_data[u'总价']=t_price house_data[u'单价']=u_price #print (house_data) #将数据存入到csv中,便于后续分析 house_data.to_csv('house_bj.csv', mode='a', header=False,encoding='gb2312',index=None)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。