知乎笔试(1)——富文本过滤

题记

无论发生什么,记住对自己好。

前言

终于,收到了知乎的回复,一面就被拒了(此处应该有一个悲伤的表情)。不过也没什么遗憾了,申请了好多次,终于申请到了笔试和面试的机会。通过这次的经历,我知道了路还很长很长,想把这次的经历写下来,也算是一种纪念。

笔试题一——富文本过滤

当我收到知乎的笔试题时,很激动,因为真心很想去知乎,用颤抖的手打开邮件,里面有两道题,第一道是这样的:最开始才疏学浅,不知道富文本过滤要干些什么,去搜索了一番,大致知道了过滤是要对Html进行解析,去掉不合法的标签和字符。我最开始还想加上自动correct富文本的功能,比如如果标签不闭合,自动补全等等,但是记得那几天事情真心太多了,还有SQA的口试,没花太多的时间去完善代码。知道了要干什么,就可以开始写了。我首先想到的肯定是要用到一个解析html库之类,跑一遍html,在解析html的过程中做一些处理。之前有用到过Python中的ElementTree解析过xml,首先去搜索了一番,找到了以下一些资料:How to parse malformed HTML in python, using standard libraries大致说Python里面有很多解析Html的库,内建的HtmlParser貌似是一种方法,但是它却经常在一些非常普通的html时会出现问题,如果你成功解决了这些问题,那么你很有可能重写了一个库——BeautifulSoup。靠谱的解析Html的方式大概有三种:lxml.html,BeautifulSoup,html5lib。但是考虑到可能面试官不会去安装这些库,我还是决定用python内建的HtmlParser去完成这道题。去搜了一下这个类的使用方法,发现原理跟Java使用SAX方式解析XML是一样的,都是提供了一系列的回调方法,使用时需要继承自相应的类,覆盖这些方法,添加上你自己的处理。比如遇到起始的tag有一个回调的方法,遇到文本有一个回调的方法,还需要一个变量来保存上一次遇到的tag,代码如下:

import HTMLParser, sysclass EditorParser(HTMLParser.HTMLParser):    def __init__(self, standard):        HTMLParser.HTMLParser.__init__(self)        self.standard = standard        self.clean_text = []        self.pre_tag = None    def handle_starttag(self, tag, attrs):        if tag in self.standard:            self.clean_text.append('<')            self.clean_text.append(tag)            for name, val in attrs:                if self.standard[tag] and name in self.standard[tag]:                    exp = ' %s="%s"' % (name, val)                    self.clean_text.append(exp)            self.clean_text.append('>')            self.pre_tag = tag    def handle_data(self, data):        if self.pre_tag in self.standard:            self.clean_text.append(data)    def handle_endtag(self, tag):        if tag in self.standard:            self.clean_text.append('</{0}>'.format(tag))            self.pre_tag = None    def get_clean_text(self):        return ''.join(self.clean_text)def main():    if len(sys.argv) < 2:        print '\nUse like this:\n\t$python filter.py [html_file_to_handle]\nThe clean html will be output to a new html file.\n'        return    html = open(sys.argv[1], 'r')    legal_tag_attr = {'a' : ['href', 'title'], 'abbr' : ['title'], 'acronym' : ['title'], 'b' : None, 'blockquote' : ['cite'], 'cite' : None, \                        'code' : None, 'del' : ['datetime'], 'em' : None, 'i' : None, 'q' :['cite'], 'strike' : None, 'strong' : None, 'pre' : None}    editorParser = EditorParser(legal_tag_attr)    editorParser.feed(html.read())    clean_text = editorParser.get_clean_text()    editorParser.close()    html.close()    # print clean_text    clean_html = open(sys.argv[1].split('.')[0] + '_clean.html', 'w')    clean_html.write(clean_text)    clean_html.close()if __name__ == '__main__':    main()

这样一个简单的过滤器就写完了,功能比较简单,仅仅能去掉不合法的标签以及不合法的属性,没有纠错功能。

样例输入与输出

样例的输入:

<abbr>This is legal abbr text.</abbr>  <a href="http://www.zhihu.com" id="bad_id">  <strong name="bad_name" id="bad_id" class="bad_class">This is a legal strong href</strong>  </a>  <head>This is a bad head</head>  <acronym title="acronym titel"></acronym>  </br>  </em>  <body>This is bad body.</body>  <title class="bad_class">This is bad title.</title>

经过过滤后的样例输出:

<abbr>This is legal abbr text.</abbr><a href="http://www.zhihu.com">  <strong>This is a legal strong href</strong></a><acronym title="acronym titel"></acronym></em>

HtmlParser提供的功能真的很少,只提供了最基本的功能,要对HTML做一些深入的操作还得用其他的lib。

题记

无论发生什么,记住对自己好。

前言

终于,收到了知乎的回复,一面就被拒了(此处应该有一个悲伤的表情)。不过也没什么遗憾了,申请了好多次,终于申请到了笔试和面试的机会。通过这次的经历,我知道了路还很长很长,想把这次的经历写下来,也算是一种纪念。

知乎笔试(1)——富文本过滤

相关文章:

你感兴趣的文章:

标签云: