dataabc / weibo-crawler

新浪微博爬虫,用python爬取新浪微博数据,并下载微博图片和微博视频
3.49k stars 772 forks source link

程序报错:KeyError #98

Open SeepenL opened 4 years ago

SeepenL commented 4 years ago

您好,由于我目前只想快速获取列表中所有用户的信息,所以我把get_pages中后半部分爬取微博内容的部分·都注释了,只剩前面get用户信息那两句。 然后当程序爬取大概几十个用户后,就会报这个错然后退出:

用户信息 Error: 'id' Traceback (most recent call last): File "C:/Users/Lzp/Desktop/weibo-crawler-master/weibo.py", line 1005, in get_pages self.print_user_info() File "C:/Users/Lzp/Desktop/weibo-crawler-master/weibo.py", line 531, in print_user_info print(u'用户id:%s' % self.user['id']) KeyError: 'id' Error: 'screen_name' Traceback (most recent call last): File "C:/Users/Lzp/Desktop/weibo-crawler-master/weibo.py", line 1083, in start self.update_user_config_file(self.user_config_file_path) File "C:/Users/Lzp/Desktop/weibo-crawler-master/weibo.py", line 969, in update_user_config_file info.append(self.user['screen_name']) KeyError: 'screen_name'

Error: Expecting value: line 1 column 1 (char 0) Traceback (most recent call last): File "C:/Users/Lzp/Desktop/weibo-crawler-master/weibo.py", line 1004, in get_pages self.get_user_info() File "C:/Users/Lzp/Desktop/weibo-crawler-master/weibo.py", line 208, in get_user_info js = self.get_json(params) File "C:/Users/Lzp/Desktop/weibo-crawler-master/weibo.py", line 119, in get_json return r.json() File "C:\Users\Lzp\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\models.py", line 897, in json return complexjson.loads(self.text, **kwargs) File "C:\Users\Lzp\AppData\Local\Programs\Python\Python36\lib\json__init__.py", line 354, in loads return _default_decoder.decode(s) File "C:\Users\Lzp\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 339, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "C:\Users\Lzp\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 357, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

好像是爬某个人的信息时得到空值了,请问您知道是为什么吗? 这个问题出现的次数非常频繁,基本上每几十个人就出一次,然后就需要把名单前面爬过的人删掉再次运行。。

SeepenL commented 4 years ago

对了,虽然是免cookie版,但我也在config中添加了cookie,所以我觉得可以排除报错是因为权限问题。也许是微博反爬的一种限制?

dataabc commented 4 years ago

感谢反馈,就是速度太快了,降低速度就可以了。因为你只想获取用户的信息,所以需要修改start方法,原来的代码:

            for user_config in self.user_config_list:
                  ......

修改后的代码:

            user_count = 0
            user_count1 = random.randint(1, 5)
            random_users = random.randint(1, 5)
            for user_config in self.user_config_list:
                if (user_count - user_count1) % random_users == 0:
                    sleep(random.randint(6, 10))
                    user_count1 = user_count
                    random_users = random.randint(1, 5)
                user_count += 1
                ......

如果不想获取微博,给since_date一个未来的日期就可以。

SeepenL commented 4 years ago

@dataabc Get it! 果然还是速度太快了。感谢您的帮助!

SeepenL commented 4 years ago

