NO.5——分析Ajax请求爬取新浪微博的相关数据

       新浪微波早已称为我每天都会登陆上去刷新一下消息的APP,除了看看比较好玩的东西,还会看看好友在更新些在朋友圈看不到的东西,今天,就试着写爬虫爬取些微博的相关数据,比如微博正文、点赞数、评论数、转发数等等,最后把这些数据保存在mongodb数据库中。

       一、分析

       以女友的微博主页为例,在实际操作中发现,在开发者模式的Network选项卡下,查看第一个请求的Response:


         从图上可见,这个页面里的内容结构非常简单,只是执行了JavaScript操作,这些内容并不是我们需要的原始内容返还的,而是执行JavaScript后向服务器发送Ajax请求,浏览器拿到数据后渲染出来的。何为Ajax,也就是异步的JavaScript和XML。比如,当你在刷微博时,整个页面并不是一开始全部被渲染出来,而是微博底部会有一个刷新箭头,当你不断下滑鼠标,页面才会逐渐被渲染出来。这是一种异步数据加载方式,当最初页面的数据加载完成,会再向服务器某个接口请求获取数据,然后数据经JavaScript处理呈现出来,这种方法的好处就是采用分步渲染的方式,降低了服务器直接渲染整个页面的压力。

        在返回的所有请求中,我看到一个以getIndex开头的请求,请求类型Type是xhr,这就是Ajax的请求类型。


        然后点击打开查看请求头Request Headers里的内容,有一个X-Requested-With:XMLHttpRequest信息,这标记的就是Ajax的请求。


          二、过滤

             既然已经知道了微博应用了Ajax渲染技术,那么如何从被Ajax渲染出的页面获取原始请求呢?

             在请求页面,直接选择以XHR筛选,获得所有Ajax的请求,选取其中一个getIndex请求,打开:


                                     在General里边,这是一个GET类型的请求,请求链接是https://m.weibo.cn/api/container/getIndex?type=uid&value=1976069377&containerid=1076031976069377。里边有三个参数类型:type、value、containerid。刷新微博,再打开一个GET类型的请求,发现,请求链接变为https://m.weibo.cn/api/container/getIndex?type=uid&value=1976069377&containerid=1076031976069377&page=2

前边三个参数没有变,后边多了一个page参数,可见这个page参数代表的页码,控制分页。而前边value是用户的ID,而containerid是107603+用户ID,type类型始终没变是uid。

继而打开Preview选项卡,里边存放的便是我所需要的内容。这个内容是JSON格式的,JSON 按照 "名称 / 值对"的方式{ "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },可以将 JavaScript 对象中表示的一组数据转换为字符串。

在data下边存放着两个主要信息:cardlistInfo和cards。在每个请求里边包含10个元素信息,说明每次刷新刷新10条微博。在cards的mblog里边,我看到了我需要爬取的信息,attitudes_count(点赞数目)、comments_count(评论数目)、created_at(发布时间)、reposts_count(转发数目)、text(微博正文)。

      

    

             这样,大体的分析完成,现在只要向服务器请求一个接口,就可以得到10条微博信息。之后只要构造一个遍历,通过改变page参数,就可以获得所有微博数据。

     三、代码

 
 
import requests
from urllib.parse import urlencode
from pyquery import PyQuery as pq
from pymongo import MongoClient

base_url = 'https://m.weibo.cn/api/container/getIndex?'
headers = {
    'Host': 'm.weibo.cn',
    'Referer': 'https://weibo.com/u/1976069377',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest',
}
client = MongoClient()
db = client['weibo']
collection = db['weibo']
max_page = 10

 #构造General里Request URL请求  Request URL:https://m.weibo.cn/api/container/getIndex?type=uid&value=1976069377&containerid=1076031976069377&page=2
def get_page(page):
    params = {
        'type': 'uid',
        'value': '1976069377',
        'containerid': '1076031976069377',
        'page': page
    }
    url = base_url + urlencode(params)    
    try:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.json()
    except requests.ConnectionError as e:
        print('Error', e.args)

#获取Preview选项卡里的JSON数据
def parse_page(json):
    if json:
        items = json.get('data').get('cards')
        for item in items:
            item = item.get('mblog')
            weibo = {}
            weibo['id'] = item.get('id')
            weibo['text'] = pq(item.get('text')).text()   #输出文字信息先用pq解析
            weibo['attitudes'] = item.get('attitudes_count')
            weibo['comments'] = item.get('comments_count')
            weibo['reposts'] = item.get('reposts_count')
            yield weibo


def save_to_mongo(result):
    if collection.insert(result):
        print('Saved to Mongo')


if __name__ == '__main__':
    for page in range(1, max_page + 1):
        json = get_page(page)
        results = parse_page(json)
        for result in results:
            print(result)
            save_to_mongo(result)


         四:结果


      哈哈。这个“国”是什么鬼?

      四、数据库工具MongoDB
1、首先在命令行窗口进入mongo.exe所在文件夹路径  G:\Program Files\MongoDB\Server\3.6\bin
2、实现本地链接,输入  mongo 127.0.0.1
3、测试一下,  直接输入db  ,默认结果是test,是本地数据库名称

      输入show dbs  ,显示已经建立的数据表


4、MongoDB的可视化工具 Robo 3T

  点击Create新建链接,可以修改name,点击Test测试链接,如果显示链接可用,点击Save保存,点击Connect进行链接本地数据库。


最后可以查看我们的数据啦。。。。。

猜你喜欢

转载自blog.csdn.net/ghl1390490928/article/details/80151632