前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微博话题爬虫更新:支持小时级别的搜索和爬完自动停止

微博话题爬虫更新:支持小时级别的搜索和爬完自动停止

作者头像
月小水长
发布2020-11-09 15:40:08
1.5K0
发布2020-11-09 15:40:08
举报
文章被收录于专栏:月小水长月小水长

距离上次微博超级爬虫更新已经过去三个月了,很多人以为我放弃这个项目了,实际上我太忙(难)了。

上个周末整理了微博话题爬虫 WeiboTopicSpider,在 issue 里看到一个同学说可以支持小时级别的搜索了,我开始试试了貌似并不可以,或者说并不准确,和我很久以前尝试的一样,爬取的微博时间跨度并没有和给定的 start_time 和 end_time 范围一致,经过一番捣鼓,终于探得其中奥秘。

先来给这个微博超级爬虫仓库求个 star

https://github.com/Python3Spiders/WeiboSuperSpider

点击红框中的 star,就是对一个开源爱好者最大的鼓励。

首先明确一点,微博话题爬虫一直是可以支持小时级别(格式诸如 2020-11-01-05)的搜索了,只是我们一直不知道使用方式,

比如,我们想要搜索 2020-10-31 04 点到 2020-10-31 05 点关于 S10 的所有原创微博,我们应该这样给定参数

WeiboTopicScrapy(keyword=keyword,filter=1,start_time='2020-10-30-20',end_time='2020-10-29-21')

一脸懵逼就对了,其实这个以前传入的时间参数和实际执行搜索的时间参数有以下关系,经过演绎推理即可得出

实际的 start_time = 以前传入的 start_time + 8hour 实际的 end_time = 以前传入的 end_time + 1day + 8hour

严重怀疑是不是服务器不在国内,或者这个规则只对国内的使用者有生效,待确认中,麻烦美国等地的读者试一下给我反馈。

那么问题又来了,每次这样自己手动换算后再传入参数,有点麻烦,于是我将这部分逻辑也写进程序了,

代码语言:javascript
复制
def time_params_formatter(params_time, offset_day=0, offset_hour=-8):
    [temp_year, temp_month, temp_day, temp_hour] = [int(e) for e in params_time.split('-')]
    temp_date = datetime(year=temp_year, month=temp_month, day=temp_day, hour=temp_hour)
    temp_offset = timedelta(days=offset_day,hours=offset_hour)
    res_time = (temp_date + temp_offset).strftime('%Y-%m-%d-%H')
    return res_time

在 WeiboTopicSpider 类内部自动做了处理

代码语言:javascript
复制
self.start_time = time_params_formatter(start_time, offset_hour=-8) # 原来是 = start_time
self.end_time = time_params_formatter(end_time, offset_day=-1, offset_hour=-8) # 原来是 = end_time

上次搜索过程就可以直观地表示为:

代码语言:javascript
复制
start_time, end_time = '2020-10-31-04', '2020-10-31-05'
if start_time>=end_time:
    raise Exception('start_time 是离现在更远的那个时间,必须小于 end_time')
WeiboTopicScrapy(keyword=keyword, filter=1, start_time=start_time, end_time=start_time)

就是上面那个公式的逆过程,求出我们想要搜索的时间范围对应的真正的时间范围,话比较啰嗦,一句话,就是你在新的代码里修改 start_time,end_time='2020-10-31-04','2020-10-31-05'这一行的时候,改成你自己想要的时间范围即可,具体的细节程序自动转换。

实际的 start_time = 现在传入的 start_time 实际的 end_time = 现在传入的 end_time 还有,小时是最最最细粒度的搜索了,分钟和秒就不行了,至少我尝试了 N 次是这样。

最后,加了一个爬完自动结束的功能,在类内部加了三行代码:

代码语言:javascript
复制
if len(weibos) == 0:
    print('自动结束,大概率是因为内容爬完了,也请留意是否是 cookie 失效等情况\n')
    break
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 月小水长 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档