• 抓取js动态生成的数据分析案例


    需求:

    爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/data018d244441062d8916dd472a4c6a0a0b.html页面中的新闻数据。
    1.爬取当前页中所有新闻的详情内容
    2.进行任意的持久化存储操作
    3.注意:新闻详情内容为新闻详情页中的文本数据,
    4.该文本数据最终解析到的可以是携带html标签的内容!

    分析:

      1.首先通过分析页面会发现该页面中的新闻数据都是动态加载出来的,并且通过抓包工具抓取数据可以发现动态数据也不是ajax请求获取的动态数据(因为没有捕获到ajax请求的数据包),那么只剩下一种可能,该动态数据是js动态生成的。

      2.通过抓包工具查找到底数据是由哪个js请求产生的动态数据:打开抓包工具,然后对首页url(第一行需求中的url)发起请求,捕获所有的请求数据包。

    分析js数据包响应回来的数据:

    该响应数据对应的url可以在抓包工具对应的该数据包的header选项卡中获取。获取url后,对其发起请求即可获取上图中选中的相应数据,该响应数据类型为application/javascript类型,所以可以将获取的响应数据通过正则提取出最外层大括号中的数据,然后使用json.loads将其转为字典类型,然后逐步解析出数据中所有新闻详情页的url即可。

    - 获取详情页中对应的新闻详情数据:对详情页发起请求后,会发现详情页的新闻数据也是动态加载出来的,因此还是跟上述步骤一样,在抓包工具中对详情页中的局部数据进行搜索,定位到指定的js数据包:

    该js数据包的url为:

    详情页url,获取后,即可请求到该数据包对应的响应数据了,该相应数据中就包含了对应新闻详情数据了。注意,该响应数据的类型同样为application/javascript,所以数据解析同上!

    分析首页中所有新闻的详情页url和新闻详情数据对应的js数据包的url之间的关联:

      - 首页中某一新闻详情页的url:            https://www.xuexi.cn/5c39c314138da31babf0b16af5a55da4/e43e220633a65f9b6d8b53712cba9caa.html

      - 该新闻详情数据对应的js数据包的url:https://www.xuexi.cn/5c39c314138da31babf0b16af5a55da4/datae43e220633a65f9b6d8b53712cba9caa.js

      - 所有的新闻详情对应的js数据包的黄色选中部分都是一样的只是红色部分各自不同,但是红色部分却和该新闻详情页的url中的红色部分是相同的!!!新闻详情页的url是可以在上述过程中解析出来的。因此现在就可以批量产生出详情数据对应js数据包的url的,然后批量进行数据请求,获取响应数据,然后对响应数据进行解析即可完成最终的需求!

    代码:

    # url -- https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/data018d244441062d8916dd472a4c6a0a0b.html
    import json
    import re
    import requests
    from lxml import etree
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.12 Safari/537.36"
    }
    url_index = "https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/data018d244441062d8916dd472a4c6a0a0b.js"
    
    # 响应数据是application/javascript类型,通过正则匹配数据
    res_text = requests.get(url=url_index, headers=headers).text
    res_str = re.findall('{.*}',res_text)[0]
    res_dic = json.loads(res_str)
    
    detial_url_list = []  # 存储获取详情页数据包的url
    # 解析出详情页的url
    for dic in res_dic.values():
        try:
            data_list = dic["list"]
        except:
            continue
        for data in data_list:
            # 详情页面的url
            detial_url = data["static_page_url"]
            # 通过详情页url,拼接出返回详情页数据的url
            
            # 方法一: url只有一段是动态的
            detial_data_url = detial_url.replace('e43e220633a65f9b6d8b53712cba9caa.html','datae43e220633a65f9b6d8b53712cba9caa.js')        
            # 方法二:假设url有两段都是动态的,先切割获取再拼接   
    #         detial_url = detial_url.replace('.html','.js')  # 将后缀改为js 
    #         li = detial_url.split("/")
    #         li.append("data" + li.pop())   
    #         detial_data_url = '/'.join(li)  # 拼接成功的详情页数据包url        
            detial_url_list.append(detial_data_url)
    
    n = 0
    for url in detial_url_list:
    #     # 获取详情页的数据
        response_text = requests.get(url=url,headers=headers).text
        response_str = re.findall('{.*}',response_text)[0]
        response_dic = json.loads(response_str)
        detail_dic = response_dic["fp8ttetzkclds001"]["detail"]
        title = detail_dic["frst_name"]
        content = detail_dic["content"]
        write_data = f"新闻标题:{title}
    新闻内容:{content}
    "
        # 持久化储存,将所有新闻存在一个文件里
        with open(f'./{title}xw.txt','w', encoding='utf-8') as fp:
            fp.write(write_data)
        n += 1
        print(f"新闻存储成功{n}")
  • 相关阅读:
    MySQL select语句中where条件的提取过程
    MySQL特性:ICP,Index Condition Pushdown
    MySQL特性:BKA,Batched Key Access,批量索引访问
    MySQL特性:MRR,Multi-Range Read,多范围读
    show engine innodb status 输出结果解读
    IPv6的一点使用小计
    MySQL 通过ibd恢复数据
    explain 小结
    clickhouse的多路径存储策略
    cenos6.5升级glibc2.18
  • 原文地址:https://www.cnblogs.com/zwq-/p/10619734.html
Copyright © 2020-2023  润新知