【需求】

  爬取青岛市二手房源信息,要求包括房源基本信息、小区名称、总价、单价以及房源的经纬度信息。
  根据以上需求,进入青岛市二手房首页,如图1所示,进行页面分析:

图1

【页面分析】

  首先分析图1所示页面。可以看到青岛市二手房源共有30266条,按区分为市南、市北、李沧等10个区。同时房源列表中包含部分我们所需要的信息,但是并不完整。我们点击该房源进行详情页,如图2、图3所示。

图2

图3   这里需要注意的是该房源的经纬度信息并没有直接展示出来,F12查看页面源码,找找看。能找到万事大吉,找不到很有可能就不包含经纬度信息。

  这里有一个小技巧:首先百度一下青岛市的经纬度范围(东经119°30′~121°00′,北纬35°35′~37°09′),然后我们就可以在控制台源码中Ctrl+F搜索该范围内的经度、纬度,比如依次搜索119、120、121或35、36、37,如果该页面中包含经纬度信息则一定可以搜索到。这里我搜索到“120.”时就找到了貌似经纬度的信息,如图4所示,通过在线经纬度信息查询与该网站上所示的地理位置对比,确认了该信息就是房源对应的经纬度,然后我们可以利用正则表达式进行提取。

图4

【亟须解决的3个问题】

  上面找到了我们所需信息的页面,那每个房源详情页都对应一个URL,

  • 【问题1】如何获取所有房源的URL?

  回到青岛市二手房首页。爬虫必备【F12】一下,打开控制台。在控制台中,点击【选择元素】,选择标题时发现<a>标签中指向一个地址,如图5所示:

图5   然后我们打开这个地址,发现刚好是该房源的详情页 ,那么我们就可以获取每一个房源指向的详情页URL了。 【问题1】也就得到了解决。

  但是当我在图1所示的青岛市二手房页面中往下拉时发现房源信息以分页的形式展示,最多分为100页,每页最多30条,如图6所示:

图6   也就是说不能一股脑的去爬,这样最多只能获取100*30=3000条数据。

  • 【问题2】怎么解决分页的问题获取所有房源的URL?

  通过观察网页二手房首页可以看到,所有二手房源可以按位置、按售价、按面积、按房型等进行分类,如图7所示:

图7   我们再点击不同区看一下对应URL:

市南:https://qd.lianjia.com/ershoufang/shinan/
市北:https://qd.lianjia.com/ershoufang/shibei/
李沧:https://qd.lianjia.com/ershoufang/licang/

  然后发现不同区的URL是有规律的,仅仅是后面拼音不一样。
  这样就可以通过不同区进行爬取。为了最大化的获取数据,同时要求每个区的房源数也不能超过3000条,如果超过3000条,则可以在按区分类的同时,再按售价(或面积、房型等)进行更细的分类,以此类推。这里由于市南、市北等几个区的二手房源超过3000,所以在按区的同时还需要再按售价进行分类爬取(因此总共应分为80类,即10个区,每个区对应8类售价)。
  我们再点击不同的售价类型:
市南&80万以下   https://qd.lianjia.com/ershoufang/shinan/p1/
市南&80-100万万以下:https://qd.lianjia.com/ershoufang/shinan/p2/
市南&100-150万万以下:https://qd.lianjia.com/ershoufang/shinan/p3/

市北&80万以下:https://qd.lianjia.com/ershoufang/shibei/p1/
市北&80-100万万以下:https://qd.lianjia.com/ershoufang/shibei /p2/
市北&100-150万万以下:https://qd.lianjia.com/ershoufang/shibei /p3/

  这里发现同时按区和售价分类的URL也存在一定规律,即在按区分类的基础上添加页码p1表示第1也,p2表示第2页…….,因此同时按区和售价爬取是一个不错的方法。那么【问题2】也就得到了解决。
  有了获取某一页某一房源详情页URL的方法和获取同时按区和售价分类后的URL,就可以从每个分类后的URL中的每一页中依次获取所有房源详情页URL,但是这里需要解决每个分类后的URL中的分页问题。

  • 【问题3】怎么解决分类后的分页的问题而获取所有房源的URL?

  下面我们同时选择市南区和100-150万,页面列出了339条数据,被分为12页。
  然后我们一直单击下一页,观察URL的变化:
