河伯特高

HerbertGao 个人主页

Python ——从入门到监控租房网站

Python

——从入门到 PY 交易

其实我早就入门了。
其实我入门了好多次。

不过这次是我第一次真正写出来一个有点用处的脚本。
虽然最终租下房子还是中介提醒我可以预定了,这脚本没完全起效


事情起因是因为最近房子快到期了,所以考虑换一套。
由于有跟人合租的需求,所以想找一套两室一厅的。
在某租房网站上挑来挑去后,决定租 X 地的房子,于是和中介打好招呼,去看房。
结果到了地方,中介告诉我房子还在装修没法看,于是只好问了问详情,留了联系方式就走了。
没想到刚上地铁走了没两站,中介打电话告诉我房子可以看了,并且看中的几套中,有一套当天 50 分钟后就可以签约。
然而看中的几套中,有一套比这一套更喜欢的,所以告诉中介希望等等后面的房子。
结果就在这套房子可签约后的 20 分钟,房子被别人签走了,走了,了……
(该网站是线上签约,热门房子就看谁手速快)
虽然想要的并不是这套房子,但是痛定思痛,还是决定写个脚本实时监控想要的房子。
虽然我学的是 Java,但是 Java 本身运行比较吃内存,不够轻量级,所以我把目光转向 Python,一个我并不怎么会的语言
思路如下:

  1. 如果网站是以 JavaScirpt 发起请求调用 JSON 获取房源数据的话,我直接解析 JSON 就很容易得到房子是否可签约。通过 JSON 获取数据例子:Apple Inc.预约新机时显示各店是否有新机是这种模式,常见于 Ajax 异步刷新使用的方式。不过我找了一圈,发现该网站不是这种类型,可能是 PHP 在后端调用接口直接把成品页面拼装好了直接返回给浏览器的;
  2. 直接抓取整个页面,通过寻找相关 Dom 节点获取所需数据,根据数据判断房子是否可以预定;
  3. 通过阿里大于,当房子可以预定时就给自己的手机发一条短信提醒;
  4. 定期执行该方法,准备随时获得最新信息。
    具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# -*- coding: utf-8 -*-
import httplib2.socks
import top.api
import sys
import time
from threading import Timer
from lxml import etree

reload(sys)
sys.setdefaultencoding('utf8')

# 阿里大于接口URL
alidayuUrl = 'gw.api.taobao.com'
# 阿里大于接口端口
alidayuPort = '80'
# 阿里大于短信模板(需要通过阿里大于服务器端验证)
alidayuTemplet = "SMS_12345678"
# 阿里大于签名(需要通过阿里大于服务器端验证)
alidayuSign = "贰浩次元"
# 阿里大于手机号
alidayuTel = "1**********"

class PageClass:
# 获得页面
def getPage(self, url):
http = httplib2.Http()
response,content = http.request(url,'GET')
return content

# 打开某一文件获得地址列表
def getURL(filepath):
input = open(filepath, 'r')
cites = input.readlines()
return cites

def zhaofangzi():
# 1、打开文件
urls = getURL('url.txt')
# 2、循环所有地址
for url in urls:
print "url:",url
# 3、实例化页面类并获取页面
page = PageClass()
content = page.getPage(url.strip())

# 4、将页面转化成树
tree = etree.HTML(content)
# 5、解析树,找到所需元素,如预订按钮元素
hyperlinks = tree.xpath(u'//div[@class="room_btns clearfix"]/a')
# 6、循环元素(此处只可能有1个元素或0个元素,即仅执行一次或不执行)
for index,hyperlink in enumerate(hyperlinks):
if index > 1:
break
btnId = hyperlink.get('id')
yudingFlg = False
if index == 0:
if btnId == 'zreserve':
yudingFlg = False
else:
yudingFlg = True
elif index == 1:
if btnId == 'toYuding':
yudingFlg = True

if yudingFlg == True:
# 7、获取所需的房间名称
title = tree.xpath(u'//div[@class="room_name"]/h2')[0].text.strip()
print "title:",title
# 8、实例化阿里大于短信发送请求并填入各种配置参数
req = top.api.AlibabaAliqinFcSmsNumSendRequest(alidayuUrl, alidayuPort)
req.set_app_info(top.appinfo('appkey', 'appsecret'))

req.extend = ""
req.sms_type = "normal"
req.sms_free_sign_name = alidayuSign
req.sms_param = "{housename:'"+title+"'}"
req.rec_num = alidayuTel
req.sms_template_code = alidayuTemplet
try:
# 9、发送
resp = req.getResponse()
print (resp)
except Exception, e:
print (e)
print "end"
return True

if __name__ == "__main__":
while zhaofangzi():
print 'now time:'+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+'. waiting for 15 min'
t = Timer(60 * 15, zhaofangzi)
t.start()
t.join()

实际操作及运行中遇到的问题如下:

  1. 乱码问题。不同的机器上运行,有的抓取页面时会出乱码,有的不会出,这个比较头疼,会直接影响到运行结果,最终也没解决这个问题(反正房子已经订好了)
  2. 做这个脚本的时候实际没有监控到「XX:XX 可预订」按钮的信息,实际上之后的某个版本做了,但仍然卡在乱码的问题上,最终还是放弃了。

一张效果图

效果图

欢迎关注我的其它发布渠道