0

我有小的抓取脚本。我有 2000 个名称的文件,我使用这些名称在 YouTube 中搜索视频 ID。由于获取所有ID需要很长时间,所以我不能一次完成。我想要的是找到我最后一次刮擦的位置,然后从那个位置开始。做这个的最好方式是什么?我正在考虑将使用过的名称添加到列表中,然后检查它是否在列表中,如果没有 - 开始抓取,但也许有更好的方法来做到这一点?(我希望是的)。

从文件和抓取的 ID 中获取名称的部分。我想要的是当我退出抓取时,下次我启动它时,它不会从头开始运行,而是从上次结束的地方开始运行:

index = 0
for name in itertools.islice(f, index, None):
    parameters = {'key': api_key, 'q': name}
    request_url = requests.get('https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&type=video&fields=items%2Fid', params = parameters)
    videoid = json.loads(request_url.text)
    if 'error' in videoid:
        pass
    else:
        index += 1
        id_file.write(videoid['items'][0]['id']['videoId'] + '\n')
        print videoid['items'][0]['id']['videoId']
4

2 回答 2

2

您可以只记住最后一次抓取的条目的索引号。每次你完成一个条目的抓取,增加一个计数器,然后假设你的文本文件中的条目没有改变顺序,只是再次拿起那个数字?

于 2013-01-29T00:28:52.380 回答
0

这里最简单的答案可能是mitim的答案。只需在每行之后保留一个使用最后处理的索引重写的文件。例如:

savepath = os.path.expanduser('~/.myprogram.lines') 
skiplines = 0
try:
    with open(savepath) as f:
        skiplines = int(f.read())
except:
    pass
with open('names.txt') as f:
    for linenumber, line in itertools.islice(enumerate(f), skiplines, None):
        do_stuff(line)
        with open(savepath, 'w') as f:
            f.write(str(linenumber))

但是,还有其他方法可以执行此操作,这可能对您的用例更有意义。

例如,您可以在处理每个名称后重写“名称”文件以删除第一行。或者,也许更好的是,将列表预处理到anydbm(甚至sqlite3)数据库中,这样您就可以在完成后更轻松地删除(或标记)名称。

或者,如果您可能针对不同的文件运行,并且需要为每个文件保留一个进度,您可以.lines为每个文件存储一个单独的文件(可能在一个~/.myprogram目录中,而不是淹没顶级主目录),或者使用anydbm映射完成的行的路径名。

于 2013-01-29T01:33:21.690 回答