history shell perl caching Draggabilly android项目实战 linux查看mysql进程 bitlocker加密好慢 ai如何导出矢量图 完美解决cpu利用率低 python基础语法 python语言编程入门 python调用自定义函数 python排序 java日期 java文件重命名 java成员变量 java将数据写入文件 java查看变量类型 phpqrcode 手机照片恢复免费软件 kms神龙 vnc客户端 dvwa安装教程 videoview 主播音效 ps二寸照片制作教程 dw网页设计教程 vue数组更新 数码管字体 电子海图 qq提取安装文件失败 如何用ps美白皮肤 pr特效插件 脚本怎么写 软件编程代码 java学生管理系统 天天手游模拟器 列转行 cad特性
当前位置: 首页 > 学习教程  > python

Python-房天下二手房信息

2021/2/8 12:35:31 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

前一阵子在学爬虫,所以就想试试爬房天下二手房的信息。 主要用到的库是requests,整理数据用的lxml 1)获取城市列表 其实如果是单个城市的话,可以看到某个城市的二手房链接是https://城市名称每个拼音的首字符.esf.fang.com,但是…

前一阵子在学爬虫,所以就想试试爬房天下二手房的信息。

主要用到的库是requests,整理数据用的lxml

1)获取城市列表

其实如果是单个城市的话,可以看到某个城市的二手房链接是https://城市名称每个拼音的首字符.esf.fang.com,但是想着要不就把所有的城市对应的链接爬下来,之后输入城市名称就可以。

    #########################################
    # 获取城市列表
    #########################################
    def GetCityList(self,newhouseoresf):
        url = "https://esf.fang.com/esfcities.aspx"

        if newhouseoresf =="二手房":
            housetype = "esf"
        else:
            housetype = "newhouse"
        pass
        # 发送请求
        response  = requests.get(url)
        
        html_base = etree.HTML(response.text)
        # 首字母个数
        tobodyszm = html_base.xpath("//div[@class='letterSelt']/div[3]/ul/li/strong")

        szmnum    = len(tobodyszm)
        citydict  = {}
        print('获取城市列表...')
        for szm in range(1,szmnum+1):
            # 首字母下每个字母的城市个数
            tobody  = html_base.xpath("//div[@class='letterSelt']/div[3]/ul/li[%d]/a" %szm)
            citynum = len(tobody)
            # 获取城市名称以及城市链接,字典存储
            for csgs in range(citynum):
                fang = tobody[csgs].get('href').split('esf')
                citydict[tobody[csgs].text] = "https:" + fang[0] + housetype + fang[1]
                # print(tobody[csgs].text,tobody[csgs].get('href'))
            pass
        pass
        return citydict
    pass

输出:

2)爬取筛选条件id

因为我只是想自己爬来看看,不是要爬取某个城市全部的信息,所以我就想加些筛选条件会更好,感觉更实用点?如果选取一些条件可以看到链接的变化,会在后面加上一些类似id的东西。

 #########################################
    # 获取筛选条件列表
    #########################################
    def getconditlist(self,cityname,newhouseoresf):

        cityname = cityname.replace('市','')
        cityurl  = self.GetCityList(newhouseoresf)[cityname]
        response = requests.get(cityurl)
        # 将响应转为html格式
        html_base = etree.HTML(response.text)
        print('获取筛选条件...')
        conditiondict = {}
        # 条件个数,包括区域、总价、面积等条件
        for id in ['ri010','ri011']:
            tobodyqx = html_base.xpath("//div[@id='%s']/div[1]/ul/li/span" %id)
            conditqx = {}
            for i in range(1,len(tobodyqx)+1):
                tempdict = {}
                a_html = html_base.xpath("//div[@id='%s']/div[1]/ul/li[%d]/ul/li" %(id,i))
                if tobodyqx[i-1].text in  ['区域','地铁']:
                    for ai in range(1,len(a_html) + 1):
                        # a_html = html_base.xpath("//div[@id='ri010']/div[1]/ul/li[1]/ul/li")
                        a_info = html_base.xpath("//div[@id='%s']/div[1]/ul/li[%d]/ul/li[%d]/a" %(id,i,ai))
                        value = a_info[0].get('href').replace('/house/','').replace('/house-','').replace('/house1/','').replace('/house1-','')
                        tempdict[a_info[0].text] = value
                elif tobodyqx[i-1].text in ['总价','面积']:
                    for ai in range(1,len(a_html)):
                        a_info = html_base.xpath("//div[@id='%s']/div[1]/ul/li[%d]/ul/li[%d]/label/a" % (id,i, ai))
                        value = a_info[0].get('href').replace('/house/', '').replace('/house-', '').replace('/house1/','').replace('/house1-', '')
                        tempdict[a_info[0].text] = value
                else:
                    for ai in range(1,len(a_html)+1):
                        a_info = html_base.xpath("//div[@id='%s']/div[1]/ul/li[%d]/ul/li[%d]/label/a" % (id,i, ai))
                        value = a_info[0].get('href').replace('/house/', '').replace('/house-', '').replace('/house1/','').replace('/house1-', '')
                        tempdict[a_info[0].text] = value
                pass
                conditqx[tobodyqx[i-1].text] = tempdict
            pass
            if id == 'ri010':
                key = '区域'
            else:
                key = '地铁'
            pass
            conditiondict[key] = conditqx
        pass
        # print(conditiondict)
        return conditiondict
    pass

