爬虫-今日头条我的收藏-增量式(二)
背景:
能够全量爬取今日头条我的收藏内容之后,新收藏的内容依然希望能够保存到新文件中。
思路:
- 每次都全量爬取数据太耗时,增量式爬取可以节省时间。但逻辑上显然要复杂一些。关键的问题是要找到断点的位置。
- 取消收藏的影响:爬虫旧文件用户收藏的链接有可能被取消收藏。所以在断点位置的判断上不能只取一条数据的id作为参考,考虑取连续100条的我的收藏id作为判断基准,这样即便用户偶尔取消收藏几条,依然能够准确找到断点。
- 增量式功能可以覆盖全量下载我的收藏。第一次下载由于没有断点,需要全量下载。后续由于已经有下载的文件作为参照物,只需要从参照物继续下载。
- 每次运行增量爬虫,如果有新内容,则新增一个文件,文件格式:myfavorites-年月日-时分秒.txt。如果没有新内容,不需要新增文件。
- 代码参考这里:https://github.com/pmh905001/myfavorite/blob/master/toutiao/increasmentdownload.py .主代码如下:
def increasement_download(): url, headers = read_curl() latest_ids_downloaded = latest_ids_from_file() page = get_page(url, headers, 0, latest_ids_downloaded) try_num = 0 file_name = f'myfavorites-{time.strftime("%Y%m%d-%H%M%S")}.txt' while page['has_more']: try_num += 1 max_behot_time = page['next']['max_behot_time'] write_page(page, file_name) sleep_time = random.randint(1, 10) print(f'-------------------------------------------page number: {try_num}, sleep {sleep_time} seconds') time.sleep(sleep_time) page = get_page(url, headers, max_behot_time, latest_ids_downloaded) else: write_page(page, file_name)
- 从断点处按照有新到旧的id需要获取最多100条,这种情况下需要遍历所有myfavorites-年月日-时分秒.txt的文件且需要倒序排列,依次读取id直到100条(用户可以自己调整)。参考latest_ids_from_file()
def latest_ids_from_file(): ids = [] my_favorite_files = sorted([f for f in os.listdir('.') if f.startswith('myfavorites-')], reverse=True) for file_name in my_favorite_files: with open(file_name, 'r', encoding='utf-8') as f: page: dict = json.loads(f.readline()) if page.get('data'): for record in page['data']: if len(ids) <= 100: ids.append(record['id']) else: return ids return ids
- 在获取每页的数据之后,需要找到断点,把冗余的数据给删除。重置has_more=False。参考get_page()方法
def get_page(url, headers, max_behot_time=0, latest_ids_downloaded=[]): url = replace_url_param(url, 'max_behot_time', max_behot_time) response = requests.get(url, headers=headers) page: dict = response.json() if page.get('data'): for index, record in enumerate(page.get('data')): if record['id'] in latest_ids_downloaded: page['data'] = page['data'][:index] page['has_more'] = False
- 在写文件的时候,如果页数据收藏列表如果为空,则不写入文件。参考write_page()
def write_page(page, file_name): if not page.get('data'): return with open(file_name, 'a', encoding='utf-8') as fp: page_info = json.dumps(page, ensure_ascii=False) fp.write(page_info) fp.write('\n') for item in page['data']: try: print(f"{item['id']}: {item['title']} => {item['share_url']}") # Fixme: UnicodeEncodeError except UnicodeEncodeError: logging.exception('occurred exception when print')
- 代码写的比较粗糙,还需要找时间重构。这里仅供参考
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人