新浪微博爬虫分享(一天可抓取 1300 万条数据)「建议收藏」

From:https://blog.csdn.net/bone_ace/article/details/50903178微博爬虫单机每日千万级的数据微博爬虫总结:https://blog.csdn.net/nghuyong/article/details/81251948Python爬虫——新浪微博(网页版):https://blog.csdn.net/qq_37267015/ar…

大家好,又见面了,我是你们的朋友全栈君。

From:https://blog.csdn.net/bone_ace/article/details/50903178

微博爬虫单机每日千万级的数据 微博爬虫总结:https://blog.csdn.net/nghuyong/article/details/81251948
Python 爬虫——新浪微博(网页版):https://blog.csdn.net/qq_37267015/article/details/71512824

github 地址:https://github.com/LiuXingMing/SinaSpider
github 地址:https://github.com/CUHKSZ-TQL/WeiboSpider_SentimentAnalysis

微博访客 cookie 池

微博爬虫 — 自动获取访客 Cookie:https://cloud.tencent.com/developer/article/1615151

# -*- coding: utf-8 -*-
# @Author  :
# @Date    :
# @File    : add_wb_cookie.py
# @description : XXX


import redis
import json
import random
import requests
import datetime
import multiprocessing
from urllib.parse import quote
from concurrent import futures

#############################################
REDIS_HOST_local = '127.0.0.1'
REDIS_PORT = 6379
REDIS_DB = 0
COOKIE_POOL = 'weibo:cookie'
#############################################

proxy_list = [
    'http://127.0.0.1:8888',
    'http://127.0.0.1:8888',
    'http://127.0.0.1:8888',
]


class WBCookiePool(object):

    def __init__(self):

        self._redis_conn_pool_local = redis.ConnectionPool(
            host=REDIS_HOST_local,
            port=REDIS_PORT,
            db=REDIS_DB
        )
        self.redis_conn_local = redis.StrictRedis(connection_pool=self._redis_conn_pool_local)
        pass

    def __del__(self):
        pass

    @staticmethod
    def get_tid():
        """
            获取 tid,c,w
        :return:tid
        """
        tid_url = "https://passport.weibo.com/visitor/genvisitor"
        data = {
            "cb": "gen_callback",
            "fp": {
                "os": "3",
                "browser": "Chrome69,0,3497,100",
                "fonts": "undefined",
                "screenInfo": "1920*1080*24",
                "plugins": "Portable Document Format::internal-pdf-viewer::Chrome PDF Plugin|::"
                           "mhjfbmdgcfjbbpaeojofohoefgiehjai::Chrome PDF Viewer|::internal-nacl-plugin::Native Client"
            }
        }

        headers = {
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
                          "(KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
        }

        proxy_host = random.choice(proxy_list)
        proxies = {
            'http': proxy_host,
            'https': proxy_host,
        }
        req = requests.post(
            url=tid_url, data=data, headers=headers,
            # proxies=proxies
        )
        if req.status_code == 200:
            ret = eval(
                req.text.replace("window.gen_callback && gen_callback(", "").replace(");", "").replace("true", "1"))
            return ret.get('data').get('tid')
        return None

    def get_cookie(self):
        """
            获取完整的 cookie
        :return: cookie
        """
        tid = self.get_tid()
        if not tid:
            return None
        cookies = {
            "tid": tid + "__095"  # + tid_c_w[1]
        }
        url = f"https://passport.weibo.com/visitor/visitor?a=incarnate&t={quote(tid)}" \
              f"&w=2&c=095&gc=&cb=cross_domain&from=weibo&_rand={random.random()}"
        # print(url)
        headers = {
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
                          "(KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
        }
        proxy_host = random.choice(proxy_list)
        proxies = {
            'http': proxy_host,
            'https': proxy_host,
        }
        req = requests.get(
            url, cookies=cookies, headers=headers,
            # proxies=proxies
        )
        if req.status_code != 200:
            return None

        ret = eval(
            req.text.replace("window.cross_domain && cross_domain(", "").replace(");", "").replace("null", "1"))

        try:
            sub = ret['data']['sub']
            if sub == 1:
                return None
            subp = ret['data']['subp']
        except KeyError:
            return None
        return sub, subp

    def del_expire_cookie(self, max_time_int=None):
        self.redis_conn_local.zremrangebyscore(COOKIE_POOL, min=0, max=max_time_int)

    def add_cookie_2_redis(self):
        count = 0
        while True:
            while True:
                try:
                    sub, sub_p = self.get_cookie()
                    break
                except BaseException as be:
                    print(be)
                    continue

            count += 1

            expire_time = datetime.datetime.now() - datetime.timedelta(minutes=10)
            expire_time_int = int(expire_time.timestamp())
            self.del_expire_cookie(max_time_int=expire_time_int)

            headers = {'cookie': f'SUB={sub};SUBP={sub_p}'}
            print(headers)
            # self.redis_conn.lpush(self.cookie_pool, json.dumps(headers, ensure_ascii=False))

            timestamp_int = int(datetime.datetime.now().timestamp())
            data_string = json.dumps(headers, ensure_ascii=False)
            self.redis_conn_local.zadd(COOKIE_POOL, timestamp_int, data_string, )


