Python HTML 解析器
我正在尝试解析一个网站。我使用的是HTMLParser模块。问题是我想在注释:<!-- /topOfPage -->
之后解析第一个<a href="">
链接,但我不知道该怎么做。所以我在文档中发现有一个叫handle_comment
的函数,但我还没弄明白怎么正确使用它。我现在有以下内容:
import HTMLParser
class LinkFinder(HTMLParser.HTMLParser):
def __init__(self, *args, **kwargs):
# Can't use super() - HTMLParser is an old-style class
HTMLParser.HTMLParser.__init__(self, *args, **kwargs)
self.in_linktag = False
self.url_cache = []
def handle_comment(self,data):
if data == "topOfPage":
print data
def handle_starttag(self, tag, attrs):
if tag == "a" and any("href" == t[0] for t in attrs): # found link
self.in_linktag = True
self.url_cache.append([dict(attrs)['href']])
def handle_endtag(self, tag):
if tag == "a" and self.in_linktag: # ignore '<a name=""...'
self.in_linktag = False
def handle_data(self, data):
if self.in_linktag:
self.url_cache[-1].append(data)
TESTDATA = """
< html>
< body>
< div>
< ul>
< !-- /topOfPage -->
< tr >
< td class="empty-cell-left"> </td>
< td class="image">
< a href="http://test" rel="nofollow">
< ul>
< /div>
< /body>
< /html>
"""
def main():
lf = LinkFinder()
lf.feed(TESTDATA)
lf.close()
print lf.url_cache
if __name__ == "__main__":
main()
该怎么做呢?
2 个回答
1
handle_comment 函数会返回所有在分隔符之间的数据。
在这个例子中,数据实际上是 " /topOfPage "(注意空格和斜杠)。
你也可以这样做:
def handle_comment(self,data):
if "topOfPage" in data:
print data
2
你需要一个额外的变量来表示解析器刚刚经过了注释,这样你就可以保存后面第一个链接的引用。
def __init__(self, *args, **kwargs):
# ...
self.first_link_after_comment = False
然后,当你遇到注释时,那个标志必须被切换。
def handle_comment(self, data):
if data.strip() == '/topOfPage':
self.first_link_after_comment = True
当你处理一个开始标签时,如果解析器还没有经过注释,你就要确保它只是简单地跳过这个标签。
def handle_starttag(self, tag, attrs):
if not self.first_link_after_comment:
return
# ...
相反,当你处理结束标签时,你要确认任务已经完成。
def handle_endtag(self, tag):
if tag == 'a' and self.in_linktag: # ignore '<a name=""...'
self.in_linktag = False
self.first_link_after_comment = False
最后,当你添加数据时,要确保这个数据不是一个空字符串或者只包含空格的字符串。
def handle_data(self, data):
if self.in_linktag and data.strip():
self.url_cache[-1].append(data)
就这样。
$ your_script.py
[['http://test']]