【问题标题】:Python: Returning only hosts/a href with my HTML parserPython:使用我的 HTML 解析器仅返回 hosts/a href
【发布时间】:2014-10-16 15:06:47
【问题描述】:

我有一个不使用任何外部库或包(例如 Beautiful Soup 等)的 HTML 解析器。它可以工作,这里它需要一个命令行 html 文件并只返回文本。

我想修改它,或者让它有一个只返回主机名的功能,例如标签中的HOST;让它只返回主机,只返回顶级目录,如“stackoverflow.com”等。

class _DeHTMLParser(HTMLParser):
def __init__(self):
    HTMLParser.__init__(self)
    self.__text = []

def handle_data(self, data):
    text = data.strip()
    if len(text) > 0:
        text = sub('[ \t\r\n]+', ' ', text)  #probably alter here?
        self.__text.append(text + ' ')

def handle_starttag(self, tag, attrs):
    if tag == 'p':
        self.__text.append('\n\n')
    elif tag == 'br':
        self.__text.append('\n')

def handle_startendtag(self, tag, attrs):
    if tag == 'br':
        self.__text.append('\n\n')

def text(self):
    return ''.join(self.__text).strip()


def dehtml():  #have it pass line?
    try:
        parser = _DeHTMLParser()

        f = open(sys.argv[1], 'r')  #not argv[1] but stdin all?
        text = f.read()
        f.close()

        parser.feed(text)
        parser.close()
        return parser.text()
    except:
        print_exc(file=stderr)
        return text

现在我可以调用 dehtml() 并且它运行返回纯文本/无标签版本。

为了让它也打印出主机,我将它添加到 def handle_starttag

if tag == 'a href':
        self.__text.append()

看看它是否会,作为第一次尝试,附加主机名,但没有运气。我相信问题出在我的 handle_data 部分,特别是在正则表达式位 - 这是正确的吗?

【问题讨论】:

  • 那么你的实际问题是什么?
  • @PaulCollingwood 如果不清楚,我深表歉意。现在它返回标签之外的文本,我希望它代替或作为附加功能,仅返回 inside a href 标签的主机名,例如在 链接
  • 我是否应该在handle_starttag中做一些事情,if tag == a href then print?
  • 你应该做某事是的,当你遇到困难时问那个问题:)
  • 用你(失败的)尝试更新你的问题,你更有可能获得帮助,因为这样看起来你并不只是在要求人们为你编写代码。

标签: python html-parsing


【解决方案1】:

handle_starttag 方法包含跟踪主机所需的所有信息。您需要解析网址,因此将其添加到顶部

from urlparse import urlparse

然后在初始化时添加一个容器来保存主机

def __init__(self):
    HTMLParser.__init__(self)
    self.__text = []
    self.hosts = set()

然后,当您在 starttag 中时,抓住主机。 (编辑:错误地将 attr 用作字典

def handle_starttag(self, tag, attrs):
    if tag == 'p':
        self.__text.append('\n\n')
    elif tag == 'br':
        self.__text.append('\n')
    elif tag == 'a':
        for name, value in attrs:
            if name == 'href':
                self.hosts.add(urlparse(value).netloc.split(':')[0].lower())
                break

【讨论】:

  • 谢谢,我试过了,但它仍然不会打印出主机,它完全忽略了文件中的 标记。想法?
  • 我在handle_starttag 中有一个错误,它应该触发了您的异常处理程序。修复后,我成功地从<a href="..."> 标签添加了主机。你可以打印parser.hosts 看看里面有什么。
  • 有趣的是,未更正的并没有触发异常。我尝试了更正的版本并在handle_starttag self.hosts.add(urlparse(attrs['href']).netloc.split(':')[0].lower( )) 类型错误:列表索引必须是整数,而不是 str"
  • 这是我修复的原始错误...确保您运行的是最新版本。如果您的原始测试没有触发错误,则表示您使用的 html 中没有“a”标签。
猜你喜欢
  • 1970-01-01
  • 2018-11-07
  • 2016-01-18
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 2014-10-21
  • 2015-11-02
  • 1970-01-01
相关资源
最近更新 更多