def main():
    wb_cookie_pool = WBCookiePool()

    cpu_count = multiprocessing.cpu_count()
    pool = futures.ThreadPoolExecutor(max_workers=cpu_count)
    for i in range(cpu_count):
        pool.submit(wb_cookie_pool.add_cookie_2_redis)


if __name__ == '__main__':
    main()

爬虫功能:

  • 此项目和QQ空间爬虫类似,主要爬取新浪微博用户的个人信息、微博信息、粉丝和关注(详细见此)。
  • 代码获取新浪微博Cookie进行登录,可通过多账号登录来防止新浪的反扒(用来登录的账号可从淘宝购买,一块钱七个)。
  • 项目爬的是新浪微博wap站,结构简单,速度应该会比较快,而且反扒没那么强,缺点是信息量会稍微缺少一些(可见爬虫福利:如何爬wap站)。
  • 爬虫抓取微博的速度可以达到 1300万/天 以上,具体要视网络情况,我使用的是校园网(广工大学城校区),普通的家庭网络可能才一半的速度,甚至都不到。

环境、架构:

开发语言:Python2.7 
开发环境:64位Windows8系统,4G内存,i7-3612QM处理器。 
数据库:MongoDB 3.2.0 
(Python编辑器:Pycharm 5.0.4;MongoDB管理工具:MongoBooster 1.1.1)

  • 主要使用 scrapy 爬虫框架。
  • 下载中间件会从Cookie池和User-Agent池中随机抽取一个加入到spider中。
  • start_requests 中根据用户ID启动四个Request,同时对个人信息、微博、关注和粉丝进行爬取。
  • 将新爬下来的关注和粉丝ID加入到待爬队列(先去重)。

使用说明:

启动前配置:

  • MongoDB安装好 能启动即可,不需要配置。
  • Python需要安装好scrapy(64位的Python尽量使用64位的依赖模块)
  • 另外用到的python模块还有:pymongo、json、base64、requests。
  • 将你用来登录的微博账号和密码加入到 cookies.py 文件中,里面已经有两个账号作为格式参考了。
  • 另外一些scrapy的设置(如间隔时间、日志级别、Request线程数等)可自行在setting里面调。

运行截图:

新浪微博爬虫程序

新浪微博爬虫数据

数据库说明:

SinaSpider主要爬取新浪微博的个人信息、微博数据、关注和粉丝。 
数据库设置 Information、Tweets、Follows、Fans四张表,此处仅介绍前面两张表的字段。

Information 表: 
_id:采用 “用户ID” 作为唯一标识。 
Birthday:出生日期。 
City:所在城市。 
Gender:性别。 
Marriage:婚姻状况。 
NickName:微博昵称。 
Num_Fans:粉丝数量。 
Num_Follows:关注数量。 
Num_Tweets:已发微博数量。 
Province:所在省份。 
Signature:个性签名。 
URL:微博的个人首页。

Tweets 表: 
_id:采用 “用户ID-微博ID” 的形式作为一条微博的唯一标识。 
Co_oridinates:发微博时的定位坐标(经纬度),调用地图API可直接查看具体方位,可识别到在哪一栋楼。 
Comment:微博被评论的数量。 
Content:微博的内容。 
ID:用户ID。 
Like:微博被点赞的数量。 
PubTime:微博发表时间。 
Tools:发微博的工具(手机类型或者平台) 
Transfer:微博被转发的数量。

