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

题记

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


前言

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

笔试题一——富文本过滤

  当我收到知乎的笔试题时,很激动,因为真心很想去知乎,用颤抖的手打开邮件,里面有两道题,第一道是这样的:


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

class 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值