分类目录归档:未分类

第一次买房记

没买房的人都亏了。

背景:作为本地人多少都有房子的,所以很长时间里我的观念中就是不要参合买房大战,房奴过的都很艰辛。买房的念头就是从户口问题开始的,孩子过一年就要上小学了,户口于是打算迁到城里,没成想今年开始政策不允许了,因为迁户口用的房子性质有问题,哎,政府的锅为什么要让老百姓买单,气。周围问了一遍,发现不买房上学真的是个问题。

看房:本来我们这是个小县城,随着经济快速发展我也从市中心一次次往外搬,出于对老城区的感情和学区的要求看的都是绣湖区块。正好碰上拆迁潮,新小区没有几个,还都是期房,价格超出预算很多,只能放弃。如果不买老城区心里有受不了住的比现在还远的落差,于是开始看二手房。

二手房:一直知道二手房坑多,看房的时候中介啊朋友啊说了各种故事。好在表哥刚刚买了二手房,可信的咨询就比较多了。作为二手房价格肯定比新房便宜多了,但是比新房多出几个成本:中介费、过户契税、营业增值税、土地出让金(如果是安置房,我买的就是这种)。然后作为二手房也有他的好处,比如学区稳定,不会像期房开始各种承诺,后面各种问题落实不了,甚至有的证件齐全却发不下房产证,本来买房就是为了入学,所以二手房是更好地选择。

中介:二手房避不开中介,哪怕你跟房东认识也必须邀请有执业资格的中介签订第三方契约。中介费就是个头疼的问题了,特别是高价的房子,因为中介费是按照百分比算的,比如义乌最大的中介坐标大概是2%,上海大概1.5左右。200万的房子中介费就是四万了。托表格的福,他花了很多时间找到了私人中介按照固定费算。有的中介带你看房后会要求签署一个协议,这个协议会锁定你半年左右时间,这段时间里哪怕你跟别人交易用的其它中介也要付中介费给协议方,要小心哦。

出让金:这个大多出现在安置房中,我觉的这个挺流氓,集体土地低价变成国有土地后居然还要交钱,无语了。这一项最重要的是用房产证来实际计算,因为变数很大,很多中介会把四五十万的出让金粗算成三十多万,就是为了促成成交。作为大头之一,直接影响到最后总的预算。

契税:这个倒是固定的,项目可能多,但是不会有变数。

营业增值税:这个是为了防止炒房出台的,一般购买时问清楚房东持有的年限就好,大城市这个影响比较大,义乌只限两年,碰到的比较少。

按揭:这是我最大的痛,如果有公积金一定要公积金贷,便宜很多很多,平常看不出来,累积起来能省三分之一。一般都是四大行操作,利率都是国家标准,打听好再去办。现在还会附带保险要求,这个就有点耍流氓,而且跟你卡绑定,逃都逃不掉。

车位:很重要,特别老城区的车库都炒到天价了,这次买的并没有车位,略有遗憾,幸好周围有新建的停车场还能自我安慰下。二手房大多老小区,所以停车一定要计划好,当然好的停车位房价总价自然也是高的。最好能有两个车位,毕竟现在车便宜了。

买房决心的因素:大概位置和学区一般开始就能定下来,预算一看便知。那么最后下决定买哪套我觉得跟心理预期最重要,简单说就是自己满意就好。

  • 小区的东南角,采光和视野应该是最好的;
  • 中间楼层,太低采光不好和蚊虫多,也不够安静,太高风大,不坐电梯就太可怕了;
  • 靠近公园,适合晚饭后散步、孩子们玩耍,近了去的才会多,城里我一直认为公园是最宝贵的,也是这套我最满意的地方;
  • 商场在小区的西面,大概几百米吧,正好吵不到,购物也方便;
  • 幼儿园在马路对面,可惜这几年不去住,否则午餐回家吃都妥妥的;
  • 小学大概1km,走路可及;
  • 离市政府不远,主要是考虑保值,涨价就不去想了,也不打算再卖;
  • 租赁:原先租户是一个单位,价格高出市场价40%,相当满意,打算多租两年,让财务缓一缓;
  • 总价比预期高了一点,这还是在房东砍价后的,可能买房时间不好吧,跟大量拆迁户正面作战;

python 爬取携程特价票-知道什么时候出发最便宜- 支持多航段搜索

好久不写文章了,两天弄了个携程的脚本,发现网上大多都是18年以前老版的做法现在已经没有借鉴的意义,于是记录攻略如下,希望能帮助到其它爬虫党。最近出国好多,查找机票价格特别烦,这次又准备买了,正好折腾一下。

网上现有脚本之所以不能执行除了页面改版外还因为携程加入sign签名使得爬取携程的难度大大上升,几乎搜不到可用的脚本,第一次真正写爬虫也希望能贡献给他人做参考。

  • 我的需求

对机票得有一个大概的认识,某一天的最低价各大网站都有提供了,所以我们这里比较的是时间段内的最低价,另外比如一周内的机票铁定贵,不太可能去买两个月以上的机票,当然跟这个脚本没关系。给出搜索后携程会推送最低价的机票,那么需求就变成在我计划出行的时间范围内哪一天走最便宜。本来的有网站提供类似时间段的搜索服务,不知道为啥现在没了。

  • 控制台分析和XHR回放

在入手前先看看难度,之前已经搜索了好多携程爬取的文章,发现可以用它的api直接取到航班json,控制台翻找后发现batchFlight这个地址就是,并且通过xhr可以回放。这点很重要,不是携程故意的漏洞,因为没登录也可以查机票,所以如果不让回放服务器就有压力了。既然可以回放那么思路就明确了,构建此XHR即可。

  • 测试脚本构建

XHR是一个Post请求,参数放在payloads中,啥都不说,先来个测试方法,用python来回放。如果回放成功说明我们需要的元素都在这里了,有洁癖的在这一步就可以试着缩减传送参数只传必要的。

def test_sample_request():
session = requests.session()
session.headers = {"hearders": random.choice(agents)}
base_url = "https://flights.ctrip.com/international/search/api/search/batchSearch"
url = base_url
payload = 'xxx payload json data'
headers['user-agent'] = random.choice(agents)
response = requests.post(url, headers=headers, params=params, data=payload.encode('utf-8'))
print(response.status_code)
print(response.content)
  • 确定sign和transactionid

经过上面的代码可以确定的是sign和transactionid缺一不可。transactionid很快发现就在主页的head标签中,通过bs4可以很容易找出来。

  • sign的破解

sign就比较麻烦了,通常的做法分为两种,一种是调试js破解sign的算法,需要大量精力明显不适合我,但是效率高,另一种是selenium模拟浏览器请求把sign拿出来。这里其实有点背道而驰,高手在模拟请求时就可以获取到所有数据才对,但是发现目前最新版的chrom对于子请求并不能获取到数据,从75版本开始不再记录response的数据。这里有的同学会考虑在selenium前面架设proxy,我也试了一下,发现等待子请求完成不是一件确定的事,反倒是模拟请求中获取sign基本没有缺失过,那么稳定为先,获取sign后用request获取json更好,把更多的时间用来分析返回的json上。

代码:

下面附上参考文献地址:https://github.com/today4king/daily-scripts/tree/master/flight-tickets

Python ctypes获取当前所有打开窗口title

Python pywin32获取当前所有打开窗口title

import ctypes
 
EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible
 
titles = []
def foreach_window(hwnd, lParam):
    if IsWindowVisible(hwnd):
        length = GetWindowTextLength(hwnd)
        buff = ctypes.create_unicode_buffer(length + 1)
        GetWindowText(hwnd, buff, length + 1)
        titles.append(buff.value)
    return True
EnumWindows(EnumWindowsProc(foreach_window), 0)
 
print(titles)

同理访问所有内部窗口

def foreach_window(hwnd, param):
        if IsWindowVisible(hwnd):
                length = GetWindowTextLength(hwnd)
                buff = create_unicode_buffer(length + 1)
                GetWindowText(hwnd, buff, length + 1)
                titles.append(buff.value)
        return True
win32gui.EnumChildWindows(mainwnd, foreach_window, None)
print(titles)

Win32 Python: Getting all window titles

对Flask 初始化过程的 profile

如果是普通的flask页面profile建议使用WSGI Application Profiler

它会自动分析每一个页面,并profile,内部也是cprofile实现。

针对初始化过程只能手动使用cProfile:

python -m cProfile -o profiling run_web.py

等到初始化完毕再进入python ide:

>>> import pstats
>>> stats = pstats.Stats(‘profiling’)
>>> stats.sort_stats(‘time’).print_stats(10)

 

Flask Debug模式下总是初始化两遍

这个如果是在debug模式下出现一般是跟reloader特性有关系,WERKZEUG提供的这个特性主要是方便实时监测到开发中修改的文件,比重启app要快很多。但是有的时候我们希望app或者部分代码指启动一遍,可以用下面的环境变量来监测是否是第二次reload中的初始化。

if not app.debug or os.environ.get(“WERKZEUG_RUN_MAIN”) == “true”

组件初始化我们也希望初始化一遍,flask对此有一个专门的事件:

@app.before_first_request
def initialize():
print “Called only once, when the first request comes in”

docker network 网络服务发现和内嵌的dns系统

docker-compose的启动会默认创建一个bridge类型的网络,当然它跟默认的bridge是继承关系。最近升级ide和docker后发现服务之间出现了个现象,服务能ping的通但是别名就不可以。而更改的地方就是网络模式network_mode  设置为了bridge。

原来当使用default bridge network的情况下,docker container使用宿主机的resolv.conf,当然不会解析服务名了。从1.10开始docker对自建的网络默认启用embedded dns,这个dns会自动更新新分配的服务。

docker network create mynet  //不指定网络模式时默认是bridge

用mynet替换原先的bridge即可。如果在一个网络内可以用服务名来访问比如ping service_name,如果不是可以通过ping service_name.devnet

mysql docker 日志输出时区修正

docker通常修改 -v /etc/localtime:/etc/localtime就可以修改系统时间,但是mysql日志输出时间还是没变,因为它的时间默认是UTC时间,修改需要更改mysql的配置。增加启动参数:–log_timestamps=SYSTEM

完整示例:

docker run -e MYSQL_ROOT_PASSWORD=root -v /etc/localtime:/etc/localtime:ro  -d mysql:5.7 –log_timestamps=SYSTEM