Python 迭代地重新检查一个巨大的列表

Python 迭代地重新检查一个巨大的列表,python,Python,我的计算机中保存了大约100000个URL的列表。这10万人可以很快增加到几百万人。对于每个url,我检查该网页并收集该网页上的所有附加url,但前提是每个附加链接都不在我的大列表中。这里的问题是迭代地将这个巨大的列表重新加载到内存中,这样我就可以始终得到一个准确的列表。使用的内存量可能很快就会变得太多,更重要的是,重新加载列表之间的时间变得更长,这严重阻碍了项目的进度 我的列表以几种不同的格式保存。一种格式是将所有链接包含在一个文本文件中,我打开filetext.readlines将其直接转换

我的计算机中保存了大约100000个URL的列表。这10万人可以很快增加到几百万人。对于每个url,我检查该网页并收集该网页上的所有附加url,但前提是每个附加链接都不在我的大列表中。这里的问题是迭代地将这个巨大的列表重新加载到内存中,这样我就可以始终得到一个准确的列表。使用的内存量可能很快就会变得太多,更重要的是,重新加载列表之间的时间变得更长,这严重阻碍了项目的进度

我的列表以几种不同的格式保存。一种格式是将所有链接包含在一个文本文件中,我打开filetext.readlines将其直接转换为列表。我保存的另一种似乎更有用的格式是保存一个包含所有链接的文件夹树,并使用os.walkpath将其转换为列表


我真的不确定有没有其他方法可以更有效地执行这种重复的条件检查,而不需要荒谬地使用内存和加载时间。我也尝试过使用队列,但是能够看到这些链接的文本输出是一个很大的好处,因此队列变得非常复杂。我还能从哪里开始呢?

主要问题是不能在内存中加载列表。这应该只在开始时做一次,然后再废弃网页。问题是查找列表中是否已经存在元素。对于大型列表,正在运行的将太长

你应该试着研究几个问题;其中有布景和熊猫。第一个可能是最佳解决方案


现在,既然您考虑使用URL作为文件夹名称的文件夹树,我可以想出一种更快的方法。不要使用os.walkpath创建列表,而是尝试查看文件夹是否已存在。如果没有,则表示您还没有该url。这基本上是一个假的图形数据库。为此,可以使用函数os.path.isdir。如果您想要一个真正的图形数据库,您可以查看OrientDB。例如,内存不应该是一个问题。如果每个url需要1KB存储在内存中,那么100万个url将是1GiB。你说你有8吉布的公羊

您可以将已知的URL保存在内存中,并检查是否在中使用包含。Python的集合使用散列,因此对包含的搜索是O1,这通常比列表的线性搜索快得多

您可以递归地刮取页面:

def main():
    with open('urls.txt') as urls:
        known_urls = set(urls)

    for url in list(known_urls):
        scrape(url, known_urls)


def scrape(url, known_urls):
    new_urls = _parse_page_urls(url)
    for new_url in new_urls:
        if new_url not in known_urls:
            known_urls.add(new_url)
            scrape(new_url, known_urls)

您是否考虑过将IP地址表映射到URL?当然,只有在同一个域上寻找唯一的域而不是数千个页面时,这才有效。这样做的好处是,您将处理12个整数地址。缺点是需要额外的表格数据结构和额外的过程来映射数据。

链接需要使用多少内存?你有多少公羊?我不认为几百万个链接会是内存问题。把它们放在一组内存中。保守一点,如果一个链接使用1KB,那么100万个链接就是1GB。老实说,我不确定,也许内存没有我想象的那么大。我有8g内存,但我还没有做到这一点,因为加载整个列表需要多长时间。@JilliamWones字符串列表加载的时间不应该太长。领先几秒。你能分享你的代码吗?这里真的是内存问题,还是你试图反复查找列表中是否存在某个条目?你每次都会从文件中重读这个列表?你有没有试过在记忆中保留一套?如果内存也是一个问题,如果许多URL共享一个更大的网页上的子页面之类的公共部分,那么你也可以考虑使用一个前缀树/TIE。如果你从URL中去掉路径、查询、协议等,那么在某些情况下,你几乎可以节省很多,就像在转换到IP时一样,这可能要简单得多。