输出:

3)处理重定向问题

可以见到,这里多了,在https://gz.esf.fang.com/chushou/3_251677053.htm?channel=2,2的的源代码中,可以看到,有这个东西,这就是调转后的链接。

r = requests.get('https://gz.esf.fang.com/chushou/3_251677053.htm?channel=2,2')
print(r.text)

 

    #########################################
    # 获取店铺链接,并将整理后的数据插入到本地数据库中
    #########################################
    def gethouseinf(self,cityname,newhouseoresf):

        # 拼接筛选链接
        cityurl = self.GetCityList(newhouseoresf)[cityname]
        condict = self.getconditlist(cityname,newhouseoresf)
        conditiondeal = {}
        for i in condict.keys():
            for j in condict[i]:
                if condict[i][j] == conditiondeal.get(j):
                    pass
                else:
                    conditiondeal[j] = condict[i][j]
                pass
            pass
        pass
        cond1 = input('\033[1;34m 请按照输入您的筛选选项[区域;地铁],默认选项是区县[输入文字],不选请按enter跳过 :  \033[0m')
        if len(cond1)!=0:
            pass
        else:
            cond1='区域'
        pass

        if cond1=='地铁':
            house = 'house1'
            print(conditiondeal['距离'].keys())
            cond2 = input('\033[1;34m 请输入以上地铁距离的选择,[输入文字],如不选,则enter跳过 : \033[0m')
        else :
            house = 'house'
            print(conditiondeal['区域'].keys())
            cond2 = input('\033[1;34m 请输入以上区域的选择,[输入文字],如不选,则enter跳过 : \033[0m')
        pass
        print(conditiondeal['总价'].keys())
        cond3 = input('\033[1;34m 请按照输入您预算的筛选选项,[输入文字],如不选,则enter跳过 : \033[0m')
        print(conditiondeal['户型'].keys())
        cond4 = input('\033[1;34m 请输入以上户型的选择,[输入文字],如不选,则enter跳过 : \033[0m')
        print(conditiondeal['面积'].keys())
        cond5 = input('\033[1;34m 请输入以上面积的选择,[输入文字],如不选,则enter跳过 : \033[0m')
        print(conditiondeal['来源'].keys())
        cond6 = input('\033[1;34m 请输入以上来源的选择,[输入文字],如不选,则enter跳过 : \033[0m')


        Url = cityurl + '/' + house+ '-' + str(conditiondeal.get(cond1).get(cond2)).replace('None','') \
              + str(str(conditiondeal.get('总价').get(cond3)).replace('None','') + str(conditiondeal.get('户型').get(cond4)).replace('None','') + \
              str(conditiondeal.get('面积').get(cond5)).replace('None','') ).replace('/','-') \
              + str(conditiondeal.get('来源').get(cond6)).replace('None', '')


        # 获取 页数
        print('开始爬取房屋信息...')
        location_href = self.pageurl(Url + 'i31')
        response1 = requests.get(location_href)
        response1_text = response1.text
        pageall = int(re.findall('共(\d+)页',response1_text)[0])
        print('共需要爬取%d 页' %pageall)
        # 第一页的房屋信息链接
        for page in range(1,pageall+1):

            print('正在爬取第%d 页' % page)
            # 1. 处理首页链接重定向问题
            location_page_href = self.pageurl(Url + 'i3' + str(page))
            time.sleep(random.randint(1,3))
            # 2. 处理房屋信息链接重定向问题
            houselist = self.gethouseurl(location_page_href)
            time.sleep(random.randint(1, 3))
            # 3. 提取房屋信息,并插入数据
            print('整合房屋信息...')
            for each_houseurl in houselist:
                self.log.info('现在整理的房屋链接是:%s' % each_houseurl)
                self.houseMessage(each_houseurl)
                time.sleep(random.randint(3,5))
            pass
            time.sleep(random.randint(10,20))
        pass
        
        return location_href
    ############### 处理页面链接重新向问题,获得页面的链接 #################
    def pageurl(self,conditionurl):
        response = requests.get(conditionurl)
        t4 = re.findall("t4=(.*?);", response.text)
        t3 = re.findall("t3=(.*?);", response.text)
        location_href = t4[0].replace('"', '').replace("'", "") + '?' + t3[0].replace('"', '').replace("'", "")
        return location_href
    pass
    ############### 处理房屋链接重新向问题,获得房屋信息的链接 #################
    def gethouseurl(self,pageurl):

        pagetext = requests.get(pageurl).text
        urllist = []
        texthtml = etree.HTML(pagetext)
        tobodygs = texthtml.xpath("//div[@class='shop_list shop_list_4']/dl")
        url = re.findall('(.*?)com', str(pageurl))[0] + 'com'
        for k in range(1,len(tobodygs)+1):
            try:
                tobody   = texthtml.xpath("//div[@class='shop_list shop_list_4']/dl[%d]/dt/a" %k)
                houseurl =  url + tobody[0].get('href') + '?channel=' + tobody[0].get('data_channel')
                time.sleep(1)
                houseresponse = requests.get(houseurl)
                t4 = re.findall("t4=(.*?);", houseresponse.text)
                t3 = re.findall("t3=(.*?);", houseresponse.text)
                hurl = t4[0].replace('"', '').replace("'", "") + '?' + t3[0].replace('"', '').replace("'", "")
                self.log.info('需要处理的房屋链接:%s' %hurl)
                urllist.append(hurl)
            except:
                print('重定向解析报错...')
                pass
            pass
        pass
        return urllist
    pass

 