第1页:https://qd.lianjia.com/ershoufang/shinan/p3/
第2页:https://qd.lianjia.com/ershoufang/shinan/pg2p3/
第3页:https://qd.lianjia.com/ershoufang/shinan/pg3p3/

  这里我们发现同样存在规律,URL中p3表示第3类售价,即100-150万,除了第一页, pg2、pg3表示页码,通过这个规律我们就可以通过代码构造不同区不同售价不同页码的URL。那么【问题3】也就得到了解决。
  综上分析我们可以构造不同区不同售价不同页码上的所有房源详情页的URL,然后通过请求并解析该URL获取我们所需爬取的信息。

【撸起袖子开始干】

  爬虫框架:这里我采用自己比较熟悉的Selenium进行爬取,使用lxml库进行Html解析,另外需要chromedriver.exe自动化加载页面。
  需要的第三方python库:selenium、lxml、xlrd、xlwt
另外下载chromedriver.exe时要求chromedriver与所使用的谷歌浏览器版本对应,其对应关系及下载地址参考:Chrome与ChromeDriver版本对应参照表及下载地址

【爬取五部曲】

  下面直接贴代码,代码不难,具体自己看

【一步曲:获取不同区的URL】

def get_range_url():
#声明list用于存储不同区的urlrange_urls={}driver=get_chromedriver()driver.get(city_url)html = driver.page_sourceselector = etree.HTML(html)#获取青岛不同区对应的URLfor i in range(0,10):#青岛市分为10个区a_href=str(selector.xpath('//*[@class="position"]/dl[2]/dd/div[1]/div/a['+str(i+1)+']/@href')[0])#标签索引从1开始rangename=str(selector.xpath('//*[@class="position"]/dl[2]/dd/div[1]/div/a['+str(i+1)+']/text()')[0])range_url='https://qd.lianjia.com'+a_hrefrange_urls[rangename]=range_urlreturn range_urls

【二步曲:获取不同区不同售价的URL】

#根据已获取的不同区的URL,获取不同区不同售价的URL
def get_range_price_url():
#获取不同区的URL
range_urls=get_range_url()#声明字典用于存储不同区不同售价的URL,key为每个区名,value为该区对应的8个售价的url
range_price_urls={}for key in range_urls:range_url=range_urls[key]part_range_price_url=[]for i in range(1,9):#按售价分为8个区间,依次在按区的URL后增加p1/,p2/,...p8/range_price_url=range_url+'p'+str(i)+'/'part_range_price_url.append(range_price_url)range_price_urls[key]=part_range_price_urlreturn range_price_urls

【三步曲:获取不同区不同售价不同页的URL】

#根据已获取的不同区不同售价的URL,获取不同区不同售价不同页的URL,并将url写入excel中
def get_range_price_page_url():
#获取不同区不同售价的URL列表集合range_price_urls=get_range_price_url()
#声明字典用于存储不同区不同售价不同页的url,key为区名, value为每个区对应的不同售价不同页的url的list集合range_price_page_urls={}#创建workbook(即excel文件)workbook = xlwt.Workbook(encoding='utf-8')#创建g工作簿(即表)worksheet = workbook.add_sheet('Sheet1')count=0for key in range_price_urls:try:driver = get_chromedriver()except Exception:driver = get_chromedriver()part_range_price_urls=range_price_urls[key]for part_range_price_url in part_range_price_urls:#请求URL获取该页面中房源的个数,从而计算有多少页try:driver.get(part_range_price_url)except Exception:driver.get(part_range_price_url)#等待2秒,以便浏览器加载所有资源,受网速影响如果网站需要加载资源较多可能加载不完全time.sleep(2)html = driver.page_sourceselector = etree.HTML(html)
#根据不同区不同售价url页面中的总房源数(每页30天,最后一页不足30条)计算有多少页house_count=selector.xpath('//*[@class="resultDes clear"]/h2/span/text()')yushu = int(house_count[0]) % 30page_count = 0if (yushu is 0):page_count = int(int(house_count[0]) / 30)else:page_count = int(int(house_count[0]) / 30) + 1#part_range_price_page_urls=[]#构造不同区不同售价不同页码的URLfor i in range(0,page_count):range_price_page_url=''if (i is 0):range_price_page_url=part_range_price_urlelse:list_ss = part_range_price_url.split('/')url_priceId = list_ss[5]range_price_page_url = part_range_price_url.replace(url_priceId, 'pg' + str(i + 1) + url_priceId)#part_range_price_page_urls.append(range_price_page_url)#将每页的URL写如excel文件中worksheet.write(count,0, key)#第一列写入区worksheet.write(count,1, range_price_page_url)#第二列写入urlcount+=1print(str(count))driver.quit()workbook.save('range_price_page_urls.xls')print('OK')

  该函数运行结果将生成range_price_page_urls.xls文件,该文件中包含结果如图8所示:

