【问题标题】:How to remove duplicate lines from a file and writing them in file in Python如何从文件中删除重复的行并将它们写入 Python 中的文件
【发布时间】:2016-04-10 06:00:14
【问题描述】:

以下代码获取 HTML 文件中的所有链接并将其写入文本文件。但它也在复制重复的行(链接)。有没有办法确保它不会写入文件中已经存在的链接?任何方法这样我就不必手动编写功能了?

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):

    def handle_starttag(self,tag,attrs):
        if tag=="a":
            if attrs.__len__>0:
                for a in attrs:
                    if a[0]=="href":
                        print a[1]
                        f=open("index_link.txt","a+")
                        f.write(a[1]+"\n")

def main():

    parser=MyHTMLParser()
    f=open("index.html")
    if f.mode=="r":
        contents=f.read()
        parser.feed(contents)
    else:
        print ("No file found")
    f=open("textfile.html","w+")
    f.write(contents)

if __name__=="__main__":
    main()

【问题讨论】:

  • 缓存链接写在dict中的链接应该可以工作
  • 保留一组链接并检查链接是否已经在其中?
  • 设置可能有效。检查 set 中的重复的语法是什么?谢谢

标签: python python-2.7 file-handling


【解决方案1】:

使用set()。不要将链接直接写入文件(无论如何效率低下),试试这个:

class MyHTMLParser(HTMLParser):
    def __init(self)__:
        super(HTMLParser, self).__init__()
        self.my_links = set()

    def handle_starttag(self,tag,attrs):
        if tag != "a" or attrs.__len__ == 0:
            return None

        for a in attrs:
            if a[0] == "href":
                self.my_links.add(a[1])

然后检索链接:

parser = MyParser() 
# ... do your parsing here
links = parser.my_links 
with open('path/to/file', 'w') as f:
    for link in list(links):
        f.write(link)

【讨论】:

  • 那么写部分会在main函数中完成吗?而不是在方法中?
  • 在班级级别,没有selfmy_links 无论如何都不应该是类属性。
  • 为什么handle_starttag 返回None
  • 一个集合是无序的。不确定,OP 想要保持订单。
  • writelines 写入不带换行符的链接。
【解决方案2】:

您需要自己记录找到的链接,例如set:

class MyHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.links_found = set()

    def handle_starttag(self,tag,attrs):
        if tag=="a" and attrs:
            for a in attrs:
                if a[0]=="href" and a[1] not in self.links_found:
                    self.links_found.add(a[1])
                    print a[1]
                    with open("index_link.txt","a+") as f:
                        f.write(a[1]+"\n")

如果你想保持链接的顺序,你也可以使用一个简单的列表,而不是直接将它们写入文件:

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.found_links = []

    def handle_starttag(self,tag,attrs):
        if tag=="a":
            attrs = dict(attrs)
            if "href" in attrs and attrs["href"] not in self.found_links:
                self.found_links.append(attrs["href"])

def main():
    parser = MyHTMLParser()
    with open("index.html") as f:
        contents = f.read()
    parser.feed(contents)
    with open("index_link.txt","w") as f:
        f.write('\n'.join(parser.found_links) + '\n')
    with open("textfile.html","w") as f:
        f.write(contents)

if __name__=="__main__":
    main()

【讨论】:

  • 'super(self).__init__' 显示错误,它必须是类型,而不是实例
  • 应该是super(MyHTMLParser, self).__init__()
  • 看看你在做什么。您将链接放入一个集合中,然后立即将其写入文件。这有什么帮助?
  • 另外,每次找到链接时都会重新打开文件。除了健谈和难以阅读之外,这还不必要地低效和复杂。
  • 我明白,但我们不应该努力帮助他吗?他的代码有缺陷,所以我们帮助他修复或至少指出它们。
【解决方案3】:

很简单,只需使用 list 数据类型,即链接列表,这里我使用 html_links 变量

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):

    def __init__(self):
        super(self).__init__
        self.html_links = []
    def handle_starttag(self,tag,attrs):
        if tag=="a":
            if attrs.__len__>0:
                for a in attrs:
                    if a[0]=="href" and a[1] not in self.html_links:
                        print a[1]
                        self.html_links.append(a[1])
                        f=open("index_link.txt","a+")
                        f.write(a[1]+"\n")

def main():
    parser=MyHTMLParser()
    f=open("index.html")
    if f.mode=="r":
        contents=f.read()
        parser.feed(contents)
    else:
        print ("No file found")
    f=open("textfile.html","w+")
    f.write(contents)

if __name__=="__main__":
    main()

【讨论】:

  • Set 可以更快地完成此操作(O(1) 查找时间),并且免费进行重复数据删除,因此您只需将 every 链接添加到该集合并为自己节省一个进入条件。
猜你喜欢
  • 2012-07-07
  • 2011-11-08
  • 2010-10-19
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多