因业务需要,在系统中需要将新加坡的地址之邮政编码输入后自动填入除了单元号的其他信息,比如街道名称,门牌号码等资料。靠谱的方法是去购买这个数据,价格在50英镑左右。方便起见,最终是会去购买这个数据的,另外里面还包含了坐标,估计以后也有用处。

在这个网站上http://sgp.postcodebase.com/上找到类似的资料,但是该网站不提供数据下载或购买,如果没有上面的渠道的话,那么只能去抓取这里的内容,处理成自己需要的材料。这个网站网页的结构比较简单,12万多条地址是根据“http://sgp.postcodebase.com/node/1”中的最后那个数字来区分。需要的字段有Postal Code,Street Name,Building No.,Building Name四个而已。看它的源代码,发现它前面的title信息就是要找的资料(这里title前后加了减号是为了注释掉它的属性):

<-title->Og Albert Complex, Albert Street, 60, Singapore, Albert, Bugis, Victoria Street, Rochor, Central: 189969 | Singapore Postcode<-/title->

其中第一个是Building Name,顺着是Street Name,Building No.,Postal Code则是“|”前面的那六位数字。将这个title里面的信息提取出来,稍微处理下就是所要的资料了:

import urllib.request

urls = ['http://sgp.postcodebase.com/node/' + str(i) \
for i in range(1, 3)]

def get_content(url):
    try:
        request = urllib.request.Request(url)
        response = urllib.request.urlopen(request)
        the_page = response.read()
    except:
        the_page = ''
    result = str(the_page)[:1500]
    #print(result)
    return result

def get_address(url):
    page = get_content(url)
    start_quote = page.find('<title>')
    end_quote = page.find('</title>')
    address = page[start_quote + 7:end_quote]
    return address


def modify_address(url):
    old_address = get_address(url)
    #print(old_address)
    address = []
    if len(old_address) > 6:
        temp = old_address.split(', ')
        #print(temp)
        address.append(temp[-1].split(': ')[1][:6])
        if temp[3] == 'Singapore':
            for i in range(2, -1, -1):
                address.append(temp[i])
        else:
            for i in range(1, -1, -1):
                address.append(temp[i])
            address.append('')
    new_address = '    '.join(address)
    return new_address

def update_file(urls):
    for url in urls:
        f = open('e:/address.txt', 'a')
        f.write('%s\n' % modify_address(url))
        f.close()

代码中的urllib.request只能在3.0以上的版本才能够用吧。写入txt文本的地址大概是这样的形式:

189969-**-60-**-Albert Street-**-Og Albert Complex

试运行的结果是,原则上可用,但是实际效果很差。原因如下:

  • 当网络有问题时,程序没有对应的处理方法。
  • 网页有延迟或者抓取不下来时,没有步骤重新去抓取。
  • 由于是单线程,网页的抓取需要一定的时间,估计每个页面需要1到2秒,因此12万多的页面需要几天的时间来抓取下来。
  • 因为以上原因,才做成每次抓取一个信息后,将它写入文件中,以免抓取过程有问题出错前功尽弃。

这样很非常相当不靠谱。搜索了下,要多线程或者同时抓取多个网页,似乎有multiprocessing之类的库可以辅助一下。我得再研究研究。

现有的Excel文档中有一万多条部件名称,基本上名称形式与下面类似:

FRONT BODY PANEL GRILLE (BOTTOM)
FRONT BRAKE PIPE
BONNET HINGE LH

当然还有一些不是这个规范来的。那些只能手动了,那样可能还会快点。我的要求是将它们转换成小写,第一个字母为大写,而表示LH和RH(左右方向)的时候则这两个字符不变。结果大概是这样:

Front Body Panel Grille (Bottom)
Front Brake Pipe
Bonnet Hinge LH

昨天起了第一稿,今天缝缝补补了一会,代码如下:

def old_type(file_path_1, file_path_2):
    f = open(file_path_1, 'r')

    t = []
    for line in f:
        if len(line) > 0:
            t.append(line)

    t1 = []
    unchange = ['LH', 'Lh', 'RH', 'Rh']
    for p in t:
        temp = p.split()
        t1_temp = []
        for k in temp:
            if len(k) > 1:
                if k[0] == '(':
                    k = k[0] + k[1].upper() + k[2:].lower()
                elif k in unchange:
                    k = k.upper()
                else:
                    k = k.capitalize()
                t1_temp.append(k)
            t2_temp = " ".join(t1_temp)
        t1.append(t2_temp)

    f.close()

    #print(t1)
    newlist = open(file_path_2, 'w')

    for item in t1:
        newlist.write("%s\n" % item)

    newlist.close()


