dataabc / weibo-crawler

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

希望添加根据since_id 作为起始开始爬 #126

Open dduo518 opened 4 years ago

dduo518 commented 4 years ago

根据since_id开始爬的话不会由于各种原因中断之后又要从第一条开始爬 不会py 但是根据自己的需求改了下里面的方法 供参考

def start_page_from_since(self, since_id):
        """获取一页的全部微博"""
        try:
            while True:
                js = self.get_weibo_json_from_since_id(since_id)
                try:
                    id = js['data']['cardlistInfo']['since_id']
                    since_id = id
                except Exception as e: # 如果这里没有拿到 直接重试
                    logger.exception(e)
                logger.info(since_id)
                t = random.randint(2, 5)
                logger.info(u'获取列表休息{}秒'.format(t))
                sleep(t)
                if js['ok']:
                    weibos = js['data']['cards']
                    for w in weibos:
                        if w['card_type'] == 9:
                            wb = self.get_one_weibo(w)
                            if wb:
                                if wb['id'] in self.weibo_id_list:
                                    continue
                                created_at = datetime.strptime(
                                    wb['created_at'], '%Y-%m-%d')
                                since_date = datetime.strptime(
                                    self.user_config['since_date'], '%Y-%m-%d')
                                if created_at < since_date:
                                    if self.is_pinned_weibo(w):
                                        continue
                                    else:
                                        # logger.info(u'{}已获取{}({})的第{}页微博{}'.format(
                                        #     '-' * 30, self.user['screen_name'],
                                        #     self.user['id'], page, '-' * 30))
                                        return True
                                if (not self.filter) or (
                                        'retweet' not in wb.keys()):
                                    # self.weibo.append(wb)
                                    # self.weibo_id_list.append(wb['id'])
                                    # self.got_count += 1
                                    self.write_csv_wb(wb)
                                    self.print_weibo(wb)
                                    t = random.randint(5, 8)
                                    logger.info(u'获取完毕休息{}秒'.format(t))
                                    sleep(t)
                                else:
                                    self.write_csv_wb(wb)
                                    self.print_weibo(wb)
                                    t = random.randint(5, 8)
                                    logger.info(u'获取完毕休息{}秒'.format(t))
                                    sleep(t)
                                    logger.info(u'正在过滤转发微博')
                # logger.info(u'{}已获取{}({})的第{}页微博{}'.format(
                #     '-' * 30, self.user['screen_name'], self.user['id'],
                #     '-' * 30))
        except Exception as e:
            logger.exception(e)

def get_weibo_json_from_since_id(self, since_id):
        """获取网页中微博json数据"""
        params = {
            'containerid': '107603' + str(self.user_config['user_id']),
            'since_id': since_id
        }
        js = self.get_json(params)
        return js

直接调用

       config = get_config()
        wb = Weibo(config)
        # wb.start()  # 爬取微博信息
        wb.get_one_page_from_since("xxxx")
dataabc commented 4 years ago

感谢建议。

建议很好,确实可以通过since_id获取。这种方式有个缺点,就是需要手动指定since_id,这对于部分用户,使用起来可能不如since_date简单,因为since_date是日期,用户能自己定,since_id是微博id,需要用户手动获取。这种方式的优点是当前一次中断时,可以输入上一次最后一个id,接着上次的继续。这种方式作为辅助的方式应该是不错的。 目前程序,如果中断了,可以设置爬取的起始页,修改weibo.py的get_pages方法:

                for page in tqdm(range(1, page_count + 1), desc='Progress'):

range后的大约个1就是起始页,把它替换成上一次中断的页面就可以。

如果还有问题欢迎继续讨论,再次感谢热心建议

dduo518 commented 4 years ago

感谢建议。

建议很好,确实可以通过since_id获取。这种方式有个缺点,就是需要手动指定since_id,这对于部分用户,使用起来可能不如since_date简单,因为since_date是日期,用户能自己定,since_id是微博id,需要用户手动获取。这种方式的优点是当前一次中断时,可以输入上一次最后一个id,接着上次的继续。这种方式作为辅助的方式应该是不错的。 目前程序,如果中断了,可以设置爬取的起始页,修改weibo.py的get_pages方法:

                for page in tqdm(range(1, page_count + 1), desc='Progress'):

range后的大约个1就是起始页,把它替换成上一次中断的页面就可以。

如果还有问题欢迎继续讨论,再次感谢热心建议

这样的话也要从第一页开始获取列表,然后在特定页之后获取内容

dduo518 commented 4 years ago

感谢建议。

建议很好,确实可以通过since_id获取。这种方式有个缺点,就是需要手动指定since_id,这对于部分用户,使用起来可能不如since_date简单,因为since_date是日期,用户能自己定,since_id是微博id,需要用户手动获取。这种方式的优点是当前一次中断时,可以输入上一次最后一个id,接着上次的继续。这种方式作为辅助的方式应该是不错的。 目前程序,如果中断了,可以设置爬取的起始页,修改weibo.py的get_pages方法:

                for page in tqdm(range(1, page_count + 1), desc='Progress'):

range后的大约个1就是起始页,把它替换成上一次中断的页面就可以。

如果还有问题欢迎继续讨论,再次感谢热心建议

一共有4500+页的数据,但是爬到第199页的时候显示

{
    "ok": 0,
    "msg": "这里还没有内容",
    "data": {
        "cards": []
    }
}
dataabc commented 4 years ago

感谢建议。 建议很好,确实可以通过since_id获取。这种方式有个缺点,就是需要手动指定since_id,这对于部分用户,使用起来可能不如since_date简单,因为since_date是日期,用户能自己定,since_id是微博id,需要用户手动获取。这种方式的优点是当前一次中断时,可以输入上一次最后一个id,接着上次的继续。这种方式作为辅助的方式应该是不错的。 目前程序,如果中断了,可以设置爬取的起始页,修改weibo.py的get_pages方法:

                for page in tqdm(range(1, page_count + 1), desc='Progress'):

range后的大约个1就是起始页,把它替换成上一次中断的页面就可以。 如果还有问题欢迎继续讨论,再次感谢热心建议

这样的话也要从第一页开始获取列表,然后在特定页之后获取内容

默认是从第一页,但是你可以把range内的数字换成上一次中断时的页数,程序会从中断时的页数开始运行。

dataabc commented 4 years ago

感谢建议。 建议很好,确实可以通过since_id获取。这种方式有个缺点,就是需要手动指定since_id,这对于部分用户,使用起来可能不如since_date简单,因为since_date是日期,用户能自己定,since_id是微博id,需要用户手动获取。这种方式的优点是当前一次中断时,可以输入上一次最后一个id,接着上次的继续。这种方式作为辅助的方式应该是不错的。 目前程序,如果中断了,可以设置爬取的起始页,修改weibo.py的get_pages方法:

                for page in tqdm(range(1, page_count + 1), desc='Progress'):

range后的大约个1就是起始页,把它替换成上一次中断的页面就可以。 如果还有问题欢迎继续讨论,再次感谢热心建议

一共有4500+页的数据,但是爬到第199页的时候显示

{
    "ok": 0,
    "msg": "这里还没有内容",
    "data": {
        "cards": []
    }
}

说明速度太快了,加上cookie会好点,或者增加sleep时间。