├── source ├── __init__.py ├── common.py ├── read.py ├── template.py ├── lianjia.py ├── beike.py ├── report.py └── save.py ├── config.ini ├── README.md ├── new_house.py └── reports └── 新房价格情况统计20200605.html /source/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | ;MySQL parameters 2 | [mysql] 3 | host = localhost 4 | port = 3306 5 | user = lv 6 | passwd = lv 7 | db = lvdb 8 | 9 | ;leancloud parameters 10 | [leancloud] 11 | appid = tprA4QlLY29nvh5QmiWsNl0s-gzGzoHsz 12 | appkey = idYvbwv28UfweEIJJ01E8bBb 13 | masterkey = I_can_not_tell_you 14 | 15 | ;default mysql 16 | [savetype] 17 | type = mysql 18 | ;type = leancloud 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # new_house 2 | 此为新房数据,需要二手房数据的移步[house](https://github.com/tree-branch/house) 3 | 4 | 爬取贝壳找房、链家(、安居客、58同城未更新,用的人少的话就不更新了)的房源信息,便于广大未买房子的朋友们尽快成为房奴!!!Crawl the house informations of lianjia.com (anjvke.com, 58.com, ganji.com after the update), convenient for the majority of friends who did not buy the house as soon as to become the mortgage slave!!! 5 | 6 | ## 直接运行 7 | 修改config.ini内的mysql链接地址 8 | 9 | python3.0及以上版本 10 | 11 | python new_house.py 12 | 13 | 缺什么包就 pip install *** 14 | 15 | ## 个性化运行 16 | 此程序是把leancloud作为云数据库使用;在 https://leancloud.cn/ 内建立账号;修改config.ini为自己的App ID App KEY 17 | 18 | python new_house.py 19 | 20 | 修改house.py内贝壳找房等网站的网址,查询的限定条件需要能够保存在URL内,例如链家的排序也是可以保存在URL内的,一看例子你也应该就懂了,不懂的话就再看一遍,直接给我发邮件当然是最快的办法 :-)。 21 | 22 | ## 联系方式 23 | 有想说的联系:lm521299@sina.com 24 | 25 | ![](https://img-blog.csdnimg.cn/2020071510365879.png) 26 | 27 | # 希望发现不好用的时候邮件通知我一下,方便我尽快修改,谢谢 :-) 28 | ![](https://starchart.cc/tree-branch/new_house.svg) 29 | ↑看一下大家什么时候喜欢关注房源信息↑ 30 | -------------------------------------------------------------------------------- /source/common.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | # python3.0 3 | import urllib.request 4 | 5 | # 定义一个getHtml()函数 6 | def getHtml(url): 7 | # HEADERS = {'cookie':'als=0; sessid=E20EF245-B578-B62A-405F-2E2EC80DD166; ajk_boostup_captcha=0e5106912b04695c71d190f8987ebf1a; ajk_member_captcha=6f503b9a45c529f8f1e53c34c8705def; search_words=%E5%A4%A7%E6%9C%89%E6%81%AC%E5%9B%AD%E4%BA%8C%E6%9C%9F%7C%E5%93%88%E4%BD%9B%E6%98%A0%E5%83%8F%7C%E5%A4%A7%E6%9C%89%E6%81%AC%E5%9B%AD; viewed_comm_21=212476_512034_538146_212341_212176; viewed_comm_list=212511_212476_512034_538146_212341_212176; ajk_member_name=%E8%80%80%E4%B8%AD; ajk_member_key=146c25ce41adc687f802173e10684b46; ajk_member_time=1519886340; aQQ_ajkauthinfos=X%2BvioYvshCNej0r1lQljTMj209xwrTWPFZHr4fU%2BBOVshg2FIa%2FwG804Z%2F5D0RBECPh2dBsrAQ; lui=34603604%3A1; ajk_member_id=34603604; lps=http%3A%2F%2Fdalian.anjuke.com%2F%7C; ctid=21; chatconf=0.1488850300876.2017094.755457675.2005134818.21; browse_comm_ids=512034%7C512033; propertys=chs2vf-omfh2s_cg0a1c-omfbnv_; 58tj_uuid=6bf94a05-49db-441c-a82b-7c6f0fd10568; new_session=0; init_refer=; new_uv=4; __xsptplusUT_8=1; _ga=GA1.2.846449226.1488850146; _gat=1; __xsptplus8=8.4.1488863765.1488864393.3%234%7C%7C%7C%7C%7C%23%23sBxkSJUmyzzeOfmsql0wujs4qe1wUNkI%23; aQQ_ajkguid=81A92F38-8AFB-3CD1-F259-78F93B4E9AE5; twe=2',} 8 | HEADERS = { 9 | 'User-Agent': 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'} 10 | HEADERS = {'User-Agent': 'User-Agent:Mozilla/5.0'} 11 | req = urllib.request.Request(url, headers=HEADERS) 12 | page = urllib.request.urlopen(req) # urllib.urlopen()方法用于打开一个URL地址 13 | html = page.read() # read()方法用于读取URL上的数据 14 | return html.decode('UTF-8').replace(u'\xa9', u'').replace("'", "").replace("\r\n", "").replace("\n", "") # 汉字转换及正则匹配无法对换行进行处理及去掉单引号 15 | -------------------------------------------------------------------------------- /new_house.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | # python3.0 3 | 4 | from source.save import saveData 5 | from source.common import getHtml 6 | from source.report import reportData 7 | import configparser 8 | import webbrowser 9 | import os 10 | 11 | 12 | # ------主函数------ 13 | # delete() 14 | if __name__ == '__main__': 15 | # 获取参数 16 | config = configparser.ConfigParser() 17 | config.read("config.ini") 18 | 19 | # 清除数据 20 | save = saveData(config) 21 | save.deleteOldData() 22 | 23 | # 贝壳找房 (例:北京、大兴 2居3居4居) 根据自己需求添加链接 24 | beike1 = getHtml('''https://bj.fang.ke.com/loupan/daxing/l2l3l4pg4/#daxing''') 25 | beike2 = getHtml('''https://bj.fang.ke.com/loupan/daxing/l2l3l4pg2/#daxing''') 26 | beike3 = getHtml('''https://bj.fang.ke.com/loupan/daxing/l2l3l4pg3/#daxing''') 27 | beike_htmls = [beike1, beike2, beike3] 28 | for beike_html in beike_htmls: 29 | save.beike_save(beike_html) 30 | 31 | # 链家 (例:北京 昌平 朝阳 大兴) 根据自己需求添加链接 32 | lianjia1 = getHtml('''https://bj.fang.lianjia.com/loupan/changping-chaoyang-daxing/bp0ep2000nht1pg5/#daxing''') 33 | lianjia2 = getHtml('''https://bj.fang.lianjia.com/loupan/changping/nht1pg2/''') 34 | lianjia3 = getHtml('''https://bj.fang.lianjia.com/loupan/changping/nht1pg1/''') 35 | lianjia_htmls = [lianjia1, lianjia2, lianjia3] 36 | for lianjia_html in lianjia_htmls: 37 | save.lianjia_save(lianjia_html) 38 | 39 | # # 58同城 高新园区 80-120W 3室 精装修 40 | # tongcheng1 = getHtml('''http://bj.58.com/ershoufang/?PGTID=0d00000c-0000-099e-5f9d-eb7cd9b2d735&ClickID=1&huansuanyue=200_600&bunengdaikuan=0&area=60_100''') 41 | # tongcheng2 = getHtml('''http://bj.58.com/ershoufang/pn2/?huansuanyue=200_600&bunengdaikuan=0&area=60_100&PGTID=0d300000-0000-0b90-1e0b-bf894f74b13a&ClickID=1''') 42 | # tongcheng3 = getHtml('''http://bj.58.com/ershoufang/pn3/?huansuanyue=200_600&bunengdaikuan=0&area=60_100&PGTID=0d300000-0000-08f9-ba56-6673c850e2b8&ClickID=1''') 43 | # # print(str(tongcheng1.encode('GB18030'))) 44 | # tongcheng_htmls = [tongcheng1, tongcheng2, tongcheng3] 45 | # for tongcheng_html in tongcheng_htmls: 46 | # save.tongcheng_save(tongcheng_html) 47 | # 48 | # # 安居客 (例:北京 200-600万 60-100平 按最新排序) 根据自己需求添加链接 49 | # anjuke1 = getHtml('''https://beijing.anjuke.com/sale/o5/?from_area=60&to_area=100&from_price=200&to_price=600''') 50 | # anjuke2 = getHtml('''https://beijing.anjuke.com/sale/o5-p2/?from_area=60&to_area=100&from_price=200&to_price=600#filtersort''') 51 | # anjuke3 = getHtml('''https://beijing.anjuke.com/sale/o5-p3/?from_area=60&to_area=100&from_price=200&to_price=600#filtersort''') 52 | # anjuke_htmls = [anjuke1, anjuke2, anjuke3] 53 | # for anjuke_html in anjuke_htmls: 54 | # save.anjuke_save(anjuke_html) 55 | 56 | # # 赶集 高新园区 80-120W 3室 精装修 57 | # ganji1 = getHtml('''http://dl.ganji.com/fang5/gaoxinyuanqu/b80e120h3q2/''') 58 | # ganji2 = getHtml('''http://dl.ganji.com/fang5/gaoxinyuanqu/b80e120h3o2q2/''') 59 | # ganji3 = getHtml('''http://dl.ganji.com/fang5/gaoxinyuanqu/b80e120h3o3q2/''') 60 | # ganji_htmls = [ganji1, ganji2, ganji3] 61 | # for ganji_html in ganji_htmls: 62 | # ganji_save(ganji_html) 63 | 64 | print("生成报告中...") 65 | rep = reportData() 66 | reportFileName = rep.get_report() 67 | webbrowser.open('''file:///''' + os.path.dirname(__file__) + '''/reports/''' + reportFileName) 68 | 69 | print("OVER!!!") 70 | -------------------------------------------------------------------------------- /source/read.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | 3 | import configparser 4 | import time 5 | 6 | class readData(): 7 | ''' 8 | 用于读取数据 9 | ''' 10 | 11 | def __init__(self, config): 12 | self._config = config 13 | pass 14 | 15 | # 读取 leancloud 表名列表 16 | def _read_leancloud_tablenames(self): 17 | import requests 18 | url = 'https://tpra4qll.api.lncld.net/1.1/schemas' 19 | head = { 20 | "X-LC-Id": self._config['leancloud']['appid'], 21 | "X-LC-Key": self._config['leancloud']['masterkey'] + ',master' 22 | } 23 | response = requests.get(url, headers=head) 24 | tablenames = sorted(list(response.json().keys()), reverse=True) 25 | return tablenames 26 | 27 | # 读取 leancloud 表数据 28 | def _read_leancloud_data(self, tablename): 29 | import requests 30 | import pandas as pd 31 | 32 | url = 'https://tpra4qll.api.lncld.net/1.1/classes/' 33 | limit = 200 34 | skip = 0 35 | head = { 36 | "X-LC-Id": self._config['leancloud']['appid'], 37 | "X-LC-Key": self._config['leancloud']['appkey'], 38 | "Content-Type": "application/json" 39 | } 40 | sign = 1 41 | data = pd.DataFrame() 42 | while(sign): 43 | response = requests.get(url + str(tablename) + '?limit=' + str(limit) + '&skip=' + str(skip), headers=head) 44 | data = data.append(pd.DataFrame(response.json()["results"])) 45 | if len(response.json()["results"])==0: 46 | sign = 0 47 | skip = skip + limit 48 | data = data.drop_duplicates(['houseLink']) 49 | print(len(data)) 50 | return data 51 | 52 | # 读取 mysql 表名列表 53 | def _read_mysql_tablenames(self): 54 | import mysql.connector 55 | import pandas as pd 56 | 57 | host = self._config.get('mysql', 'host') 58 | port = self._config.getint('mysql', 'port') 59 | user = self._config.get('mysql', 'user') 60 | passwd = self._config.get('mysql', 'passwd') 61 | db = self._config.get('mysql', 'db') 62 | 63 | conn = mysql.connector.connect(host=host, user=user, password=passwd, database=db, port=port, use_unicode=True) 64 | get_tableNames_sql = """select table_name from information_schema.tables order by table_name DESC """ 65 | tablenames = pd.read_sql(get_tableNames_sql, conn).iloc[:, 0].tolist() 66 | 67 | return tablenames 68 | 69 | # 读取 mysql 表数据 70 | def _read_mysql_data(self, tablename): 71 | import mysql.connector 72 | import pandas as pd 73 | 74 | host = self._config.get('mysql', 'host') 75 | port = self._config.getint('mysql', 'port') 76 | user = self._config.get('mysql', 'user') 77 | passwd = self._config.get('mysql', 'passwd') 78 | db = self._config.get('mysql', 'db') 79 | 80 | conn = mysql.connector.connect(host=host, user=user, password=passwd, database=db, port=port, use_unicode=True) 81 | get_data_sql = """select * from %s""" % tablename 82 | data = pd.read_sql(get_data_sql, conn) 83 | 84 | return data 85 | 86 | def read_tablenames(self): 87 | if self._config['savetype']['type'] == 'mysql': 88 | return self._read_mysql_tablenames() 89 | elif self._config['savetype']['type'] == 'leancloud': 90 | return self._read_leancloud_tablenames() 91 | 92 | def read_data(self, tablename): 93 | if self._config['savetype']['type'] == 'mysql': 94 | return self._read_mysql_data(tablename) 95 | elif self._config['savetype']['type'] == 'leancloud': 96 | return self._read_leancloud_data(tablename) 97 | -------------------------------------------------------------------------------- /source/template.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | # python3.0 3 | 4 | html_temp = ''' 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 100 | 101 | 102 | 103 |
104 | 105 | 110 | %s 111 | %s 112 | %s 113 |
114 | 115 | 116 | ''' 117 | -------------------------------------------------------------------------------- /source/lianjia.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | 3 | from html.parser import HTMLParser 4 | 5 | class LianjiaParser(HTMLParser): 6 | def __init__(self): 7 | super().__init__() 8 | # 存储中间数据(链家为总房价与单价) 9 | self.span = "" 10 | # 小区名称 11 | self.houseName = [] 12 | # 小区地址 13 | self.villageName = [] 14 | # 小区介绍 15 | self.houseNote = [] 16 | # 总价 17 | self.houseTotlePrice = [] 18 | # 单价 19 | self.houseUnitPrice = [] 20 | # 房屋链接 21 | self.houseLink = [] 22 | # 第一张图片 23 | self.houseImg = [] 24 | # 用于标记数据类型 25 | self.flag = [] 26 | # url连接头 27 | self.urlHead = "" 28 | 29 | def feed(self, data): 30 | super().feed(data) 31 | # 校验数据个数是否统一 32 | size = len(self.houseName) 33 | if len(self.houseName) != size or len(self.villageName) != size or len(self.houseNote) != size \ 34 | or len(self.houseTotlePrice) != size or len(self.houseUnitPrice) != size or len(self.houseLink) != size \ 35 | or len(self.houseImg) != size: 36 | raise ValueError("数据个数不一致:houseName-" + str(len(self.houseName)) + ",villageName-" + str(len(self.villageName)) + 37 | ",houseNote-" + str(len(self.houseNote)) + ",houseTotlePrice-" + str(len(self.houseTotlePrice)) + 38 | ",houseUnitPrice-" + str(len(self.houseUnitPrice)) + ",houseLink-" + str(len(self.houseLink)) + 39 | ",houseImg-" + str(len(self.houseImg))) 40 | return self.houseName, self.villageName, self.houseNote, self.houseTotlePrice, self.houseUnitPrice, self.houseLink, self.houseImg 41 | 42 | def handle_starttag(self, tag, attrs): 43 | if tag == "a" and ("class", "on") in attrs: 44 | for attr in attrs: 45 | if attr[0] == "href": 46 | self.urlHead = attr[1] 47 | break 48 | elif tag == "a" and ("class", "resblock-img-wrapper ") in attrs: 49 | for attr in attrs: 50 | if attr[0] == "title": 51 | self.houseName.append(attr[1]) 52 | break 53 | for attr in attrs: 54 | if attr[0] == "href": 55 | self.houseLink.append(self.urlHead + attr[1]) 56 | break 57 | elif tag == "img" and ("class", "lj-lazy") in attrs: 58 | for attr in attrs: 59 | if attr[0] == "data-original": 60 | self.houseImg.append(attr[1]) 61 | break 62 | elif tag == "a" and ("data-xftrack", "10254") in attrs: 63 | self.flag.append("villageName") 64 | elif tag == "a" and ("class", "resblock-room") in attrs: 65 | self.flag.append("houseNote") 66 | self.houseNote.append('') 67 | elif tag == "span" and len(self.flag) > 0 and self.flag[-1] == "houseNote": 68 | self.flag.append("span") 69 | elif tag == "i" and ("class", "split") in attrs and len(self.flag) > 0 and self.flag[-1] == "houseNote": 70 | self.flag.append("span") 71 | elif tag == "div" and ("class", "main-price") in attrs: 72 | self.flag.append("housePrice") 73 | self.houseTotlePrice.append('') 74 | self.houseUnitPrice.append('') 75 | elif tag == "span" and len(self.flag) > 0 and self.flag[-1] == "housePrice": 76 | self.flag.append("span") 77 | elif tag == "div" and ("class", "second") in attrs: 78 | self.flag.append("div") 79 | elif tag == "div" and ("class", "resblock-follow") in attrs and len(self.flag) > 0 and self.flag[-1] == "housePrice": 80 | self.flag.pop() 81 | 82 | def handle_data(self, data): 83 | if len(self.flag) != 0: 84 | if self.flag[-1] == "span" and self.flag[-2] == "houseNote": 85 | self.houseNote[-1] = self.houseNote[-1] + data.replace(' ','') 86 | self.flag.pop() 87 | elif self.flag[-1] == "span" and self.flag[-2] == "housePrice": 88 | self.houseUnitPrice[-1] = self.houseUnitPrice[-1] + data.replace(' ','') 89 | self.flag.pop() 90 | elif self.flag[-1] == "div" and self.flag[-2] == "housePrice": 91 | self.houseTotlePrice[-1] = self.houseTotlePrice[-1] + data.replace(' ','') 92 | self.flag.pop() 93 | elif self.flag[-1] == "villageName": 94 | self.villageName.append(data) 95 | self.flag.pop() 96 | 97 | def handle_endtag(self, tag): 98 | if tag == "div" and len(self.flag) > 0 and self.flag[-1] == "houseNote": 99 | self.flag.pop() 100 | -------------------------------------------------------------------------------- /source/beike.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | 3 | from html.parser import HTMLParser 4 | 5 | class BeikeParser(HTMLParser): 6 | def __init__(self): 7 | super().__init__() 8 | # 存储中间数据(链家为总房价与单价) 9 | self.span = "" 10 | # 小区名称 11 | self.houseName = [] 12 | # 小区地址 13 | self.villageName = [] 14 | # 小区介绍 15 | self.houseNote = [] 16 | # 总价 17 | self.houseTotlePrice = [] 18 | # 单价 19 | self.houseUnitPrice = [] 20 | # 房屋链接 21 | self.houseLink = [] 22 | # 第一张图片 23 | self.houseImg = [] 24 | # 用于标记数据类型 25 | self.flag = [] 26 | # url连接头 27 | self.urlHead = "" 28 | self.sign = 0 29 | 30 | def feed(self, data): 31 | super().feed(data) 32 | # 校验数据个数是否统一 33 | size = len(self.houseName) 34 | if len(self.houseName) != size or len(self.villageName) != size or len(self.houseNote) != size \ 35 | or len(self.houseTotlePrice) != size or len(self.houseUnitPrice) != size or len(self.houseLink) != size \ 36 | or len(self.houseImg) != size: 37 | raise ValueError("数据个数不一致:houseName-" + str(len(self.houseName)) + ",villageName-" + str(len(self.villageName)) + 38 | ",houseNote-" + str(len(self.houseNote)) + ",houseTotlePrice-" + str(len(self.houseTotlePrice)) + 39 | ",houseUnitPrice-" + str(len(self.houseUnitPrice)) + ",houseLink-" + str(len(self.houseLink)) + 40 | ",houseImg-" + str(len(self.houseImg))) 41 | return self.houseName, self.villageName, self.houseNote, self.houseTotlePrice, self.houseUnitPrice, self.houseLink, self.houseImg 42 | 43 | def handle_starttag(self, tag, attrs): 44 | if self.urlHead == "" and tag == "a" and ("class", "") in attrs: 45 | for attr in attrs: 46 | if attr[0] == "href" and attr[1][-8:] == "/loupan/": 47 | self.urlHead = attr[1][:-8] 48 | break 49 | elif tag == "a" and ("class", "name ") in attrs: 50 | for attr in attrs: 51 | if attr[0] == "title": 52 | self.houseName.append(attr[1]) 53 | break 54 | for attr in attrs: 55 | if attr[0] == "href": 56 | self.houseLink.append(self.urlHead + attr[1]) 57 | break 58 | elif tag == "img" and ("class", "lj-lazy") in attrs: 59 | for attr in attrs: 60 | if attr[0] == "data-original": 61 | self.houseImg.append(attr[1]) 62 | break 63 | elif tag == "a" and ("class", "resblock-location") in attrs: 64 | for attr in attrs: 65 | if attr[0] == "title": 66 | self.villageName.append(attr[1]) 67 | break 68 | elif tag == "a" and ("class", "resblock-room") in attrs: 69 | self.flag.append("houseNote") 70 | self.houseNote.append('') 71 | elif tag == "span" and len(self.flag) > 0 and self.flag[-1] == "houseNote": 72 | self.flag.append("span") 73 | elif tag == "i" and ("class", "split") in attrs and len(self.flag) > 0 and self.flag[-1] == "houseNote": 74 | self.flag.append("span") 75 | elif tag == "div" and ("class", "main-price") in attrs: 76 | self.flag.append("housePrice") 77 | self.houseTotlePrice.append('') 78 | self.houseUnitPrice.append('') 79 | elif tag == "span" and len(self.flag) > 0 and self.flag[-1] == "housePrice": 80 | self.flag.append("span") 81 | elif tag == "div" and ("class", "second") in attrs: 82 | self.flag.append("div") 83 | elif tag == "div" and ("class", "resblock-follow") in attrs and len(self.flag) > 0 and self.flag[-1] == "housePrice": 84 | self.flag.pop() 85 | 86 | def handle_data(self, data): 87 | if len(self.flag) != 0: 88 | if self.flag[-1] == "span" and self.flag[-2] == "houseNote": 89 | self.houseNote[-1] = self.houseNote[-1] + data.replace(' ','') 90 | self.flag.pop() 91 | elif self.flag[-1] == "span" and self.flag[-2] == "housePrice": 92 | self.houseUnitPrice[-1] = self.houseUnitPrice[-1] + data.replace(' ','') 93 | self.flag.pop() 94 | elif self.flag[-1] == "div" and self.flag[-2] == "housePrice": 95 | self.houseTotlePrice[-1] = self.houseTotlePrice[-1] + data.replace(' ','') 96 | self.flag.pop() 97 | 98 | def handle_endtag(self, tag): 99 | if tag == "a" and len(self.flag) > 0 and self.flag[-1] == "houseNote": 100 | self.flag.pop() 101 | -------------------------------------------------------------------------------- /source/report.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | # python3.0 3 | import source.template as temp 4 | from .read import readData 5 | import time 6 | 7 | class reportData(): 8 | ''' 9 | 用于读取数据 10 | ''' 11 | 12 | def __init__(self, reportFileName=None): 13 | if reportFileName is None: 14 | self._reportFileName = '新房价格情况统计' + time.strftime('%Y%m%d', time.localtime(time.time())) 15 | else: 16 | self._reportFileName = reportFileName 17 | 18 | # 生成数据块 19 | def _get_table_label(self, id, day, newdata, olddata): 20 | import pandas as pd 21 | new = pd.DataFrame() 22 | down = pd.DataFrame() 23 | up = pd.DataFrame() 24 | other = pd.DataFrame() 25 | for index, row in newdata.iterrows(): 26 | if row.houseLink in olddata.houseLink.tolist(): 27 | if row.houseTotlePrice < olddata[olddata.houseLink == row.houseLink].houseTotlePrice.iloc[0]: 28 | down = down.append(row.append(pd.Series({'old_houseTotlePrice': olddata[olddata.houseLink == row.houseLink].houseTotlePrice.iloc[0]})), ignore_index=True) 29 | elif row.houseTotlePrice > olddata[olddata.houseLink == row.houseLink].houseTotlePrice.iloc[0]: 30 | up = up.append(row.append(pd.Series({'old_houseTotlePrice': olddata[olddata.houseLink == row.houseLink].houseTotlePrice.iloc[0]})), ignore_index=True) 31 | else: 32 | other = other.append(row.append(pd.Series({'old_houseTotlePrice': olddata[olddata.houseLink == row.houseLink].houseTotlePrice.iloc[0]})), ignore_index=True) 33 | else: 34 | new = new.append(row.append(pd.Series({'old_houseTotlePrice': '-'})), ignore_index=True) 35 | new['sign'] = '新增' 36 | down['sign'] = '下降' 37 | up['sign'] = '上升' 38 | other['sign'] = '不变' 39 | result = ''' 40 |

