做 Python爬虫 的朋友,大多都写过电商数据,但很少有人认真做过房产数据。其实,房产网站的房源信息采集,才是真正考验爬虫稳定性的试金石。
安居客(Anjuke) 作为国内头部找房平台,覆盖了全国几百个城市的二手房、新房、租房数据。无论是做 房价走势分析、小区性价比对比,还是帮亲戚朋友筛选高性价比房源,一套稳定的 安居客房源爬虫 都能帮你节省大量手动翻页的时间。
但现实是:安居客的反爬并不弱,页面结构经常微调,传统的 requests 方案很容易失效。今天分享一个基于 DrissionPage 的实战脚本,不逆向、不破解,直接接管浏览器,按城市自动切换域名(如 bj.anjuke.com),稳定提取标题、小区、户型、面积、总价、单价、标签等 11 个核心字段。
无论你是 数据分析新手,还是正在做 房地产市场调研,这套代码都能直接复用。下面进入全代码拆解环节 👇
技术栈:DrissionPage + pypinyin + CSS 选择器 + 容错解析
一、依赖导入与城市拼音转换
import timeimport csvfrom pypinyin import pinyin, lazy_pinyinfrom DrissionPage import ChromiumPage
•pypinyin:核心亮点
•安居客的城市域名是拼音:bj.anjuke.com
•用户输入“北京”,必须转成 beijing
•lazy_pinyin:返回列表,用 join 拼成字符串
cityname = input('请输入城市名称(如:北京):')cityname_pinyin = "".join(lazy_pinyin(cityname))print(cityname_pinyin)
二、构造城市专属 URL
URL = f"https://{cityname_pinyin}.anjuke.com/sale/"
安居客的二级域名结构非常规范
这也是它比链家、贝壳更适合做爬虫的原因之一
三、CSV 初始化(字段设计很完整)
csv_file = f"{cityname}安居客房源.csv"csv_header = [ "标题", "小区", "地址", "户型", "面积", "朝向", "总价", "单价", "标签", "详情链接", "采集时间"]
✅ 字段设计很专业:
区分了 总价 / 单价
保留了 标签(如“近地铁”“满五唯一”)
记录了 采集时间,方便做价格追踪
f = open(csv_file, "w", newline="", encoding="utf-8-sig")writer = csv.writer(f)writer.writerow(csv_header)
•utf-8-sig:Excel 打开不乱码
•csv.writer:比 DictWriter 更轻量
四、浏览器启动与第一页加载
dp = ChromiumPage()dp.get(URL)time.sleep(2)
真实浏览器访问,绕过 UA 校验
sleep(2):等页面 JS 渲染完成
五、房源卡片定位(外层容器)
items = dp.eles("css:.property", timeout=2)if not items: print("⚠️ 未检测到房源卡片,可能被拦截或页面结构已变更") break
•.property:安居客房源卡片的最外层 class
•用 eles(复数),一次拿一整页
•空列表 = 被反爬 / 城市无数据 / 结构变更
六、单条房源字段提取(容错拉满)
1️⃣ 标题
title = it.ele("css:.property-content-title-name", timeout=1).text.strip()
2️⃣ 总价(带单位)
total_price_num = it.ele("css:.property-price-total-num", timeout=1).text.strip()total_price = f"{total_price_num}万"
安居客只给数字,单位要自己拼
“万”是中文用户最直观的单位
3️⃣ 单价
unit_price = it.ele("css:.property-price-average", timeout=1).text.strip()
4️⃣ 小区名称
community = it.ele("css:.property-content-info-comm-name", timeout=1).text.strip()
5️⃣ 户型 / 面积 / 朝向(一组字段)
fangxing = it.eles("css:.property-content-info-text", timeout=1)huxing = fangxing[0].text.strip() if len(fangxing) > 0 else "-"mianji = fangxing[1].text.strip() if len(fangxing) > 1 else "-"chaoxiang = fangxing[2].text.strip() if len(fangxing) > 2 else "-"
✅ 非常经典的写法:
安居客把户型、面积、朝向放在同一组 span 里
用索引取,比单独写选择器稳
len(fangxing) 判断,防止越界
6️⃣ 地址
dizhi = it.ele("css:.property-content-info-comm-address", timeout=1).text.strip()
7️⃣ 标签(多值合并)
tags = ",".join([ t.text.strip() for t in it.eles("css:span.property-content-info-tag", timeout=1)])
8️⃣ 详情链接
detail_url = it.ele("css:.property-ex", timeout=1).attr("href")
9️⃣ 采集时间
fetch_time = time.strftime("%Y-%m-%d%H:%M:%S")
七、翻页逻辑
next_btn = dp.ele("css:.pagination .next-active", timeout=2)
•.next-active:可点击的“下一页”
•如果不存在,说明已是最后一页
next_btn.click()page_num += 1time.sleep(2)
八、收尾与统计
f.close()print(f"\n✅ 全部爬取完毕,共 {total_count} 条房源")input("回车关闭浏览器")dp.quit()
关闭 CSV
input():防止窗口一闪而过
退出浏览器,释放资源
这段代码的 5 个细节
城市拼音自动转换:pypinyin 让脚本支持全国城市
字段分组索引取值:户型 / 面积 / 朝向一把梭
标签数组拼接:保留完整营销信息
总价单位补全:用户体验友好
翻页按钮精准定位:.next-active 防误判
实战延展(比代码更有价值)
拿到这份 CSV,你可以:
📈 做城市房价地图:按区域统计均价
🏘️ 小区性价比排行:单价 + 房龄 + 标签
🔔 降价监控:定期跑脚本,对比历史价格
📊 房源特征分析:电梯 / 朝向 / 楼层的影响