@dataabc 我刚刚又测试了一下,按您提供的代码跑了一遍,以及自己又让每爬一条信息就sleep rand(3, 5),几次下来发现结果和之前是一样的,都是爬取60+条后报错退出。 如果当即再次运行,会立马报相同的错;于是我再次运行前换了一下cookie,发现可以马上运行,但同样是60+条后报错退出。 所以我想这跟速度可能没关系或者说我们还是爬的太快。。有一个cookie池的话才是解决问题的根本办法(笑 如果您能后续能为项目添加一个cookie池的话,就再好不过啦~不过还是很感谢您所有的开源贡献。

dataabc commented 4 years ago

就是速度太快了,加快暂停频率或者增大sleep就可以。

cookie池是个好建议,但是不打算实现。原因是为了避免程序被用来谋利。当前的程序如果控制好速度是可以正确运行的,对个人用户是够用的,但是对想要谋利的人来说就太慢了,这样也就避免了被商用。

感谢反馈,如果还有问题,欢迎继续讨论。

SeepenL commented 4 years ago

@dataabc 好的吧,可能我太心急了hhhh 暂时没有问题了,谢谢您的解答。

gudaocode commented 4 years ago

感谢反馈,就是速度太快了,降低速度就可以了。因为你只想获取用户的信息,所以需要修改start方法,原来的代码:

            for user_config in self.user_config_list:
                  ......

修改后的代码:

            user_count = 0
            user_count1 = random.randint(1, 5)
            random_users = random.randint(1, 5)
            for user_config in self.user_config_list:
                if (user_count - user_count1) % random_users == 0:
                    sleep(random.randint(6, 10))
                    user_count1 = user_count
                    random_users = random.randint(1, 5)
                user_count += 1
                ......

如果不想获取微博,给since_date一个未来的日期就可以。

请问,如果只获取图片和视频,但是不爬取微博内容等信息的话,应该如何修改?

dataabc commented 4 years ago

@gudaost

获取微博和不获取,效率都是一样的,如果不想要直接删去就可以。如果要修改代码的话,可以把写文件的代码注释掉,只保留下载图片和视频的部分。write_data方法是写文件的,可以把出图片、视频之外的去掉

        if self.got_count > wrote_count:
            if self.original_pic_download:
                self.download_files('img', 'original', wrote_count)
            if self.original_video_download:
                self.download_files('video', 'original', wrote_count)
            if not self.filter:
                if self.retweet_pic_download:
                    self.download_files('img', 'retweet', wrote_count)
                if self.retweet_video_download:
                    self.download_files('video', 'retweet', wrote_count)
gudaocode commented 4 years ago

好的,多谢!我的也在不停Error,按您的意见修改等待时长中……目前用等待(10,15)

gudaocode commented 4 years ago

按前面修改后,报错不一样了,但是下载中断了 微博正文:唐汉霄超话把近在眼前的有限和远在天边的无限放入音乐🎶 @唐漢霄 谢谢你加入《拾伍》,华语乐坛独创一格的新锐唱作人�Traceback (most recent call last): File "weibo.py", line 654, in get_one_page self.print_weibo(wb) File "weibo.py", line 575, in print_weibo print('-' * 120) OSError: [WinError 87] 参数错误。

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "weibo.py", line 1014, in get_pages is_end = self.get_one_page(page) File "weibo.py", line 662, in get_one_page print("Error: ", e) OSError: [WinError 87] 参数错误。

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "weibo.py", line 1082, in start self.get_pages() File "weibo.py", line 1034, in get_pages print("Error: ", e) OSError: [WinError 87] 参数错误。

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "weibo.py", line 1112, in main wb.start() # 爬取微博信息 File "weibo.py", line 1088, in start print('Error: ', e) OSError: [WinError 87] 参数错误。

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "weibo.py", line 1119, in main() File "weibo.py", line 1114, in main print('Error: ', e) OSError: [WinError 87] 参数错误。 微博正文:唐汉霄超话把近在眼前的有限和远在天边的无限放入音乐🎶 @唐漢霄 谢谢你加入《拾伍》,华语乐坛独创一格的新锐唱作人�Exception ignored in: <_io.TextIOWrapper name='' mode='w' encoding='utf-8'> OSError: [WinError 87] 参数错误。 微博正文:唐汉霄超话把近在眼前的有限和远在天边的无限放入音乐🎶 @唐漢霄 谢谢你加入《拾伍》,华语乐坛独创一格的新锐唱作人�微博正文:唐汉霄超话把近在眼前的有限和远在天边的无限放入音乐🎶 @唐漢霄 谢谢你加入《拾伍》,华语乐坛独创一格的新锐唱作人�

dataabc commented 4 years ago

@gudaost 像上面这样包含特殊符号的微博在一些系统中可能会打印出错, 把get_one_page方法中的self.print_weibo(wb)注释掉就可以了,它负责打印微博,注释后可以获取微博只是不再打印出来。

gudaocode commented 4 years ago

昨晚睡觉前又做了次尝试,id文件中一共200多个,之前成功了90个/行,把代码按照您说的做了如下修改: user_count = 0 user_count1 = random.randint(1, 10) random_users = random.randint(1, 10) for user_config in self.user_config_list: if (user_count - user_count1) % random_users == 0: sleep(random.randint(10, 15)) user_count1 = user_count random_users = random.randint(1, 10) user_count += 1

运行了之后,结果依旧是Error,而且出现的时候依旧是在第91个,即一个新的id都没有下载。 还要把某个数字调大吗?

gudaocode commented 4 years ago

另外,刚才把前面90个已经下载过的移动出来,把id list变成所有都是没有下载过的(即后面都没有日期),现在开始下载了 结果过一阵再反馈

gudaocode commented 4 years ago

这次爬了111个,最末尾一个的效果是: `Ninemuses朴景丽首站 信息写入csv文件完毕,保存路径: D:\YunData\我的坚果云\Program Files\Pic_Follow_WeiBo\免Cookie版(使用中)\weibo\users.csv ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 用户信息 用户id:5384960865 用户昵称:Ninemuses朴景丽首站 性别:女 生日:1990-07-05 巨蟹座 所在地:其他 教育经历: 公司: 阳光信用:信用较好 注册时间:2014-11-22 微博数:504 粉丝数:1927 关注数:27 url:https://m.weibo.cn/profile/5384960865 朴倞利中国粉丝,感谢关注! ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Progress: 0%| | 0/51 [00:00<?, ?it/s]------------------------------已获取Ninemuses朴景丽首站(5384960865)的第1页微博------------------------------ Progress: 0%| | 0/51 [00:00<?, ?it/s] 微博爬取完成,共爬取0条微博 信息抓取完毕


Error: [Errno 13] Permission denied: 'D:\某中文路径\user_id_list.txt' Traceback (most recent call last): File "weibo.py", line 1086, in start self.update_user_config_file(self.user_config_file_path) File "weibo.py", line 955, in update_user_config_file with open(user_config_file_path, 'rb') as f: PermissionError: [Errno 13] Permission denied: 'D:\某中文路径\user_id_list.txt'`

gudaocode commented 4 years ago

再次把已经爬完的id行删除,运行,又可以继续了 是不是一次爬的太多了的问题?? 修改哪些才能一次都爬完呢?这样折腾有点麻烦的说,还是增加某个时间吗?

gudaocode commented 4 years ago

再次尝试: 把全部264个放到id文档中 其中前90行的日期未20日(昨天),后面的为今天 间隔时长代码为: user_count = 0 user_count1 = random.randint(1, 10) random_users = random.randint(1, 10) for user_config in self.user_config_list: if (user_count - user_count1) % random_users == 0: sleep(random.randint(10, 15)) user_count1 = user_count random_users = random.randint(1, 10) user_count += 1 Cookie已经添加(昨天添加)

再次运行 结果到41行运行完毕,日期变为21日,再次暂停,提示为 `微博爬取完成,共爬取0条微博 信息抓取完毕


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 用户信息 Error: 'id' Traceback (most recent call last): File "weibo.py", line 1003, in get_pages self.print_user_info() File "weibo.py", line 529, in print_user_info print(u'用户id:%s' % self.user['id']) KeyError: 'id' 信息抓取完毕


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 用户信息 Error: 'id' Traceback (most recent call last): File "weibo.py", line 1003, in get_pages self.print_user_info() File "weibo.py", line 529, in print_user_info print(u'用户id:%s' % self.user['id']) KeyError: 'id' 信息抓取完毕


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 用户信息 Error: 'id' Traceback (most recent call last): File "weibo.py", line 1003, in get_pages self.print_user_info() File "weibo.py", line 529, in print_user_info print(u'用户id:%s' % self.user['id']) KeyError: 'id' 信息抓取完毕


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 用户信息 Error: 'id' Traceback (most recent call last): File "weibo.py", line 1003, in get_pages self.print_user_info() File "weibo.py", line 529, in print_user_info print(u'用户id:%s' % self.user['id']) KeyError: 'id' 信息抓取完毕


Error: [Errno 13] Permission denied: 'D:\某中文路径\user_id_list.txt' Traceback (most recent call last): File "weibo.py", line 1086, in start self.update_user_config_file(self.user_config_file_path) File "weibo.py", line 955, in update_user_config_file with open(user_config_file_path, 'rb') as f: PermissionError: [Errno 13] Permission denied: 'D:\某中文路径\user_id_list.txt'`

注意:前面几个错误提示一样,最后一个的提示不同

dataabc commented 4 years ago

昨晚睡觉前又做了次尝试,id文件中一共200多个,之前成功了90个/行,把代码按照您说的做了如下修改:

user_count = 0 user_count1 = random.randint(1, 10) random_users = random.randint(1, 10) for user_config in self.user_config_list: if (user_count - user_count1) % random_users == 0: sleep(random.randint(10, 15)) user_count1 = user_count random_users = random.randint(1, 10) user_count += 1 运行了之后,结果依旧是Error,而且出现的时候依旧是在第91个,即一个新的id都没有下载。 还要把某个数字调大吗?

random_users改犯了,它的意思是让程序每隔多少页sleep,你现在是每1-10页sleep,很多时候程序爬了7、8页才sleep,太快,你应该让random_users越小越好,如果直接等于1就是每爬一页暂停一次,这是最快的暂停频率

dataabc commented 4 years ago

PermissionError错误说明是权限问题,程序没有权限写入文件,可能是因为user_id_list.txt已经被打开了,也可能是其它原因。

KeyError错误还是太快了,程序获取失败,却又尝试取不存在的key,所以出错。

gudaocode commented 4 years ago

PermissionError错误说明是权限问题,程序没有权限写入文件,可能是因为user_id_list.txt已经被打开了,也可能是其它原因。

KeyError错误还是太快了,程序获取失败,却又尝试取不存在的key,所以出错。

多谢!暂时问题都解决了!感谢感谢!