在Python中中止HTMLParser处理
在Python中使用HTMLParser
类时,能不能在handle_*
函数里中止处理?在处理的早期,我就得到了我需要的所有数据,所以继续处理似乎有点浪费。下面是一个提取文档元描述的例子。
from HTMLParser import HTMLParser
class MyParser(HTMLParser):
def handle_start(self, tag, attrs):
in_meta = False
if tag == 'meta':
for attr in attrs:
if attr[0].lower() == 'name' and attr[1].lower() == 'description':
in_meta = True
if attr[0].lower() == 'content':
print(attr[1])
# Would like to tell the parser to stop now,
# since I have all the data that I need
3 个回答
1
在@shylent的回答基础上,我来分享一下我的解决方案:
class MyParser(HTMLParser):
boolean_flag = False
def handle_starttag(self, tag, attrs):
# for example:
self.boolean_flag = (tag == "sometag" and ("id", "someid") in attrs)
def handle_endtag(self, tag):
pass
def handle_data(self, data):
if self.boolean_flag:
raise DataParsedException(data)
class DataParsedException(Exception):
def __init__(self, data):
self.data = data
使用方法:
try:
parser.feed(html.decode())
except DataParsedException as dataParsed:
vars.append(dataParsed.data)
这个方法可以完成任务。
1
如果你使用pyparsing的scanString方法,你就能更好地控制你在输入字符串中实际处理的范围。在你的例子中,我们创建了一个可以匹配<meta>
标签的表达式,并添加了一个解析动作,确保我们只匹配带有name="description"
的标签。这段代码假设你已经把页面的HTML内容读入了变量htmlsrc
中:
from pyparsing import makeHTMLTags, withAttribute
# makeHTMLTags creates both open and closing tags, only care about the open tag
metaTag = makeHTMLTags("meta")[0]
metaTag.setParseAction(withAttribute(name="description"))
try:
# scanString is a generator that returns each match as it is found
# in the input
tokens,startloc,endloc = metaTag.scanString(htmlsrc).next()
# attributes can be accessed like object attributes if they are
# valid Python names
print tokens.content
# if the attribute name clashes with a Python keyword, or is
# otherwise unsuitable as an identifier, use dict-like access instead
print tokens["content"]
except StopIteration:
print "no matching meta tag found"
10
你可以抛出一个异常,并把你的 .feed()
调用放在一个尝试块里。
当你决定完成时,也可以调用 self.reset()
(我其实没有试过,但根据文档的说法,“重置实例。会丢失所有未处理的数据。” - 这正是你需要的)。