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

题记

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


前言

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

笔试题一——富文本过滤

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


  
  最开始才疏学浅,不知道富文本过滤要干些什么,去搜索了一番,大致知道了过滤是要对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
    评论
很高兴接受您的要求,以下是一个简单的 HTML 页面范例,您可以参考下面的代码实现页面设计。 ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>我的知乎主页</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; color: #595959; } header { background-color: #fff; padding: 20px; box-shadow: 0 3px 3px rgba(0,0,0,0.1); position: fixed; top: 0; left: 0; right: 0; z-index: 999; } nav a { font-size: 18px; font-weight: bold; color: #999; text-decoration: none; margin: 0 10px; padding: 10px; border-radius: 5px; transition: all 0.3s ease-in-out; } nav a:hover { background-color: #F5F5F5; color: #333; } .main { margin-top: 70px; padding: 20px; max-width: 800px; margin: auto; } h1 { font-size: 36px; font-weight: bold; margin-bottom: 20px; } p { font-size: 16px; line-height: 1.5; margin-bottom: 20px; } section { border-bottom: 1px solid #E5E5E5; padding-bottom: 20px; margin-bottom: 30px; } section:last-child { border-bottom: none; padding-bottom: 0; margin-bottom: 0; } </style> </head> <body> <header> <nav> <a href="#">首页</a> <a href="#">文章</a> <a href="#">提问</a> <a href="#">话题</a> <a href="#">消息</a> </nav> </header> <div class="main"> <h1>我的知乎主页</h1> <p>欢迎来到我的知乎主页,我是一名程序员,热爱技术、阅读和思考,喜欢分享和交流,希望能够结交更多志同道合的朋友。</p> <section> <h2>最新文章</h2> <ul> <li><a href="#">如何掌握 JavaScript 面向对象编程</a></li> <li><a href="#">Vue.js 实战:构建一个电子商务网站</a></li> <li><a href="#">如何写出高质量的 React 组件</a></li> </ul> </section> <section> <h2>热门问题</h2> <ul> <li><a href="#">如何从零开始学习编程?</a></li> <li><a href="#">如何提高编程能力?</a></li> <li><a href="#">如何写出优美的代码?</a></li> </ul> </section> <section> <h2>精选话题</h2> <ul> <li><a href="#">前端开发</a></li> <li><a href="#">后端开发</a></li> <li><a href="#">机器学习</a></li> <li><a href="#">人工智能</a></li> </ul> </section> </div> </body> </html> ``` 您可以复制以上代码并保存成 .html 文件,用浏览器打开即可预览页面效果。这个页面包括一个固定在顶部的导航栏,三个部分分别显示最新文章、热门问题和精选话题,每个部分都是一个包含标题和列表的小模块,样式简洁清晰,易于阅读。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值