# file_path_1 = 'e:/vehicle.part.0.txt'
# file_path_2 = 'e:/vehicle.part.new.txt'

里面有的毛病是命名不规范,可以再优化一下,这个得水平高点才能够搞了。还有就是记不住那些格式转换的规则,得翻书才行。不管怎样,对比手动来说,效率提高了N倍。

上个月完成了两门Coursera的在线课程:

并不是很难,更多的似乎是在词汇量上遇到问题。金融导论讲述的是如何初级评估各类资产,以及一些基本的金融信息。而游戏化则是提及各类商业活动中如何将游戏因素整合到规划、设计、推广等环节中去。

Introduction to Finance – Statement of Accomplishment
Coursera - Introduction to Finance

Gamification – Statement of Accomplishment
Coursera - Gamification

清晨七点半在公司门口集合,填好过境卡,不到八点出发。从Tuas关卡经过柔佛海峡,先前往马六甲。一路上睡着过去,因前一晚看电影到三十点多。在马六甲一个地方下来购物,然后在另一个地方吃娘惹餐,就赶着去Pahang。公司是承包了一辆大巴士,不过该巴士租赁公司还提供了导游服务,该妹妹是马来人,但有一半华人血统。因此有点像一日游的行程。宴席是在晚上六点半开始,现在看来去马六甲除了在路程上有点弯之外,没有其他任何的亮点。如我所言,希望有所不同,各位,这就是不同之处。

Melaka
靠近海边的马六甲

离开马六甲,还是一路睡着过去,提前40分钟达到。礼金按习俗是放在邀请函里面,而不用另外准备红包封,这个安排比较环保,也知晓礼金的主人。金童玉女,天作之合。W哥在工作上对待客户和同事一直都挂着微笑,这是很值得佩服的地方。几个月前他父亲过世,根据习俗得在一百天内举办婚礼。婚宴过程跟大多数华人的宴席差不多,但其中一个环节跟国内的有很大的不同。刚开始上菜时,就听到司仪说邀请新娘的亲戚上台卡拉OK,之后就有陆续双方的亲朋好友在台上一展歌喉。该酒楼据说是西马东部最大的酒楼,但是一开始就感觉到了基础设施的不完备,没有准备好一个婚礼的条件。家人都不高兴,尽管返回一些费用,但是这毕竟是一生一次的时刻。

晚上九点宴席结束,司机一路狂飙回新。凌晨三点半回到公司。五点进入梦乡。

今天收到两张婚礼摄影相片,这也是习俗。

鲁宾逊将他的土著同伴取名为星期五的原因是,估计没人能够想得到:只有星期五是以F开头的,作者是借此来代表鲁宾逊被困在荒岛上的愤怒和随之而来的无力感。有时候,事情就是这么简单。

回归正题。英语角已经重新开始,这个星期是第三次。由于需要参加S哥所在的周五羽毛球“进阶班”,只在第一次回到J&C家里,跟老朋友们一起讨论故事和听纯正的英文。虽然在狮城论坛上也发布了帖子,不过已经不像上次那样“招到”新朋友;尽管如此,还是可以维持小型的英语角。不排除没有及时更新和顶自己的帖子,以至于没有获得足够的关注。关于羽毛球,完全是个初学者,握球拍的手势也不对,然后击球的角度和力度也是业余水平。在休息间隙,朋友们很耐心的提醒注意事项和相关技巧,比如重心放到右脚,握球拍的手势跟握手时差不多,球拍的边缘方向对着自己,靠身体的侧向来利用整个肩膀的力量来击球,击球时前一瞬间用手腕用力去扣球等等。开始时,会觉得记住这些技巧会阻碍了灵活性,但得认真体会和消化到动作当中去,要不然,打下去仍然是业余入门级。

昨天在QQ上收到要注意酸雨的群发留言,狼来了喊多啦也就不会注意。而且,下意识的认为冰岛火山爆发的灰尘跟大陆相隔还是蛮远的,应该不会造成什么影响。刚才看到新闻写到要小心哗啦哗啦的酸雨,TLT说昨天下了很大雨,不过她也没有特别提到酸雨这个字眼。打完球,去勿洛坊那家星期五“固定”古早味餐馆吃饭时被告知他们将在这个周末结束营业,租金6500对他们来说太贵了,其实也就是国内普通大排档的规模,店铺已经给隔壁的生意超好的茶餐厅老板租下来。然后我该睡觉了。

注:其实,鲁宾逊从食人族手中救下这个土著的那天是星期五,因而给该土著人命名为「星期五」。看,事情真的很简单。