新浪微博网页版微信登录入口 新浪微博网页版 新浪网页版电脑版

前言:本次爬取的是新浪微博移动端(http://m.weibo.cn/) , 爬取的数据是用户微博首页的第一条微博(如下图) , 包括文字内容、转发量、评论数、点赞数和发布时间 , 还有用户名和其所在地区(后面可以分析不同地区微博用户的关心的热点话题) 。

新浪微博网页版微信登录入口 新浪微博网页版 新浪网页版电脑版

文章插图
开发工具【新浪微博网页版微信登录入口 新浪微博网页版 新浪网页版电脑版】Python版本:3.6
相关模块:
import scrapyfrom sinaweibo.items import SinaweiboItemimport jsonimport reimport copy分析网页浏览发现使用的是使用Ajax渲染的网页 , 微博数据(http://m.weibo.cn/api/container/getIndex?containerid=102803_ctg1_5088-ctg1_5088&openApp=0&since_id=1)存储在json格式网页中 , 所以思路是先通过微博数据得到用户url(如下图) , 再来爬取后续内容 。
新浪微博网页版微信登录入口 新浪微博网页版 新浪网页版电脑版

文章插图
获取第一条微博数据
也是使用了Ajax渲染的网页 , 跟上面一样找到网页入口就行了 。请求网址如下:
新浪微博网页版微信登录入口 新浪微博网页版 新浪网页版电脑版

文章插图
这样看网址的话毫无规律可言 , 简化后发现 http://m.weibo.cn/api/container/getIndex?containerid=1076032554757470就可以进入 。而且containerid=107603(***)这里 , 括号里的数字刚好是用户的id号 , 因此我们可以通过这个来构造网页 。
获取用户所在地区用户所在地在其基本资料中 , 如下图
新浪微博网页版微信登录入口 新浪微博网页版 新浪网页版电脑版

文章插图
地址为:
新浪微博网页版微信登录入口 新浪微博网页版 新浪网页版电脑版

文章插图
同样进行简化得到:http://m.weibo.cn/api/container/getIndex?containerid=230283(***)-INFO其中括号里面是用户id号 。
通过以上分析可知 , 获取用户的 id 号是本次爬取数据的关键 , 只需要用 id 构成网址 , 后面的爬取就相对简单了 。下面是编程部分 。
编程爬取items.py定义爬虫字段
import scrapy'''遇到不懂的问题?Python学习交流群:821460695满足你的需求 , 资料都已经上传群文件 , 可以自行下载!'''class SinaweiboItem(scrapy.Item):define the fields for your item here like:name = scrapy.Field() name = scrapy.Field() 用户名 first_news = scrapy.Field() 首条微博 dates = scrapy.Field() 发布时间zhuanzai = scrapy.Field() 转载数 comment = scrapy.Field() 评论数 agree = scrapy.Field() 点赞数 city = scrapy.Field() 所在地区编写爬取代码
-*- coding: utf-8 -*-import scrapyfrom sinaweibo.items import SinaweiboItemimport jsonimport reimport copy'''遇到不懂的问题?Python学习交流群:821460695满足你的需求 , 资料都已经上传群文件 , 可以自行下载!'''class WeibodiyuSpider(scrapy.Spider): name = 'weibodiyu' 爬虫名 allowed_domains = ['m.weibo.cn'] 只在该域名内爬取 start_urls = ['http://m.weibo.cn/api/container/getIndex?containerid=102803_ctg1_4188_-_ctg1_4188&openApp=0&since_id=1' ]? def parse1(self, response): infos = json.loads(response.body) 将内容转为json对象 item = response.meta['item'] 利用meta方法传入item city = response.meta['city'] 传入城市 try: name = infos["data"]["cards"][0]["mblog"]["user"]["screen_name"] 爬取名字 first_news = re.findall('([\u4e00-\u9fa5]+)', str(infos["data"]["cards"][0]["mblog"]["text"]), re.S) 爬取微博内容 , 使用正则去除一些杂项如网页代码 dates = infos["data"]["cards"][0]["mblog"]["created_at"] 发布时间 zhuanzai = infos["data"]["cards"][0]["mblog"]["reposts_count"] 转载数 comment = infos["data"]["cards"][0]["mblog"]["comments_count"] 评论数 agree = infos["data"]["cards"][0]["mblog"]["attitudes_count"] 点赞数 将数据赋给item item['name'] = name item['first_news'] = first_news item['dates'] = dates item['zhuanzai'] = zhuanzai item['comment'] = comment item['agree'] = agree item['city'] = city return item 返回 except IndexError or KeyError: pass? def parse2(self, response): 获取所在地区函数 infos = json.loads(response.body) try: item = response.meta['item'] 传入item city_cont = str(infos["data"]["cards"][1]["card_group"]) city = re.findall('card_type.*?所在地.*?item.*?:(.*?)}]', city_cont, re.S)[0].replace('\'', '').replace( ' ', '') 城市 item['city'] = city ids = response.meta['ids'] 传入id并赋给ids变量 n_url1 = 'http://m.weibo.cn/api/container/getIndex?&containerid=107603' + ids yield scrapy.Request(n_url1, meta={'item': item, 'city': copy.deepcopy(city)}, callback=self.parse1) 执行完上述命令后的步骤 except IndexError or KeyError: pass? def parse(self, response): datas = json.loads(response.body) item = SinaweiboItem() for i in range(0, 20): try: ids = str(datas["data"]["cards"][i]["mblog"]["user"]["id"]) 获取用户id n_url2 = 'http://m.weibo.cn/api/container/getIndex?containerid=230283{}_-_INFO'.format(ids) yield scrapy.Request(n_url2, meta={'item': item, 'ids': copy.deepcopy(ids)}, callback=self.parse2) 进入parse2函数执行命令 except IndexError or KeyError: pass social_urls = [ 'http://m.weibo.cn/api/container/getIndex?containerid=102803_ctg1_4188_-_ctg1_4188&openApp=0&since_id={}'.format( str(i)) for i in range(2, 100)] celebritys_urls = [ 'http://m.weibo.cn/api/container/getIndex?containerid=102803_ctg1_4288_-_ctg1_4288&openApp=0&since_id={}'.format( str(j)) for j in range(1, 100)] hots_urls = ['http://m.weibo.cn/api/container/getIndex?containerid=102803&openApp=0&since_id={}'.format(str(t)) for t in range(1, 100)] urls = celebritys_urls + social_urls + hots_urls 入口网址 for url in urls: yield scrapy.Request(url, callback=self.parse)这里要注意 scrpay.Request 函数的meta参数 , 它是一个字典 , 用来进行参数传递 , 如上面代码所示 , 我想在parse2()函数中用到parse()函数中爬取的用户id , 就需要进行设置 , 这里就不过多解释了 , 其实我也是处于摸着石头过河的理解程度 , 想深入了解的朋友可自行百度 。