zoukankan      html  css  js  c++  java
  • python和Ajax在一起了?真的???


    Ajax动态网页加载爬取新浪微博某关键词下的信息

    前言

    有些时候我们使用浏览器查看页面正常显示的数据与使用requests抓取页面html得到的数据不一致,这是因为requests获取的是原始的HTML文档,而浏览器中的页面是经过JavaScript处理数据后的结果。这些处理过的数据可能是通过Ajax加载的,可能包含HTML文档中,可能经过特定算法计算后生成的。

    一、Ajax原理

    1、什么是Ajax?
    Ajax全称为Asynchronous JavaScript and XML,即为异步的JavaScript(JS语言)和XML(万能的数据传输格式)。
    2、异步化?
    Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器。像—些数据验证和数据处理等都交给Ajax引擎自己来做,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求它能够利用,JavaScript在保证不被刷新,连接不变的情况下,服务器交换数据并更新部分网页的技术。像传统的网页(不使用Ajax)若要更新网页内容,必须重新加载网页,比如猫眼、豆瓣等。下图为对比图:

    3、示例
    浏览网页的时候,我们发现很多网页都有下滑查看更多的选项。比如,就拿新浪微博主页来说。一直往下滑,看到几个微博之后就没有了,而是会出现一个加载的动画,很快就出现了新的微博内容,这个过程就是Ajax加载的过程

    二、准备环境+爬取网站

    ananconda3——spyder
    谷歌浏览器
    https://m.weibo.cn/

    三、网页分析与定位

    1、本次爬取选取“夺冠”这一关键词

    2、检查元素——Network——XHR——Ctrl+R

    3、滑动页面,依次查看前三页page,Request URL中包含多个参数




    选了前三页观察,发现在Request URL里面除了最后page=2,page=3,其他参数都不发生变化


    4、观察Preview里面的信息


    想要获取的信息都在data——cards——mblog下面


    分别查询三个页面发现,只有在第一页中时,有些cards下面不存在mblog,也就是说爬出来的内容可能会为空,所以本次爬取我舍去第一页内容不全的,从page=2开始,这样可以保证爬出来的内容比较全。

    三、代码实现

    1、导入库

    from urllib.parse import urlencode
    import requests
    import json
    
    
    

    使用urlencode主要用于正常识别输入的汉字、空格以及其他特殊字符,由于url中传入了部分参数,所以需识别参数拼接为完整的url
    输出格式为对象格式:{“key1”:obj,“key2”:obj,“key3”:obj…},所以导入json包
    2、解析页面
    定义一个获取页面的函数,其中的参数params包含如下所示


    除了page以外,其他参数均不变。定义一个base_url,所有网页的base_url为同一个。

    base_url='https://m.weibo.cn/api/container/getIndex?'
    
    
    

    这里需要用到urlencode对参数进行转化拼接,使其转化并生成出每一页完整的url

    def get_page(page):
        params = {
            'containerid':'231522type=1&t=10&q=#夺冠#',
            'page_type':'searchall',
            'isnewpage':'1',
            'luicode':'10000011',
            'lfid':'100103type=38&q=夺冠&t=0',
            'page_type': 'searchall',
            'page':page
        }
        url = base_url + urlencode(params)
        try:
            rq = requests.get(url,headers = headers)
            if rq.status_code == 200 :
                return rq.json()
        except rq.ConnectionError as e:
            print('程序错误',e.args)
    
    
    

    3、定位id和raw_text
    第一个函数返回rq.json(),目的是获取如下界面的全部解析码
    print(re.json())后,输出全部内容

    j = get_page(page)返回那个解析页面,从解析页面里面找data——cards,items为cards下面所有的东西,我只想获得mblog下的id和raw_text,所以用了一个循环。先找到mblog用item接收,再再item下找到id用id接收,再找raw_text用raw_text接收,用append进行列表的依次添加,得到 all_id和all_raw_text。最后转化为字典形式

    def parse_page(j):
            items = j['data']['cards']
            all_id=[]
            all_raw_text=[]
            for item in items:
                item = item['mblog']
                id=item['id']
                raw_text=item['raw_text']
                all_id.append(id)
                all_raw_text.append(raw_text)
            weibo = dict(zip(all_id,all_raw_text))      #zip,将两个列表合并成一个字典
            return weibo
    
    
    

    4、存入txt文件
    存入为json格式

    def write_text(result):
        with open('关键词信息.txt','a',encoding='utf-8') as f:
                f.write(json.dumps(result, ensure_ascii=False) + '
    ')
                f.write('
    ')
        f.close()
    
    
    

    5、主函数调用
    Referer,User-Agent,X-Reuestes-With均在网页里

    if __name__ == '__main__':
        base_url = 'https://m.weibo.cn/api/container/getIndex?'
        headers = {"Referer": 'https://m.weibo.cn/search?containerid=100103type%3D1%26q%3D%E5%A4%BA%E5%86%A0',
                   "User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
                   "X-Requested-With":'XMLHttpRequest'}
        for page in range(2,50):
            j = get_page(page)
            result = parse_page(j)
            print(result)
            write_text(result)
    
    
    
    
    

    四、结果展示

    每个id对应一条微博信息

    欢迎关注公众号:Python爬虫数据分析挖掘

    记录学习python的点点滴滴;

    回复【开源源码】免费获取更多开源项目源码;

    公众号每日更新python知识和【免费】工具;

    本文已同步到【开源中国】、【腾讯云社区】、【CSDN】;

    耐得住寂寞,才能登得顶
    Gitee码云:https://gitee.com/lyc96/projects
  • 相关阅读:
    python模块--time模块
    python模块--如何相互调用自己写的模块
    Animating Views Using Scenes and Transitions
    fragment 切换
    android textview 设置text 字体
    android intent 5.1
    android EditView ime
    animation of android (4)
    animation of android (3)
    animation of android (2)
  • 原文地址:https://www.cnblogs.com/chenlove/p/14038565.html
Copyright © 2011-2022 走看看