较上%s天

41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ''' % (day, id) 56 | result += self._get_tbody_label(new) 57 | result += self._get_tbody_label(down) 58 | result += self._get_tbody_label(up) 59 | result += self._get_tbody_label(other) 60 | result += ''' 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
升降标志房屋名房屋备注房屋总价房屋历史总价房屋单价小区名房屋链接来源网站
升降标志房屋名房屋备注房屋总价房屋历史总价房屋单价小区名房屋链接来源网站
''' 76 | return result 77 | 78 | def _get_tbody_label(self, data): 79 | result = '' 80 | for index, row in data.iterrows(): 81 | result += ''' 82 | 83 | %s 84 | %s 85 | %s 86 | %s 87 | %s 88 | %s 89 | %s 90 | %s 91 | %s 92 | '''% (row.sign, row.houseName, row.houseNote, row.houseTotlePrice, row.old_houseTotlePrice, row.houseUnitPrice, row.villageName, row.houseLink if row.houseLink[:4]=="http" else "http://" + row.houseLink, row.houseLink, row.webName) 93 | return result 94 | 95 | # 生成报告文件 96 | def get_report(self): 97 | import datetime 98 | import configparser 99 | import os 100 | 101 | start = time.perf_counter() 102 | # 获取参数 103 | config = configparser.ConfigParser() 104 | config.read("config.ini") 105 | 106 | # 时间差 107 | day1 = None 108 | day7 = None 109 | day30 = None 110 | 111 | # 表名 112 | tn0 = None 113 | tn1 = None 114 | tn7 = None 115 | tn30 = None 116 | 117 | # 数据 118 | data0 = None 119 | data1 = None 120 | data7 = None 121 | data30 = None 122 | 123 | # 获得所有表名 124 | read = readData(config) 125 | tablenames = read.read_tablenames() 126 | 127 | # 得到当天,一天前,一周前,一月前的表名 128 | day = 1 129 | while True: 130 | day = day - 1 131 | if day == -60: 132 | break 133 | res = None 134 | timestring = (datetime.datetime.now() + datetime.timedelta(days=day)).strftime('%Y%m%d') 135 | for tablename in tablenames: 136 | if tablename[4:12] == timestring: 137 | res = tablename 138 | break 139 | if res is not None: 140 | if day == 0: 141 | tn0 = res 142 | elif day > -7: 143 | tn1 = res 144 | day1 = day 145 | day = -6 146 | elif day > -15: 147 | tn7 = res 148 | day7 = day 149 | day = -29 150 | elif day > -60: 151 | tn30 = res 152 | day30 = day 153 | else: 154 | break 155 | elif day == 0: 156 | raise ValueError("当天数据不存在。") 157 | if tn0 is not None: 158 | # 得到当天的数据 159 | data0 = read.read_data(tn0) 160 | if tn1 is not None: 161 | # 得到day1天前的数据 162 | data1 = read.read_data(tn1) 163 | if tn7 is not None: 164 | # 得到day7天的数据 165 | data7 = read.read_data(tn7) 166 | if tn30 is not None: 167 | # 得到day30天的数据 168 | data30 = read.read_data(tn30) 169 | result1 = None 170 | result7 = None 171 | result30 = None 172 | if data1 is not None: 173 | # 较1天结果html 174 | result1 = self._get_table_label('day1', (-1)*day1, data0, data1) 175 | if data7 is not None: 176 | # 较7天结果html 177 | result7 = self._get_table_label('day7', (-1)*day7, data0, data7) 178 | if data30 is not None: 179 | # 较30天结果html 180 | result30 = self._get_table_label('day30', (-1)*day30, data0, data30) 181 | end = time.perf_counter() 182 | html = temp.html_temp % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), str(end-start) + 's', result1, result7, result30) 183 | 184 | os.makedirs(os.path.dirname(__file__) + '''/../reports/''', exist_ok=True) 185 | f = open(os.path.dirname(__file__) + '''/../reports/''' + self._reportFileName + '.html', 'wb') 186 | f.write(html.encode('utf-8')) 187 | 188 | return self._reportFileName + '.html' 189 | 190 | -------------------------------------------------------------------------------- /source/save.py: -------------------------------------------------------------------------------- 1 | # encoding:utf-8 2 | 3 | import configparser 4 | import time 5 | 6 | from .beike import BeikeParser 7 | # from .anjuke import AnjukeParser 8 | # from .ganji import GanjiParser 9 | from .lianjia import LianjiaParser 10 | # from .tongcheng import TongchengParser 11 | 12 | 13 | class saveData(): 14 | ''' 15 | 用于保存数据 16 | ''' 17 | 18 | def __init__(self, config): 19 | self._config = config 20 | pass 21 | 22 | # 清除leancloud数据 23 | def _delete_leancloud(self): 24 | import leancloud 25 | # 初始化leancloud 26 | leancloud.init(self._config['leancloud']['appid'], self._config['leancloud']['appkey']) 27 | # 开启日志 28 | # logging.basicConfig(level=logging.DEBUG) 29 | timestring = time.strftime('%Y%m%d%H', time.localtime(time.time())) 30 | tablename = 'TNew' + timestring + 'TheFutureOfHome' 31 | TestObject = leancloud.Object.extend(tablename) 32 | test_object = TestObject() 33 | test_object.destroy() 34 | 35 | # 保存到leancloud 36 | def _save_leancloud(self, webName, houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, 37 | houseImg): 38 | import leancloud 39 | # 初始化leancloud 40 | leancloud.init(self._config['leancloud']['appid'], self._config['leancloud']['appkey']) 41 | # 开启日志 42 | # logging.basicConfig(level=logging.DEBUG) 43 | timestring = time.strftime('%Y%m%d%H', time.localtime(time.time())) 44 | # import datetime 45 | # timestring = (datetime.datetime.now() - datetime.timedelta(hours=25)).strftime('%Y%m%d%H') 46 | tablename = 'TNew' + timestring + 'TheFutureOfHome' 47 | TestObject = leancloud.Object.extend(tablename) 48 | for i in range(0, len(houseName)): 49 | test_object = TestObject() 50 | test_object.set('webName', webName) 51 | test_object.set('houseName', houseName[i]) 52 | test_object.set('villageName', villageName[i]) 53 | test_object.set('houseNote', houseNote[i]) 54 | test_object.set('houseTotlePrice', houseTotlePrice[i]) 55 | test_object.set('houseUnitPrice', houseUnitPrice[i]) 56 | test_object.set('houseLink', houseLink[i]) 57 | test_object.set('houseImg', houseImg[i]) 58 | try: 59 | test_object.save() 60 | except: 61 | print( 62 | "webName:%s\nhouseName:%s\nvillageName:%s\nhouseNote:%s\nhouseTotlePrice:%s\nhouseUnitPrice:%s\nhouseLink:%s\nhouseImg:%s\n" % ( 63 | webName, houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, 64 | houseImg)) 65 | print(webName + ' saved ' + str(len(houseName)) + ' rows.') 66 | 67 | # 清理mysql数据 68 | def _delete_mysql(self): 69 | import pymysql 70 | # 用于忽略表已存在的警告 71 | import warnings 72 | warnings.filterwarnings("ignore") 73 | host = self._config.get('mysql', 'host') 74 | port = self._config.getint('mysql', 'port') 75 | user = self._config.get('mysql', 'user') 76 | passwd = self._config.get('mysql', 'passwd') 77 | db = self._config.get('mysql', 'db') 78 | 79 | conn = pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=db, charset='utf8') 80 | cursor = conn.cursor() 81 | timestring = time.strftime('%Y%m%d%H', time.localtime(time.time())) 82 | tablename = 'TNew' + timestring + 'TheFutureOfHome' 83 | drop_sql = """drop table IF EXISTS %s""" % (tablename) 84 | drop_rows = cursor.execute(drop_sql) 85 | print('delete ' + str(drop_rows) + ' rows.') 86 | 87 | conn.commit() 88 | cursor.close() 89 | conn.close() 90 | 91 | # 保存到mysql 92 | def _save_mysql(self, webName, houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, 93 | houseImg): 94 | import pymysql 95 | # 用于忽略表已存在的警告 96 | import warnings 97 | warnings.filterwarnings("ignore") 98 | host = self._config.get('mysql', 'host') 99 | port = self._config.getint('mysql', 'port') 100 | user = self._config.get('mysql', 'user') 101 | passwd = self._config.get('mysql', 'passwd') 102 | db = self._config.get('mysql', 'db') 103 | 104 | conn = pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=db, charset='utf8') 105 | cursor = conn.cursor() 106 | 107 | timestring = time.strftime('%Y%m%d%H', time.localtime(time.time())) 108 | tablename = 'TNew' + timestring + 'TheFutureOfHome' 109 | create_table_sql = """CREATE TABLE IF NOT EXISTS %s ( 110 | Id int auto_increment, 111 | webName varchar(255), 112 | houseName varchar(255), 113 | villageName varchar(255), 114 | houseNote varchar(255), 115 | houseTotlePrice varchar(255), 116 | houseUnitPrice varchar(255), 117 | houseLink varchar(255), 118 | houseImg varchar(255), 119 | primary key(Id) 120 | ) 121 | ENGINE=InnoDB DEFAULT CHARSET=utf8;""" % (tablename) 122 | cursor.execute(create_table_sql) 123 | 124 | insert_sql = """insert into %s (webName, houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg) values """ % ( 125 | tablename) 126 | for i in range(0, len(houseName)): 127 | if i == 0: 128 | insert_sql += """('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')""" % ( 129 | webName, houseName[i], villageName[i], houseNote[i], houseTotlePrice[i], houseUnitPrice[i], 130 | houseLink[i], houseImg[i]) 131 | else: 132 | insert_sql += """,('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')""" % ( 133 | webName, houseName[i], villageName[i], houseNote[i], houseTotlePrice[i], houseUnitPrice[i], 134 | houseLink[i], houseImg[i]) 135 | insert_sql += """;""" 136 | saved_rows = 0 137 | if len(houseName) > 0: 138 | try: 139 | saved_rows = cursor.execute(insert_sql) 140 | except: 141 | print(insert_sql) 142 | print(webName + ' saved ' + str(saved_rows) + ' rows.') 143 | conn.commit() 144 | cursor.close() 145 | conn.close() 146 | 147 | def deleteOldData(self): 148 | if self._config['savetype']['type'] == 'mysql': 149 | self._delete_mysql() 150 | elif self._config['savetype']['type'] == 'leancloud': 151 | self._delete_leancloud() 152 | 153 | def _saveData(self, *args): 154 | if self._config['savetype']['type'] == 'mysql': 155 | self._save_mysql(*args) 156 | elif self._config['savetype']['type'] == 'leancloud': 157 | self._save_leancloud(*args) 158 | 159 | # 贝壳找房 160 | def beike_save(self, html): 161 | beike = BeikeParser() 162 | houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg = beike.feed(html) 163 | self._saveData('贝壳', houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg) 164 | 165 | # 链家 166 | def lianjia_save(self, html): 167 | lianjia = LianjiaParser() 168 | houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg = lianjia.feed(html) 169 | self._saveData('链家', houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg) 170 | 171 | # # 58同城 172 | # def tongcheng_save(self, html): 173 | # tongcheng = TongchengParser() 174 | # houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg = tongcheng.feed(html) 175 | # self._saveData('58同城', houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg) 176 | # 177 | # # 安居客 178 | # def anjuke_save(self, html): 179 | # anjuke = AnjukeParser() 180 | # houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg = anjuke.feed(html) 181 | # self._saveData('安居客', houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg) 182 | # 183 | # # 赶集 184 | # def ganji_save(self, html): 185 | # ganji = GanjiParser() 186 | # houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg = ganji.feed(html) 187 | # self._saveData('赶集', houseName, villageName, houseNote, houseTotlePrice, houseUnitPrice, houseLink, houseImg) 188 | -------------------------------------------------------------------------------- /reports/新房价格情况统计20200605.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 22 | 97 | 98 | 99 | 100 |
101 | 102 | 107 | 108 |

较上1天

109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 |
升降标志房屋名房屋备注房屋总价房屋历史总价房屋单价小区名房屋链接来源网站
新增和悦春风户型:3室/4室建面82-107㎡总价273万/套-35000 元/平(均价)庞各庄镇瓜乡路与永兴河交汇处//bj.fang.ke.com/loupan/p_hycfbkzcf/贝壳
新增融创公园壹号总价268万/套-40000 元/平(均价)孙村公园西侧//bj.fang.ke.com/loupan/p_rcgyyhbkzwc/贝壳
新增首开璞瑅墅户型:3室/4室建面297-644㎡总价1600万/套-1600 万/套(总价)榆垡镇京开高速(106国道段)东侧、榆垡路北侧, 祥和街48号院//bj.fang.ke.com/loupan/p_skptsaakyo/贝壳
新增中南湾户型:2室/3室建面97-135㎡总价520万/套-53000 元/平(均价)五福堂北路与京福路交汇处//bj.fang.ke.com/loupan/p_aabep/贝壳
新增瀛海府户型:3室建面88㎡-52449 元/平(均价)黄亦路与京福路交叉口西南侧//bj.fang.ke.com/loupan/p_yhfaftku/贝壳
新增和成璟园户型:3室/4室/5室建面140-346㎡总价868万/套-63000 元/平(均价)三羊北街3号院//bj.fang.ke.com/loupan/p_hcyaaaev/贝壳
新增首开保利熙悦诚郡户型:3室/4室建面128-160㎡总价1000万/套-79000 元/平(均价)南四环榴乡桥与德贤路交汇处东南角800米处//bj.fang.ke.com/loupan/p_skblxycjaadqm/贝壳
新增北京城建海梓府户型:3室建面105-186㎡-800 万/套(总价)三海子东路与姜场街交汇处南150米, 四海路1号院//bj.fang.ke.com/loupan/p_bjcjhzfaaaql/贝壳
新增万和斐丽户型:1室/3室建面62-90㎡-52449 元/平(均价)经二路与瀛安街交叉口北200米//bj.fang.ke.com/loupan/p_whflbidvq/贝壳
新增金地悦风华户型:3室建面89-134㎡-55000 元/平(均价)广阳大街与春和路交口西南//bj.fang.ke.com/loupan/p_jdyfhbimds/贝壳
新增首开保利熙悦林语户型:3室/4室建面220-280㎡总价1100万/套-1100 万/套(总价)旧宫镇五环路与德贤路交叉口东150米//bj.fang.ke.com/loupan/p_skblxylybiead/贝壳
新增金融街金悦府户型:2室/3室建面83-129㎡总价412万/套-50000 元/平(均价)4号线义和庄地铁站往北400米//bj.fang.ke.com/loupan/p_jrjjyfbifbi/贝壳
新增颐璟万和户型:4室建面80-135㎡总价753万/套-55016 元/平(均价)新源大街4号线义和庄地铁向北约500米//bj.fang.ke.com/loupan/p_yjwhbimfy/贝壳
新增和悦华锦户型:3室/4室建面89-135㎡总价460万/套-52695 元/平(均价)博兴八路与兴海一街交叉口西南侧100米//bj.fang.ke.com/loupan/p_hyhjbimmj/贝壳
新增北京城建海梓府户型:4室/5室建面280-360㎡总价1400万/套-1400 万/套(总价)三海子东路与姜场街交汇处南150米//bj.fang.ke.com/loupan/p_aaizj/贝壳
新增中海云筑户型:3室建面89㎡总价340万/套-340 万/套(总价)京开高速庞各庄桥西1500米(庞各庄镇宏轩饺子馆儿对面)//bj.fang.ke.com/loupan/p_zhyzbixxw/贝壳
新增中海云筑户型:4室建面266㎡总价860万/套-750 万/套(总价)京开高速庞各庄桥西1500米,团结路北(庞各庄镇宏轩饺子馆儿对面)//bj.fang.ke.com/loupan/p_zhyzbixyb/贝壳
新增招商雍合府户型:2室/3室/4室建面84-131㎡总价460万/套-55800 元/平(均价)兴业大街与清源西路交汇处西南角(地铁4号线清源路站西侧800米)//bj.fang.ke.com/loupan/p_zsyhfbjgqz/贝壳
新增金隅·金麟府户型:3室/4室建面89-141㎡总价468万/套-52695 元/平(均价)博兴八路与兴海一街交叉口西北侧//bj.fang.ke.com/loupan/p_jylfbjgrj/贝壳
新增中海云熙户型:2室/3室建面76-89㎡总价309万/套-37700 元/平(均价)魏善庄新城南中轴路东侧500米//bj.fang.ke.com/loupan/p_zhyxbjjre/贝壳
新增大兴金茂悦户型:2室/3室/4室建面74-104㎡总价291万/套-37500 元/平(均价)南中轴与龙江路交汇处东300米(世界月季公园北500米)//bj.fang.ke.com/loupan/p_dxjmybjnud/贝壳
新增海晏春秋户型:4室建面307-393㎡总价1300万/套-52449 元/平(均价)灜安街与经二路交汇处西北角//bj.fang.ke.com/loupan/p_whflbjopc/贝壳
新增中铁华侨城和园户型:4室建面198-370㎡总价1350万/套-50000 元/平(均价)南五环南海子公园西侧约500米//bj.fang.ke.com/loupan/p_zthqchybkiwm/贝壳
新增金地旭辉·江山风华户型:3室/4室建面89-136㎡总价480万/套-55800 元/平(均价)地铁4号线清源路站西侧800米//bj.fang.ke.com/loupan/p_jdxhjsfhbkmaf/贝壳
新增金隅学府户型:2室/3室/4室建面82-139㎡总价374万/套-52695 元/平(均价)兴海路金隅学府//bj.fang.ke.com/loupan/p_jyxfbknry/贝壳
新增中国铁建国际公馆户型:2室/3室/4室建面80-150㎡总价365万/套-52590 元/平(均价)博兴十路中国铁建国际公馆//bj.fang.ke.com/loupan/p_zgtjgjggbknwp/贝壳
新增北京城建宽院国誉府户型:4室建面152-240㎡总价420万/套-31000 元/平(均价)南北大街北京城建宽院国誉府//bj.fang.ke.com/loupan/p_bjcjkygyfbkrog/贝壳
新增中海寰宇时代户型:2室/3室/4室建面70-112㎡总价374万/套-52449 元/平(均价)大兴区瀛昌街与经二路交叉口东北150米//bj.fang.ke.com/loupan/p_zhhysdbksho/贝壳
新增住总如院户型:2室/3室/4室建面98-233㎡总价314万/套-31136 元/平(均价)采育镇采华路南端//bj.fang.ke.com/loupan/p_zzrybkwcr/贝壳
新增住总如院户型:3室/4室建面240-440㎡总价550万/套-31136 元/平(均价)采育镇波尔多小镇南区//bj.fang.ke.com/loupan/p_zzrybkxho/贝壳
新增西山上品湾MOMA3室/4室建面130-150㎡总价460万/套-37500 元/平(均价)阳坊镇温南路与阳八路交汇处//bj.fang.lianjia.com//loupan/p_xsspwmbkqax/链家
新增北京城建宽院国誉府-31000 元/平(均价)南北大街北京城建宽院国誉府//bj.fang.lianjia.com//loupan/p_bjcjkygyfbkrnz/链家
新增中海寰宇时代2室/3室/4室建面70-112㎡总价374万/套-52449 元/平(均价)大兴区瀛昌街与经二路交叉口东北150米//bj.fang.lianjia.com//loupan/p_zhhysdbksho/链家
新增住总如院2室/3室/4室建面98-233㎡总价314万/套-31136 元/平(均价)采育镇采华路南端//bj.fang.lianjia.com//loupan/p_zzrybkwcr/链家
新增和悦春风3室/4室建面82-107㎡总价273万/套-35000 元/平(均价)庞各庄镇瓜乡路与永兴河交汇处//bj.fang.lianjia.com//loupan/p_hycfbkzcf/链家
新增融创公园壹号建面73-133㎡总价268万/套-40000 元/平(均价)孙村公园西侧//bj.fang.lianjia.com//loupan/p_rcgyyhbkzwc/链家
新增小营路5号2室/3室建面109-150㎡总价762万/套-67000 元/平(均价)小营路5号//bj.fang.lianjia.com//loupan/p_xyl5hbkzzn/链家
新增恒大华府4室/5室建面271-338㎡总价2700万/套-88000 元/平(均价)东坝中街与单店北街交汇处西北侧//bj.fang.lianjia.com//loupan/p_hdhfaalqa/链家
新增MAHA缦合北京4室/5室/7室建面450-900㎡总价7000万/套-159000 元/平(均价)将台街道霄云路8号//bj.fang.lianjia.com//loupan/p_xylaampv/链家
新增山水文园五期2室建面153㎡-1300 万/套(总价)弘燕东路与西大望路交叉口向东100米//bj.fang.lianjia.com//loupan/p_sswyaamyo/链家
新增未来金茂府4室建面120-160㎡总价920万/套-920 万/套(总价)未来科学城南区英才南三街//bj.fang.lianjia.com//loupan/p_wljmfbjykc/链家
新增信达·国子郡3室建面79-115㎡总价390万/套-48810 元/平(均价)沙河镇北沙河中路与高教园附近//bj.fang.lianjia.com//loupan/p_xdzjbkebv/链家
新增京投发展公园悦府2室/3室/4室建面86-152㎡总价495万/套-58500 元/平(均价)回南北路与科星西路交汇路口处(8号线平西府站向东200米)//bj.fang.lianjia.com//loupan/p_aabaq/链家
新增北京怡园3室/4室建面95-170㎡总价460万/套-460 万/套(总价)水库路与昌崔路交汇处向北1公里路东//bj.fang.lianjia.com//loupan/p_bjyyaadjy/链家
新增东方蓝海中心3室/4室建面104-136㎡总价550万/套-52000 元/平(均价)未来科技城南区内科技城路与南区一路交界处//bj.fang.lianjia.com//loupan/p_dflhzxablaf/链家
新增未来公元3室/4室建面104-169㎡总价630万/套-60800 元/平(均价)京承高速北七家出口800米路南//bj.fang.lianjia.com//loupan/p_wlgyabloz/链家
新增融尚未来3室建面138-220㎡总价800万/套-59000 元/平(均价)未来科学城南区鲁瞳西路和南区三街交叉口西行50米//bj.fang.lianjia.com//loupan/p_rswlabqly/链家
新增招商都会湾3室/4室建面88-135㎡总价380万/套-43000 元/平(均价)内环西路招商都会中心//bj.fang.lianjia.com//loupan/p_zsdhzxacpea/链家
新增华润理想国3室/4室建面90-140㎡总价600万/套-49520 元/平(均价)北七家镇立汤路与北清路交叉点向东800米北清路南侧//bj.fang.lianjia.com//loupan/p_hrlxgbidvs/链家
新增中海丽春湖墅·SMART墅3室建面89-260㎡总价660万/套-660 万/套(总价)地铁昌平线沙河地铁站南600米//bj.fang.lianjia.com//loupan/p_zhlchsbifdm/链家
新增和悦华玺4室建面89-129㎡总价650万/套-49800 元/平(均价)北七家正北五环外,立汤路与北清路交汇处东行800米//bj.fang.lianjia.com//loupan/p_hyhxbimmq/链家
新增金辰府3室/4室建面89-143㎡总价400万/套-53000 元/平(均价)北五环定泗路北七家镇政府正南//bj.fang.lianjia.com//loupan/p_jcfbjyid/链家
升降标志房屋名房屋备注房屋总价房屋历史总价房屋单价小区名房屋链接来源网站
711 | None 712 | None 713 |
714 | 715 | 716 | --------------------------------------------------------------------------------