图8

【四步曲:获取每个房源详情页的URL】

  该步骤首先读取步骤三中生成的excel文件,获取不同区不同售价不同页的URL,并依次请求每个URL,然后在请求页面中获取每页中房源的详情页,每页均按30个来处理,注意这里需要捕获异常,不满30个的情况将会出现IndexError,然后我们break即可。

def get_finall_urls():#读取get_range_price_page_url()生成的excel文件:range_price_page_urls.xlsdata = xlrd.open_workbook('range_price_page_urls.xls')table = data.sheets()[0]  # 通过索引顺序获取表#获取行数row_count=table.nrowsdriver = get_chromedriver()# 创建workbook(即excel文件)workbook = xlwt.Workbook(encoding='utf-8')# 创建g工作簿(即表)worksheet = workbook.add_sheet('Sheet1')count = 0for i in range(0,row_count):# 读取区名和url后发现该值形如:text:'区名'、text:'url',但excel文件中仅显示的为区名和url(这里原因我暂时没有仔细考虑)# 所以就用一个正则直接把区名和url给提取出来pattern = re.compile("text:'" + '(.*?)' + "'", re.S)rangename_temp=str(table.cell(i,0))rangename= pattern.findall(rangename_temp)[0]url_temp=str(table.cell(i,1))url = pattern.findall(url_temp)[0]try:driver.get(url)except Exception:driver.get(url)time.sleep(2)html = driver.page_sourceselector = etree.HTML(html)for j in range(0,30):try:finall_url = selector.xpath('//*[@class="sellListContent"]/li[' + str(j + 1) + ']/a/@href')[0]  # 某一个房源的详情页except Exception:breakworksheet.write(count, 0,rangename)  # 第一列写入区worksheet.write(count, 1,finall_url)  # 第二列写入urlcount+=1print(str(count)+'/30266')driver.quit()workbook.save('finall_urls.xls')print('OK')

  该函数运行结果将生成finall_urls.xls 文件,如图9所示包含30192条房源详情页的URL,和30266条相差73条原因可能是网络请求超时跳过了。

图9

【终曲:爬取每个房源的信息】

#爬取每一个房源详情页中的信息
def get_house_info():# 读取get_finall_urls()生成的excel文件:finall_urls.xlsdata = xlrd.open_workbook('finall_urls.xls')table = data.sheets()[0]  # 通过索引顺序获取表# 获取行数row_count = table.nrows# 启动一个driverdriver = get_chromedriver()f = open("qingdao.txt", 'w', encoding='utf-8')for i in range(0,row_count):#这里同样会出现get_finall_urls()函数中的问题,处理方法与其一样pattern = re.compile("text:'" + '(.*?)' + "'", re.S)rangename_temp=str(table.cell(i,0))rangename=pattern.findall(rangename_temp)[0]url_temp=str(table.cell(i,1))url=pattern.findall(url_temp)[0]try:driver.get(url)except Exception:driver.get(url)time.sleep(2)# 获取房源详情页面html=driver.page_source# 解析详情页  获取所需信息selector = etree.HTML(html)try:#获取总价total_price=selector.xpath('//*[@class="total"]/text()')[0]#获取单价unit_price=selector.xpath('//*[@class="unitPriceValue"]/text()')[0]#获取小区名称apartment_name = selector.xpath('//*[@class="communityName"]/a[1]/text()')[0]# 获取所在区域inrange= selector.xpath('//*[@class="info"]/a[2]/text()')[0]# 通过正则表达式匹配获取经纬度信息pattern = re.compile("resblockPosition:'" + '(.*?)' + "',", re.S)pos = pattern.findall(html)[0]lon=pos.split(',')[0]lat=pos.split(',')[1]#获取基本信息 ,包括以下13个基本属性#1.房屋户型house_type=selector.xpath('//*[@class="base"]/div[2]/ul/li[1]/text()')#2所在楼层floor=selector.xpath('//*[@class="base"]/div[2]/ul/li[2]/text()')[0]# 3建筑面积out_area = selector.xpath('//*[@class="base"]/div[2]/ul/li[3]/text()')[0]# 4户型结构house_stru = selector.xpath('//*[@class="base"]/div[2]/ul/li[4]/text()')[0]# 5套内面积in_area = selector.xpath('//*[@class="base"]/div[2]/ul/li[5]/text()')[0]# 6建筑类型build_type = selector.xpath('//*[@class="base"]/div[2]/ul/li[6]/text()')[0]# 7房屋朝向house_direc = selector.xpath('//*[@class="base"]/div[2]/ul/li[7]/text()')[0]# 8建筑结构bulid_stru = selector.xpath('//*[@class="base"]/div[2]/ul/li[8]/text()')[0]# 9装修情况decorate = selector.xpath('//*[@class="base"]/div[2]/ul/li[9]/text()')[0]# 10梯户比例ratio = selector.xpath('//*[@class="base"]/div[2]/ul/li[10]/text()')[0]# 11供暖方式heating = selector.xpath('//*[@class="base"]/div[2]/ul/li[11]/text()')[0]# 12配备电梯elevator = selector.xpath('//*[@class="base"]/div[2]/ul/li[12]/text()')[0]# 13产权年限age_limit = selector.xpath('//*[@class="base"]/div[2]/ul/li[13]/text()')[0]#获取交易属性 ,包括以下8个#1.挂牌时间pull_time=selector.xpath('//*[@class="transaction"]/div[2]/ul/li[1]/span[2]/text()')[0]#2交易权属deal_owner=selector.xpath('//*[@class="transaction"]/div[2]/ul/li[2]/span[2]/text()')[0]# 3上次交易lasttime = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[3]/span[2]/text()')[0]# 4房屋用途house_use = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[4]/span[2]/text()')[0]# 5房屋年限house_age = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[5]/span[2]/text()')[0]# 6产权所属right_owner = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[6]/span[2]/text()')[0]# 7抵押信息,这里存在换行符和空格,需要处理pledge_info = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[7]/span[2]/text()')[0].replace('\n','').replace(' ','')# 8房本备件house_part = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[8]/span[2]/text()')[0]except Exception:continue#将获取的所有信息写入文本文件中f.write("%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s"%(total_price,unit_price,apartment_name,inrange,lon,lat,house_type,floor,out_area,house_stru,in_area,build_type,house_direc,bulid_stru,decorate,ratio,heating,elevator,age_limit,pull_time,deal_owner,lasttime,house_use,house_age,right_owner,pledge_info,house_part))f.write('\n')print(str(i+1))f.close()print('OK')

【爬虫结果查看及数据可视化】

【数据查看】
  最终爬取28869条数据,不足30192的原因可能是网络异常或者获取相关信息不存在抛出异常时给跳过了,如下图10所示。