转载请注明出处,谢谢!(原文链接:http://blog.csdn.net/bone_ace/article/details/50903178

微博爬虫,单机每日千万级的数据 && 吐血整理的微博爬虫总结

前言

此前我发布了一篇博客微博爬虫,每日百万级数据,并且把代码开源在了Github上,然后就有很多人联系我,也有公众号转载了这篇文章。

不过对于微博爬虫,我还是心虚的,因为没有解决账号池的问题,所以每天百万级的数据,是有水分的。单单爬好友关系,这种简单数据可以达到百万级,如果爬关键词搜索的微博,或者一个人的全部微博,是达不到百万级数据这个量的。

不过既然已经埋了坑,就要填!所以自从写了那片文章以后,就一直想构建一个稳定的单机每日千万级的微博抓取系统

值得庆祝的是,这个问题现在已经全面解决了!也对微博爬虫有了更深层次的认识!

微博站点分析

目前微博一共有三个站点,分别是 
https://weibo.cn 
这里写图片描述
https://m.weibo.com 
这里写图片描述
https://weibo.com 
这里写图片描述

可以看到这三个站点的复杂程度是逐渐提高的,很显然,如果能在最简单的weibo.cn完成的抓取,肯定不去复杂的weibo.com上去抓,但是事实上,有的只能在复杂的抓取!

那什么任务是weibo.cn完成不了的呢?可以说,抓取一个人的全部微博,抓取好友关系,抓取个人信息,这些都能在weibo.cn这个站点完成。 
但是,就是有一个任务,weibo.cn实现不了,就是高级搜索

微博高级搜索

可能你经常有这样的需要,比如最近疫苗事件兴起,你要抓取7月10号到7月20号这段时间,提及到疫苗这个关键词的微博

这其实是一个非常刚性的需求,这就要采用微博的高级搜索来完成了。

对于高级搜索接口,微博三个站点的情况是:

weibo.cn

高级搜索入口:https://weibo.cn/search/mblog?advanced=mblog&f=s 
这里写图片描述
可以看到这里可以筛选的条件是,类型,用户,时间,注意,这里的时间是以天为单位。

下面具体搜索一个关键词,疫苗 
这里写图片描述
这里写图片描述

可以看到一页有10条搜索的结果,最多显示100页,也就是1000条结果, 
所以,一次搜索的结果,最多返回1000条微博, 
而这个站点的时间单位是,所以比如搜索的时间段是10天,那么最多能抓取到10*1000=10000条数据。

m.weibo.com

很遗憾这个站点没有高级搜索接口

weibo.com

高级搜索入口:https://s.weibo.com 
这里写图片描述
可以看到这里可以筛选的条件是,类型,用户,时间,地区,注意,这里的时间是以小时为单位。

这里写图片描述

这个站点一页是20条微博,最多50页,所以一次搜索也是最多返回1000条微博数据 
但是这个站点的时间单位是小时, 
所以比如搜索的时间段是10天,那么最多能抓取到10*24*1000=240000条数据。

总结

  • 对于搜索接口,只能选择weibo.com和weibo.cn
  • weibo.com的筛选条件更加丰富,包括了地区,时间段更细,以小时为单位
  • 所以如果希望抓取尽可能多的关键词搜索结果,需要采用weibo.com

所以仅仅高级搜索有可能需要用到weibo.com,并且是你需要的搜索结果数据很大,并且筛选条件很细,比如地区,其他所有爬虫需求都可以通过weibo.cn这个站点来抓取,包括比较粗略的高级搜索

微博抓取经验总结

wiebo.com 还是传统的验证码,5位数的数字字母组合 
这里写图片描述
这种验证码可以通过扫码平台解决。具体的登陆代码参考这里 
不过,由于你买的小号,可能由于频繁操作,被微博盯上了,登陆进去是账号异常,这就会产生非常恶心的验证码,如下图 
这里写图片描述
这种情况,我建议你放弃治疗吧,不要想着破解这种验证码了,所以一般买的小号,不是100%可以用,有一部分是异常账号的!

构建千万级的爬虫系统

根据以上这些分析以后,要想构建千万级别的爬虫系统,只要做一件事情构建账号池

构建账号池的步骤也非常简单: 
1. 购买大量账号 
2. 登陆进微博,保存下cookie 
就这两步,以后每次请求,只要随机从账号池中选择一个账号即可。

对于weibo.cn和weibo.com这两个站点的cookie是不同的,所以要构建两个账号池,一个cn站点的,一个com站点的。

这时候,你结合我之前写的项目WeiboSpider就可以轻松达到每日百万级的数据抓取了!

注意这里实际的抓取速度和你的账号池大小和电脑的带宽有很大关系,如果账号池不大,请求的间隔延迟就需要时间长一点,如果带宽小的话,每次请求的耗时也会长一点

我的数据是, 
账号池里230个账号,每次请求延迟为0.1秒,可以达到一天200~300万的抓取结果。

冲刺千万级

我一直认为,我上面构建的这个爬虫,已经占满了带宽! 
有一次,我又启动了一个爬虫程序,发现另一个爬虫,也可以达到一天200~300万的抓取速度,同时之前的爬虫也是在以一天200~300万的抓取速度在运行, 
所以,仅仅是因为CPU限制了爬虫的抓取量,而不是网络IO!

所以只需要用多进程优化即可,这里推荐Redis-Scrapy,所有的爬虫共享一个Redis队列,通过Redis统一给爬虫分配URL,这样就是一个分布式的抓取系统了。 
可以分别部署在不同的机器上(如果一个机器带宽/CPU占用满了),或者就在一个机器上开多个进程即可。

就这样,我开了5个进程,不敢多开,毕竟账号池还是200多个。

然后结果就是:

这里写图片描述

一分钟可以抓取8000条数据,一天可以达到1100万+

这个抓取系统目前一直在稳定运行

所以就此实现了最初的目标,千万级别的微博爬虫系统

总结

  • 解决微博登陆问题,并构建账号池
  • 通过scrapy-redis框架构建分布式系统
  • 深入分析微博高级搜索需求的解决方案,并编写weibo.cn和weibo.com两个站点的爬虫

至此,可以说,彻底解决了一切关于微博爬虫的问题!!!

开源代码在这里,你需要添加自己的账号池.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/128843.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 关于fmincon和cvx[通俗易懂]

    关于fmincon和cvx[通俗易懂]网上有很多fmincon函数如何使用的,这里不多讲。我主要总结我自己知道的。1.精度问题。在我的使用过程中,感觉cvx和fmincon都有精度限制,到10^(-6)左右就不准了。碰到精度问题,我采取做法是同时乘上一个放大因子10^(10)。2.cvx写起来更方便;3.fmincon目标函数和约束函数都可以有多个输入变量,而不仅仅是需要优化的那个变量,这样当目标函数和约束函数以及主要模

  • GPU利用率低的解决办法

    GPU利用率低的解决办法watch-n0.1-dnvidia-smi#检查GPU利用率参数解决办法:1.dataloader设置参数2.增大batchsize3.减少IO操作,比如tensorboard的写入和打印。4.换显卡

  • 利用java生成uuid

    利用java生成uuid在实际项目中,我们可能想生成一个随机的而且可以保证唯一的标识,比如在给图片命名时,这时就可以采用uuid来生成随机字符串,这个随机字符串基本上是不会出现重复的。什么是UUIDuuid,就是通用唯一识别码的缩写。它的组成比较复杂,是基于当前时间(纳秒级时间)、计数器、硬件标识(通常是MAC地址)以及随机数等组合来生成的,一般情况下,不会生成重复的UUID(重复几率非常小,据概率估计,若每秒产生10亿笔UUID,100年后只产生一次重复的机率是50%),所以,我们大可不必考虑发生重复的问题。它有很多不

  • 英语词汇表

    英语词汇表Aa(an)art.一(个、件……)abandonv.放弃,抛弃abilityn.能力;才能ablea.能够;有能力的abnormala.不正常的aboardprep.在(或上)船,飞机,火车等abolishv.废除abortionn.流产aboutad.大约;到处;四处prep.关于;

  • pycharm运行卡死_pycharm调试快捷键

    pycharm运行卡死_pycharm调试快捷键就跑着跑着莫名其妙卡住,具体表现在左下角的Debugger一片空白,变量监视也啥都没有原链接:https://www.jianshu.com/p/8a8a93c330b5感谢这位大佬!我们在使用PyCharm进行Python代码调试查看具体变量时,会随机遇到一直显示collectingdata,到最后报错Timeoutwaitingforresponse,在界面中看不到变量内部的内容,导致Debug卡死的问题。在PyCharm中,打开Setting界面,在如下设置项中勾选“Geventc

  • paloalto防火墙内存使用率高

    paloalto防火墙内存使用率高

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号