PS:(本人长期出售超大量微博数据、旅游网站评论数据,并提供各类指定数据爬取服务,Message to YuboonaZhang@Yahoo.com。因为微博接口更新后限制增大,这个代码已经不能用来爬数据了。若是只是为了收集数据能够咨询个人邮箱,若是是为了学习爬虫,建议改学phantomjs从网页中爬取微博的)html
<font color=#FF0000 size=4 face="黑体">
2018.5.16 提示
微博的api接口如今已经很差用了,普通权限的token已经爬不到什么数据了,想要用这个代码爬大量数据的已经不太可能,只能做为熟悉微博api接口使用方法的一个小demo了。python
2018.4.16 说明linux
注意:今天有人言语恶劣地评论个人博客是垃圾,说个人代码有问题,这篇博客历史久远,是我初玩爬虫写的博客。我很是感谢能对个人代码提出意见的人,可是出言不逊,态度恶劣的人我是忍受不了的,有话好好说,是一个现代社会高学历高知识分子的最低觉悟。ios
代码我已经改过了,若是还有问题很是欢迎你们来温和地指出!!!!git
同时,因为新浪微博自己api机制的不断更改,到目前为止,这篇博客的内容已经有了局限,对于我的开发者来讲,你申请到的token的权限只能爬你本身的微博,因此对于想要靠api来爬数据的人,恐怕可能并不能达成本身的目的了。想要用api来爬取微博内容只能选择获取更高的开发者权限了。github
</font>web
<br/>mongodb
我主要抓取了大概4天的数据,图上能够看的出来大概有360万条数据,因为是在本身的电脑上爬取作数据的,有时候晚上断网了就间断了,因此大概一天能够爬取有100万左右的最新微博数据(由于我调用的是最新的微博API public_timeline)数据库
API文档当中定义了不少返回的类型(以json数据格式返回,我选取了一些我认为重要的信息抓取下来_如图所示_: 大概有id号,所在位置,粉丝数,发的微博内容,发微博的时间等等。 固然这些数据均可以根据本身的须要进行定制。)json
咱们须要的东西:
MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发。Mongo的官方网站地址是:http://www.mongodb.org/,读者能够在此得到更详细的信息。
小插曲:什么是NoSql?NoSql,全称是 Not Only Sql,指的是非关系型的数据库。下一代数据库主要解决几个要点:非关系型的、分布式的、开源的、水平可扩展的。原始的目的是为了大规模web应用,这场运动开始于2009年初,一般特性应用如:模式自由、支持简易复制、简单的API、最终的一致性(非ACID)、大容量数据等。NoSQL被咱们用得最多的当数key-value存储,固然还有其余的文档型的、列存储、图型数据库、xml数据库等。
建立完毕须要填写手机号验证
<br/>
<br/>
<br/>
初次建立应用须要填写以下信息:
此页面信息不须要填写真实信息,如地区,电话,可随意填写。网站填https://www.baidu.com/便可。(邮箱要真实)
继续建立应用。应用名称自定义,平台以下勾选 ios 、andrioid
建立完毕直接返回继续建立,一个帐号能够建立10个应用,每一个应用对应一个access-token(事实上我只用了一个就能够知足需求)
<br/>
<br/>
依次选取建立的应用。点将下方的token用txt保存便可。
回到
<br/>
点击个人应用
而后选择本身刚刚建立的应用
进入以后点击应用信息
保存下 APP Key 和 APP Secret
点击高级信息
设置回调网址
能够设置成默认的
http://api.weibo.com/oauth2/d...
至此你的开发者帐号就已经完成了
requests和pymongo的安装
能够直接用pip安装
pip install requests 和 pip install pymongo
也能够在Pycharm里面直接安装
选择File -> Settings -> Project -> Project Interpreter
能够看到本身安装的Python库,点击右边的绿色 + 号
安装便可
受权机制说明(很重要)
网上不少讲利用新浪微博API发送微博什么的都是使用的请求用户受权Token这种方式,可是这种方式显然不适用于咱们爬取数据,由于每次都要请求,每次都要从新获取code。具体可参考新浪微博API的受权机制
廖雪峰老师(sinaweibopy 的贡献者)也对这个受权机制有一个说明
经过新浪微博的API接入网站,因为用户无需在您的网站上注册,就能够直接?使用他/她在新浪微博的账号和口令登陆您的网站,这就须要确保您的网站在无需知道,也不能知道用户口令的状况下确认用户已经登陆成功。因为用户的口令存储在新浪微博,所以,认证用户的过程只能由新浪微博完成,但新浪微博如何与您的网站通讯并告知您用户是否登陆成功呢?这个过程称之为第三方登陆,OAuth是一个标准的第三方登陆协议,借助OAuth,您的网站就能够安全地接入来自新浪微博登陆成功的用户。
OAuth目前主要有1.0和2.0两个版本,2.0版对1.0版作了大量简化,API也更简单。新浪微博最新的API也是采用的OAuth 2.0,整个登陆流程以下:
- 用户在您的网站上点击“使用新浪微博登陆”,您的网站将用户重定向到新浪微博的OAuth认证页,重定向连接中包含client_id参数做为您的网站ID,redirect_uri参数告诉新浪微博当用户登陆成功后,将浏览器重定向到您的网站;
- 用户在新浪微博的认证页输入账号和口令;
- 新浪微博认证成功后,将浏览器重定向到您的网站,并附上code参数;
- 您的网站经过code参数向新浪微博请求用户的access token;
- 您的网站拿到用户的access token后,用户登陆完成。
OAuth的access token是提供认证服务的网站(例如新浪微博)生成的令牌,表明一个用户认证信息。在随后的API调用中,传入该access token就表明这个登陆用户,这样,经过OAuth协议,您的网站将验证用户的步骤交给新浪微博完成,并由新浪微博告知您用户是否登陆成功。
OAuth的安全性是经过步骤4完成的,经过code参数获取access token的过程是您的网站后台到新浪微博网站完成的,用户没法看到获取access token的HTTP请求。若是用户传入伪造的code,则新浪微博会返回一个错误。
具体内容请看廖雪峰老师的文档
大体上来讲按照通常的请求用户受权Token调用会出现这种状况:
<br/>
获取code
登录后会调转到一个链接https://api.weibo.com/oauth2/...××××××××
咱们所须要的就是code=×××××××××× 的值
怎么解决问题呢?首先咱们想到的天然是在Python程序里面模拟登陆新浪微博,而后天然能够获取到code的值,可是,模拟新浪微博登陆相对来讲比较复杂,并且既然都模拟登陆成功了,为啥还要调用API呢...直接自定义进行抓取不是更加方便。
若是看了上面的那个受权机制,就应该想到。这个时候就须要咱们以前申请的access-token了
access-token 根据个人理解就是把你的微博受权给了第三方让他帮你作一些事情,相似于在你的手机端经过新浪微博来登陆而后进行操做(利用上面受权机制里面讲的一句话来讲就是)_移动端应用可直接使用官方移动SDK,经过呼起微博客户端(未安装微博客户端的会呼起H5受权页)方式受权_
这个界面你应该很熟悉
新浪也给出了说明Oauth2/access token
有了token以后,实现抓取数据就十分简单了
能抓取数据的多少就取决于你的token权限了
接下来就是利用API来获取数据了:新建一个文件weibo_run.py
# -*- coding:utf-8 -*- import requests from pymongo import MongoClient ACCESS_TOKEN = '2.00ZooSqFHAgn3D59864ee3170DLjNj' URL = 'https://api.weibo.com/2/statuses/public_timeline.json' def run(): #受权 while True: #调用statuses__public_timeline的api接口 params = { 'access_token': ACCESS_TOKEN } statuses = requests.get(url=URL, params=params).json()['statuses'] length = len(statuses) #这是后来我为了查看获取微博条数设置的 print length #链接mongodb,不须要本地的额外配置 Monclient = MongoClient('localhost', 27017) db = Monclient['Weibo'] WeiboData = db['HadSelected'] #获取的各个数据名应该能够清楚的看出来对应的是什么数据 for i in range(0, length): created_at = statuses[i]['created_at'] id = statuses[i]['user']['id'] province = statuses[i]['user']['province'] city = statuses[i]['user']['city'] followers_count = statuses[i]['user']['followers_count'] friends_count = statuses[i]['user']['friends_count'] statuses_count = statuses[i]['user']['statuses_count'] url = statuses[i]['user']['url'] geo = statuses[i]['geo'] comments_count = statuses[i]['comments_count'] reposts_count = statuses[i]['reposts_count'] nickname = statuses[i]['user']['screen_name'] desc = statuses[i]['user']['description'] location = statuses[i]['user']['location'] text = statuses[i]['text'] #插入mongodb WeiboData.insert_one({ 'created_at': created_at, 'id': id, 'nickname': nickname, 'text': text, 'province': province, 'location': location, 'description': desc, 'city': city, 'followers_count': followers_count, 'friends_count': friends_count, 'statuses_count': statuses_count, 'url': url, 'geo': geo, 'comments_count': comments_count, 'reposts_count': reposts_count }) if __name__ == "__main__": run()
刚开始个人代码是这样的,看起来已经完成了。
可是,由于新浪会限制你的调用次数,后来我试了一下从新运行,结果发现了一个问题,我以前的_print length_ 出来的每行获取值都不同,老是在16-20之间徘徊,这说明了我每次从新运行获取的数据都不同.而后我想算了,干脆写个死循环看他何时再被封吧。因而代码就变成了下面这样
把run()删除,换成下面这个死循环。
if __name__ == "__main__": while 1: try: run() except: pass
结果他就一直运行下去了...运行了四天尚未被封,估计是封不了了...
其余接口也是同样使用,只用改变url和params就行,具体参数参照新浪微博API文档
开始我发现一天能够获取800万的数据,把我给乐的...后来发现好多好多重复的数据。最后找了半天的解决方案,在mongodb中根据用户的id和建立的时间这两点创建索引(由于一我的不可能在同一时刻发送两条微博),最后没有重复数据大概一天能够获取100万条左右的信息。
8aoy1.cn