图10 注意事项:在爬取的过程中,可能会因为网络波动(或其它原因)致使chromedriver请求数据时出现请求超时的错误而终止程序,如图11所示,我使用异常捕获根本没用, 这里有哪位大神有好的解决办法可以告诉我一下,另外据说scrapy-splash不错,比selenium快,有时间我会学习一下。如果程序终止,如图12所示,更改红框处URL的起止索引继续往下爬取即可。

图11

图12

【数据可视化】
  将txt文本以@符号进行分割转为excel文件(保存为.xls的excel文件,因为【添加XY数据】只能识别.xls格式的excel文件,且经度、纬度两列单元格的格式需要为数值类型,为了数据的精确度小数点应设置为7位或以上),然后使用ArcGIS中的【添加XY数据】添加二手房源数据,并将其导出为shp格式。最后通过分级设色将房价分为10类,可视化结果如图13所示。

图13   另外我用同样的方法爬取了成都市的二手房信息,可视化结果如图14所示。

图14

【完整代码】

import xlrd
import xlwt
from lxml import etree
from selenium import webdriver
import re
import time
city_url='https://qd.lianjia.com/ershoufang/'
#实例化chromedriver
def get_chromedriver():#设置参数chrome_options = webdriver.ChromeOptions()chrome_options.add_argument('--headless')#控制是否显示浏览器,注释将显示#chrome_options.add_argument("--start-maximized")#控制浏览器运行时的窗口大小chrome_options.add_argument('--disable-gpu')driverpath = "E:\chromedriver.exe"#下载的chromedriver.exe的全路径#创建谷歌浏览器驱动对象,用于后续操作浏览器chromedriver = webdriver.Chrome(executable_path=driverpath, chrome_options=chrome_options)return chromedriver
#获取不同区的URL,参数为城市二手房首页的url,青岛的为:https://qd.lianjia.com/ershoufang/
def get_range_url():# 声明list用于存储不同区的urlrange_urls={}driver=get_chromedriver()driver.get(city_url)html = driver.page_sourceselector = etree.HTML(html)#获取青岛不同区对应的URLfor i in range(0,10):#青岛市分为10个区a_href=str(selector.xpath('//*[@class="position"]/dl[2]/dd/div[1]/div/a['+str(i+1)+']/@href')[0])#标签索引从1开始rangename=str(selector.xpath('//*[@class="position"]/dl[2]/dd/div[1]/div/a['+str(i+1)+']/text()')[0])range_url='https://qd.lianjia.com'+a_hrefrange_urls[rangename]=range_urlreturn range_urls
#根据已获取的不同区的URL,获取不同区不同售价的URL
def get_range_price_url():# 获取不同区的URLrange_urls = get_range_url()# 声明字典用于存储不同区不同售价的URL,key为每个区名,value为该区对应的8个售价的urlrange_price_urls={}for key in range_urls:range_url=range_urls[key]part_range_price_url=[]for i in range(1,9):#按售价分为8个区间,依次在按区的URL后增加p1/,p2/,...p8/range_price_url=range_url+'p'+str(i)+'/'part_range_price_url.append(range_price_url)range_price_urls[key]=part_range_price_urlreturn range_price_urls
#根据已获取的不同区不同售价的URL,获取不同区不同售价不同页的URL,并将url写入excel中
def get_range_price_page_url():range_price_urls=get_range_price_url()range_price_page_urls={}#创建workbook(即excel文件)workbook = xlwt.Workbook(encoding='utf-8')#创建g工作簿(即表)worksheet = workbook.add_sheet('Sheet1')count=0for key in range_price_urls:try:driver = get_chromedriver()except Exception:driver = get_chromedriver()part_range_price_urls=range_price_urls[key]for part_range_price_url in part_range_price_urls:#请求URL获取该页面中房源的个数,从而计算有多少页try:driver.get(part_range_price_url)except Exception:driver.get(part_range_price_url)#等待2秒,以便浏览器加载所有资源,受网速影响如果网站需要加载资源较多可能加载不完全time.sleep(2)html = driver.page_sourceselector = etree.HTML(html)#根据不同区不同售价url页面中的总房源数(每页30天,最后一页不足30条)计算有多少页house_count=selector.xpath('//*[@class="resultDes clear"]/h2/span/text()')yushu = int(house_count[0]) % 30#page_count = 0if (yushu is 0):page_count = int(int(house_count[0]) / 30)else:page_count = int(int(house_count[0]) / 30) + 1#part_range_price_page_urls=[]#构造不同区不同售价不同页码的URLfor i in range(0,page_count):#range_price_page_url=''if (i is 0):range_price_page_url=part_range_price_urlelse:list_ss = part_range_price_url.split('/')url_priceId = list_ss[5]range_price_page_url = part_range_price_url.replace(url_priceId, 'pg' + str(i + 1) + url_priceId)#part_range_price_page_urls.append(range_price_page_url)#将每页的URL写如excel文件中worksheet.write(count,0,key)#第一列写入区worksheet.write(count,1,range_price_page_url)#第二列写入urlcount+=1print(str(count))driver.quit()workbook.save('range_price_page_urls.xls')print('OK')
#获取每一个房源详情页的url
def get_finall_urls():#读取get_range_price_page_url()生成的excel文件:range_price_page_urls.xlsdata = xlrd.open_workbook('range_price_page_urls.xls')table = data.sheets()[0]  # 通过索引顺序获取表#获取行数row_count=table.nrowsdriver = get_chromedriver()# 创建workbook(即excel文件)workbook = xlwt.Workbook(encoding='utf-8')# 创建g工作簿(即表)worksheet = workbook.add_sheet('Sheet1')count = 0for i in range(0,row_count):# 读取区名和url后发现该值形如:text:'区名'、text:'url',但excel文件中仅显示的为区名和url(这里原因我暂时没有仔细考虑,可能是编码不一致的问题)# 所以就用一个正则直接把区名和url给提取出来pattern = re.compile("text:'" + '(.*?)' + "'", re.S)rangename_temp=str(table.cell(i,0))rangename= pattern.findall(rangename_temp)[0]url_temp=str(table.cell(i,1))url = pattern.findall(url_temp)[0]try:driver.get(url)except Exception:driver.get(url)time.sleep(2)html = driver.page_sourceselector = etree.HTML(html)for j in range(0,30):try:finall_url = selector.xpath('//*[@class="sellListContent"]/li[' + str(j + 1) + ']/a/@href')[0]  # 某一个房源的详情页except Exception:breakworksheet.write(count, 0,rangename)  # 第一列写入区worksheet.write(count, 1,finall_url)  # 第二列写入urlcount+=1print(str(count)+'/30266')driver.quit()workbook.save('finall_urls.xls')print('OK')
#爬取每一个房源详情页中的信息
def get_house_info():# 读取get_finall_urls()生成的excel文件:finall_urls.xlsdata = xlrd.open_workbook('finall_urls.xls')table = data.sheets()[0]  # 通过索引顺序获取表# 获取行数row_count = table.nrows# 启动一个driverdriver = get_chromedriver()f = open("qingdao34"".txt", 'w', encoding='utf-8')for i in range(0,row_count):#这里同样会出现get_finall_urls()函数中的问题,处理方法与其一样pattern = re.compile("text:'" + '(.*?)' + "'", re.S)rangename_temp=str(table.cell(i,0))rangename=pattern.findall(rangename_temp)[0]url_temp=str(table.cell(i,1))url=pattern.findall(url_temp)[0]try:driver.get(url)except Exception:driver.get(url)time.sleep(2)# 获取房源详情页面html=driver.page_source# 解析详情页  获取所需信息selector = etree.HTML(html)try:#获取总价total_price=selector.xpath('//*[@class="total"]/text()')[0]#获取单价unit_price=selector.xpath('//*[@class="unitPriceValue"]/text()')[0]#获取小区名称apartment_name = selector.xpath('//*[@class="communityName"]/a[1]/text()')[0]# 获取所在区域inrange= selector.xpath('//*[@class="info"]/a[2]/text()')[0]# 通过正则表达式匹配获取经纬度信息pattern = re.compile("resblockPosition:'" + '(.*?)' + "',", re.S)pos = pattern.findall(html)[0]lon=pos.split(',')[0]lat=pos.split(',')[1]#获取基本信息 ,包括以下13个基本属性#1.房屋户型house_type=selector.xpath('//*[@class="base"]/div[2]/ul/li[1]/text()')#2所在楼层floor=selector.xpath('//*[@class="base"]/div[2]/ul/li[2]/text()')[0]# 3建筑面积out_area = selector.xpath('//*[@class="base"]/div[2]/ul/li[3]/text()')[0]# 4户型结构house_stru = selector.xpath('//*[@class="base"]/div[2]/ul/li[4]/text()')[0]# 5套内面积in_area = selector.xpath('//*[@class="base"]/div[2]/ul/li[5]/text()')[0]# 6建筑类型build_type = selector.xpath('//*[@class="base"]/div[2]/ul/li[6]/text()')[0]# 7房屋朝向house_direc = selector.xpath('//*[@class="base"]/div[2]/ul/li[7]/text()')[0]# 8建筑结构bulid_stru = selector.xpath('//*[@class="base"]/div[2]/ul/li[8]/text()')[0]# 9装修情况decorate = selector.xpath('//*[@class="base"]/div[2]/ul/li[9]/text()')[0]# 10梯户比例ratio = selector.xpath('//*[@class="base"]/div[2]/ul/li[10]/text()')[0]# 11供暖方式heating = selector.xpath('//*[@class="base"]/div[2]/ul/li[11]/text()')[0]# 12配备电梯elevator = selector.xpath('//*[@class="base"]/div[2]/ul/li[12]/text()')[0]# 13产权年限age_limit = selector.xpath('//*[@class="base"]/div[2]/ul/li[13]/text()')[0]#获取交易属性 ,包括以下8个#1.挂牌时间pull_time=selector.xpath('//*[@class="transaction"]/div[2]/ul/li[1]/span[2]/text()')[0]#2交易权属deal_owner=selector.xpath('//*[@class="transaction"]/div[2]/ul/li[2]/span[2]/text()')[0]# 3上次交易lasttime = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[3]/span[2]/text()')[0]# 4房屋用途house_use = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[4]/span[2]/text()')[0]# 5房屋年限house_age = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[5]/span[2]/text()')[0]# 6产权所属right_owner = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[6]/span[2]/text()')[0]# 7抵押信息,这里存在换行符和空格,需要处理pledge_info = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[7]/span[2]/text()')[0].replace('\n','').replace(' ','')# 8房本备件house_part = selector.xpath('//*[@class="transaction"]/div[2]/ul/li[8]/span[2]/text()')[0]except Exception:continue#将获取的所有信息写入文本文件中f.write("%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s@%s"%(total_price,unit_price,apartment_name,inrange,lon,lat,house_type,floor,out_area,house_stru,in_area,build_type,house_direc,bulid_stru,decorate,ratio,heating,elevator,age_limit,pull_time,deal_owner,lasttime,house_use,house_age,right_owner,pledge_info,house_part))f.write('\n')print(str(i+1))f.close()print('OK')
def main():#get_range_price_page_url()#调用一次即可,生成的excel文件range_price_page_urls.xls,将在get_finall_urls()中使用#get_finall_urls()#调用一次即可,生成的excel文件finall_urls.xls,将在get_house_info()中使用get_house_info()
if __name__=='__main__':main()

