朋友股票虧慘了,我一怒用Python爬取了證券最新數據


 

 抓取目標:

url:http://webapi.cninfo.com.cn/#/marketDataDate
數據目標: 獲取 證券代碼 證券簡稱 交易日期  開盤價 最高價 最低價 收盤價 成交數量
難點: 請求頭參數mcode 加密生成 

使用第三方庫:

1. requests
2. execjs
3. js2py
4. math
5. time
6. pandas

工具:

1. 谷歌瀏覽器
2. pycharm
3. python3.7

 

 

頁面分析:

進入頁面,鼠標右擊,選擇檢查 -> 彈出瀏覽器開發者工具 -> Netword -> 選擇xhr -> 刷新頁面

 

 找到接口,觀察接口數據情況:

 

 

此接口為post請求,需要提交兩個表單參數。

代碼片段:

url = 'http://webapi.cninfo.com.cn/api/sysapi/p_sysapi1015' data = {    'tdate': datetime,    'scode': '399001' } headers = {    'mcode': 'MTYzNTEzOTkxMQ==',    'Referer': 'http://webapi.cninfo.com.cn/',    'Cookie': 'Hm_lvt_489bd07e99fbfc5f12cbb4145adb0a9b=1634795282; Hm_lpvt_489bd07e99fbfc5f12cbb4145adb0a9b=1634799860',    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36' } response = requests.post(url, headers=headers, data=data).json()

請求成功, 但是有時效性的問題,等過了幾分鍾后,就無權限訪問了,仔細觀察發現特殊參數mcode。

開始JS找加密參數生成位置: (注意需要重新刷新頁面,不然會出現沒有js情況)

 

 問題來了,好幾個js文件,怎么確定那個是我們需要的?

使用第二種搜索方式,根據url的請求地址搜索:

 

 

 

 

 

打上斷點后 直接刷新頁面 開始調試

 

 

var indexcode={
    getResCode:function(){
        var time=Math.floor(new Date().getTime()/1000); return window.JSonToCSV.missjson(""+time); } }

繼續調試,看看這個missjson是干啥的。

 

 下面把這些js扣下來執行

完整代碼

import requests import execjs import js2py import math import time import pandas as pd ​ ​ code_list = [] ​ ​ def MCODE():    jscode = '''   function missjson(input) {         var keyStr = "ABCDEFGHIJKLMNOP" + "QRSTUVWXYZabcdef" + "ghijklmnopqrstuv"   + "wxyz0123456789+/" + "=";         var output = "";         var chr1, chr2, chr3 = "";         var enc1, enc2, enc3, enc4 = "";         var i = 0;         do {             chr1 = input.charCodeAt(i++);             chr2 = input.charCodeAt(i++);             chr3 = input.charCodeAt(i++);             enc1 = chr1 >> 2;             enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);             enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);             enc4 = chr3 & 63;             if (isNaN(chr2)) {                 enc3 = enc4 = 64;             } else if (isNaN(chr3)) {                 enc4 = 64;             }             output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2)                     + keyStr.charAt(enc3) + keyStr.charAt(enc4);             chr1 = chr2 = chr3 = "";             enc1 = enc2 = enc3 = enc4 = "";         } while (i < input.length);             return output;     }       '''    time1 = js2py.eval_js('Math.floor(new Date().getTime()/1000)')    # py方式    a = math.floor(time.time() / 1000)    mcode = execjs.compile(jscode).call('missjson', '{a}'.format(a=time1))    return mcode ​ ​ def PageRquest(datetime, mcode):    # 接口可以換    url = 'http://webapi.cninfo.com.cn/api/sysapi/p_sysapi1015'    data = {        'tdate': datetime, # 獲取數據時間        'scode': '399001'  # 股票代碼 以及交易所簡稱   }    headers = {        'mcode': str(mcode),        'Referer': 'http://webapi.cninfo.com.cn/',        'Cookie': 'Hm_lvt_489bd07e99fbfc5f12cbb4145adb0a9b=1634795282; Hm_lpvt_489bd07e99fbfc5f12cbb4145adb0a9b=1634799860',        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36'   }    response = requests.post(url, headers=headers, data=data).json()    code = response['records']    for i in code:        code_list.append(i) ​ ​ def main(date):    mcode = MCODE()    PageRquest(date, mcode) ​ ​ if __name__ == '__main__':    # main()    # 數據分析 pandas 自動化辦公的    datetime = pd.period_range('2021/5/1', '2021/10/20', freq='B')    for date in datetime:        main(date)    df = pd.DataFrame(code_list)    df.to_excel('code.xlsx')


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM