• 爬虫之突破xm-sign校验反爬


    喜马拉雅

    网页分析

    - 打开我们要爬取的音乐专辑https://www.ximalaya.com/ertong/424529/
    - F12打开开发者工具
    - 点击XHR 随便点击一首歌曲会看到存储所有歌曲的地址【json格式】
    - 正常情况下我们直接用requests请求上面的地址就可以直接获取歌曲的所有信息
    - 我们拿着上面获取的地址向浏览器发起请求,发现没有返回任何信息 - 我们查看请求头中的信息发现有一个xm-sign参数,值为加密后的字符串,就是这个参数使我们获取不到数据 - 31a0dbb5916dfe85d62d8fa5988efc43(36)1563537528652(26)1563537531252 - 后面的时间戳为服务器时间戳和系统当前时间戳,计算过期时间 - 我们分析出xm-sign参数的加密规则,每次请求都在headers加上我们自己生成的xm-sign参数即可
    加密方式:
    ximalaya-时间戳(sha1加密) + (100以内随机生成一个数) + 服务器时间 + (100以内随机生成一个数) + 系统当前时间
    
    校验方式:
    ximalaya-时间戳(sha1加密) + 服务器时间 

    获取地址

    请求地址

    告诉我们没有标志,此时感觉我们在请求时少了点参数,去查看请求头

    查看请求头

    后端逻辑代码

    - 下载安装node.js   https://nodejs.org/en/download/    安装方式:https://blog.csdn.net/cai454692590/article/details/86093297
    - 获取服务器时间戳
    - 调用js代码中的函数生成xm-sign参数
    - 在headrs中加上生成的xm-sign参数像浏览器发起请求
    - 获取数据进行持久化

    js代码需要改的

    目标地址:

    加密方式:

    代码实现

    安装pyexecjs模块

    pip install pyexecjs

    猛击下载js代码

    # -*- coding: utf-8 -*-
    # @Time    : 2019/7/19 19:05
    import requests
    import os
    import re
    from bs4 import BeautifulSoup
    import lxml
    import json
    import execjs   # 操作js代码的库
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36',
        'Accept': 'text/html,application/xhtml+ xml,application/xml;q = 0.9,image/webp,image/apng,*/*;q=0.8, application/signe-exchange;v = b3',
        'Host': 'www.ximalaya.com'
    }
    
    '''爬取喜马拉雅服务器系统时间戳,用于生成xm-sign'''
    def getxmtime():
        url="https://www.ximalaya.com/revision/time"
        response = requests.get(url, headers=headers)
        html = response.text
        return html
    
    '''利用xmSign.js生成xm-sign'''
    def exec_js():
        #获取喜马拉雅系统时间戳
        time = getxmtime()
    
        #读取同一路径下的js文件
        with open('xmSign.js',"r",encoding='utf-8') as f:
            js = f.read()
    
        # 通过compile命令转成一个js对象
        docjs = execjs.compile(js)
        # 调用js的function生成sign
        res = docjs.call('python',time)
        return res
    
    """获取专辑一共有多少页"""
    def getPage():
        url = "https://www.ximalaya.com/ertong/424529/"
        html = requests.get(url,headers=headers).text
        # 创建BeautifulSoup对象
        suop = BeautifulSoup(html,'lxml')  # 实例化对象,使用lxml进行解析
        # 根据属性获取 最大页码
        max_page = suop.find("input",placeholder="请输入页码").attrs["max"]
        return max_page
    
    
    response_list = []
    """请求歌曲源地址"""
    def gethtml():
        # 调用exec_js函数生成xm-sign
        xm_sign = exec_js()
        # 将生成的xm-sign添加到请求投中
        headers["xm-sign"] = xm_sign
        max_page = getPage()
        for page in range(1,int(max_page)+1):
            url = "https://www.ximalaya.com/revision/play/album?albumId=424529&pageNum={}&sort=1&pageSize=30".format(page)
            # 下载
            response= requests.get(url,headers=headers).text
            response = json.loads(response)
            response_list.append(response)
    
    """数据持久化"""
    def write_data():
        # 请求歌曲地址拿到响应数据json
        gethtml()
        for res in response_list:
            data_list = res["data"]["tracksAudioPlay"]
            for data in data_list:
                trackName = data["trackName"] # 歌名
                trackCoverPath = data["trackCoverPath"] # 封面地址
                music_path = data["src"] # url
                print(trackName,trackCoverPath,music_path)
    write_data()
    下载音频

  • 相关阅读:
    Netty源码分析第6章(解码器)---->第3节: 行解码器
    Netty源码分析第6章(解码器)---->第2节: 固定长度解码器
    Netty源码分析第6章(解码器)---->第1节: ByteToMessageDecoder
    Netty源码分析第5章(ByteBuf)---->第10节: SocketChannel读取数据过程
    Netty源码分析第5章(ByteBuf)---->第9节: ByteBuf回收
    Netty源码分析第5章(ByteBuf)---->第8节: subPage级别的内存分配
    Netty源码分析第5章(ByteBuf)---->第7节: page级别的内存分配
    【转】关于Tomcat下项目线程启动两次的问题
    设计模式【单例模式】
    【SQL学习笔记】一、select语句
  • 原文地址:https://www.cnblogs.com/songzhixue/p/11215844.html
Copyright © 2020-2023  润新知