Selenium+ChromeDriver爬取链家网二手房价(包括经纬度)信息相关推荐

  1. 多进程+多线程爬取链家武汉二手房价

    因为数据分析的需要,就写了爬取链家武汉的数据.因为用scrapy框架感觉太慢了,就自己写了个多进程同步执行的代码. 1.数据量:20000+ 2.程序环境:Python3.6--->用的Anac ...

  2. Python爬虫攻略(2)Selenium+多线程爬取链家网二手房信息

    申明:本文对爬取的数据仅做学习使用,请勿使用爬取的数据做任何商业活动,侵删 前戏 安装Selenium: pip install selenium 如果下载速度较慢, 推荐使用国内源: pip ins ...

  3. 基于python多线程和Scrapy爬取链家网房价成交信息

    文章目录 知识背景 Scrapy- spider 爬虫框架 SQLite数据库 python多线程 爬取流程详解 爬取房价信息 封装数据库类,方便多线程操作 数据库插入操作 构建爬虫爬取数据 基于百度 ...

  4. python+selenium爬取链家网房源信息并保存至csv

    python+selenium爬取链家网房源信息并保存至csv 抓取的信息有:房源', '详细信息', '价格','楼层', '有无电梯 import csv from selenium import ...

  5. Scrapy实战篇(一)之爬取链家网成交房源数据(上)

    今天,我们就以链家网南京地区为例,来学习爬取链家网的成交房源数据. 这里推荐使用火狐浏览器,并且安装firebug和firepath两款插件,你会发现,这两款插件会给我们后续的数据提取带来很大的方便. ...

  6. python爬房源信息_用python爬取链家网的二手房信息

    题外话:这几天用python做题,算是有头有尾地完成了.这两天会抽空把我的思路和方法,还有代码贴出来,供python的初学者参考.我python的实战经历不多,所以代码也是简单易懂的那种.当然过程中还 ...

  7. python爬取链家新房_Python爬虫实战:爬取链家网二手房数据

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 买房装修,是每个人都要经历的重要事情之一.相对于新房交易市场来说,如今的二手房交易市场一点也 ...

  8. python爬取链家网的房屋数据

    python爬取链家网的房屋数据 爬取内容 爬取源网站 爬取内容 爬取思路 爬取的数据 代码 获取房屋url 获取房屋具体信息 爬取内容 爬取源网站 北京二手房 https://bj.lianjia. ...

  9. 【爬虫】爬取链家网青城山二手房源信息

    一.项目背景 本项目是用python爬虫来实现爬取链家网青城山的二手房信息,我们小组是针对于在我们成都东软学院周边的二手房信息做一个数据爬取和建表.我们小组做这个项目的背景是因为在不久的将来,我们大学 ...