4)整理房屋信息

    ########################### 获取房屋的基本信息 #########################
    def houseMessage(self,houseurl):

        r = requests.get(houseurl )
        html_base = etree.HTML(r.text)
        if 'captcha' in r.url:
            time.sleep(random.randint(1200,1300))
            r = requests.get(houseurl)
            html_base = etree.HTML(r.text)
        pass

        househx = self.ifnull(html_base.xpath("//div[@class='tr-line clearfix'][1]/div[1]/div[1]/text()"))   #户型
        housemj = self.ifnull(html_base.xpath("//div[@class='tr-line clearfix'][1]/div[2]/div[1]/text()")) #面积
        housedj = self.ifnull(html_base.xpath("//div[@class='tr-line clearfix'][1]/div[3]/div[1]/text()")) #单价
        housecx = self.ifnull(html_base.xpath("//div[@class='tr-line clearfix'][2]/div[1]/div[1]/text()")) # 朝向
        houselc = self.ifnull(html_base.xpath("//div[@class='tr-line clearfix'][2]/div[2]/div[1]/text()"))  #楼层
        houselc2 = self.ifnull(html_base.xpath("//div[@class='tr-line clearfix'][2]/div[2]/div[2]/text()")) # 楼层2
        housezx = self.ifnull(html_base.xpath("//div[@class='tr-line clearfix'][2]/div[3]/div[1]/text()")) #装修
        housexq = self.ifnull(html_base.xpath("//div[@class='trl-item2 clearfix'][1]/div[2]/a[1]/text()"))  #小区
        housedz1 = self.ifnull(html_base.xpath("//div[@class='trl-item2 clearfix'][2]/div[2]/a[1]/text()"))  #地址1
        housedz2 = self.ifnull(html_base.xpath("//div[@class='trl-item2 clearfix'][2]/div[2]/a[2]/text()"))  # 地址2

        # 房源信息
        housedcmc = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[1]/div[1]/span/span/span[1]/text()")) # 地产名称
        housejznd = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[1]/div[2]/div[1]/span[2]/text()")) # 建筑年代
        houseywnd = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[1]/div[2]/div[2]/span[2]/text()"))  # 有无电梯
        housecqxz = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[1]/div[2]/div[3]/span[2]/text()"))  # 产权性质
        housezzlb = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[1]/div[2]/div[4]/span[2]/text()"))  # 住宅类别
        housejzjg = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[1]/div[2]/div[5]/span[2]/text()"))  # 建筑结构
        housegpsj = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[1]/div[2]/div[6]/span[2]/text()"))  # 挂牌时间

        # 小区信息
        houseckjg = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[3]/div[2]/div[1]/div[1]/span[2]/i/text()")) #参考均价
        housetbsn = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[3]/div[2]/div[1]/div[2]/span[2]/em/text()")) #同比去年
        househbsy = self.ifnull(html_base.xpath("//div[@class='w1200 clearfix']/div[1]/div[3]/div[2]/div[1]/div[3]/span[2]/em/span/text()")) # 环比上月

        # 将数据写入本地数据库
        data = [househx, housemj, housedj, housecx, houselc + '[' + houselc2 + ']', housezx, housexq, housedz1, housedz2, \
          housedcmc,housejznd, houseywnd, housecqxz, housezzlb,housejzjg,housegpsj,houseckjg + '元/平米', housetbsn, \
         househbsy]
        print(data)
        self.insertdata(data)


        # print(househx, housemj, housedj, housecx, houselc, houselc2, housezx, housexq, housedz1, housedz2)
        # print(housedcmc, housejznd, houseywnd, housecqxz, housezzlb, housejzjg, housejgpsj)
        # print(houseckjg, housetbsn, househbsy)
    pass
    ####### 判断列表是为为空,空值则返回' ',否则返回本身 ########
    def ifnull(self,data):
        if len(data)==0:
            info = ' '
        else :
            info = data[0].strip()
        pass
        return info
    pass

5)结果

# 挂牌时间有点问题,应该是有些链接的结构有点不一样,但这不是我最关注的的,所以我也没再改了。

 

 

 


本文链接: http://www.dtmao.cc/news_show_2000344.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?