我有一个小的抓取脚本。我有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']
答案 0 :(得分:2)
你可以记住最后一个被删除条目的索引号。每次你完成一个条目的抓取,增加一个计数器,然后假设你的文本文件中的条目不改变顺序,只需再次拿起那个数字?
答案 1 :(得分: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))
但是,还有其他方法可以对您的用例更有意义。
例如,您可以在处理每个名称后重写“names”文件以删除第一行。或者,更好的是,将列表预处理到anydbm
(或甚至sqlite3
)数据库中,这样您就可以在完成后更轻松地删除(或标记)名称。
或者,如果您可能针对不同的文件运行,并且需要为每个文件保持进度,则可以为每个文件存储单独的.lines
文件(可能在~/.myprogram
目录中,而不是充斥顶级主目录),或使用anydbm
映射路径名来完成。