最新文章

  1. python控制手机发短信_python-在python3中使用容联云通讯发送短信验证码
  2. 牛客-Forsaken喜欢独一无二的树【并查集,最小生成树】
  3. NXP UWB NCJ29D5开发(一)环境搭建
  4. 华为S1720, S2700, S5700, S6720 V200R010C00 产品文档
  5. 2021年河南省高考成绩位次查询,2021年河南高考分数一分一段位次表,河南高考个人成绩排名查询方法...
  6. div p span的用法和区别
  7. iphone按钮圆角的问题
  8. Laravel User Agent 轻松识别客户端(微信)信息(2019版)
  9. 金融行业相关知识点整理
  10. 电商产品设计:如何设计产品分销体系
  11. 工作笔记-thingworx连接mongdb
  12. NFS服务器配置与管理笔记
  13. Linux0.11内核--进程的调度(就绪态和运行态之间的转换)
  14. CTFshowWeb入门nodejs
  15. 作为一名java开发人员,不了解jvm调优对工作有什么影响?
  16. 海康威视工程师谈嵌入式软件
  17. 使用Arduino实现JDY-40无线模块的通信
  18. android 9.0 添加自定义恢复出厂设置标识
  19. React Native集成友盟推送
  20. SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@xxx] was not registered for synchro

热门文章

  1. 【Windows】快捷添加鼠标右键的菜单项
  2. 【计算机图形学】流体模拟渲染基础
  3. 财务内部收益率用计算机怎么算,财务内部收益率EXCEL怎么计算
  4. ESP32之 ESP-IDF 教学(十三)—— 分区表
  5. iOS 非越狱下的代码注入
  6. Flutter之Toast
  7. java截取视频第几秒与另一个秒之间生成gif
  8. [Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例
  9. 01-2016.07-小学期游戏开发《坦克大战》
  10. 交换机Access模式和Trunk模式配置演示