哈嘍兄弟們,今天來實現一下建築市場公共服務平臺的數據採集,順便實現一下網站的JS解密。 話不多說,我們直接開始今天的內容。 首先我們需要準備這些 環境使用 Python 3.8 Pycharm 模塊使用 requests --> pip install requests execjs --> pip ...
哈嘍兄弟們,今天來實現一下建築市場公共服務平臺的數據採集,順便實現一下網站的JS解密。
話不多說,我們直接開始今天的內容。
首先我們需要準備這些
環境使用
- Python 3.8
- Pycharm
模塊使用
- requests --> pip install requests
- execjs --> pip install PyExecJS
- json
爬蟲基本流程思路
一. 數據來源分析
1. 明確需求: 明確採集的網站以及數據內容
- 網址: https://jzsc.mohurd.gov.cn/data/company
- 數據: 企業信息
初學者同學: 瀏覽器導航欄上面鏈接是什麼, 請求什麼鏈接
2. 抓包分析: 通過瀏覽器去分析, 我們需要數據具體在那個鏈接中
- 靜態網頁: 刷新網頁查看數據包內
- 動態網頁: 點擊到下一頁數據內容 / 下滑到下一頁的數據內容
* 打開開發者工具: F12
* 點擊第二頁數據內容
加密數據: https://jzsc.mohurd.gov.cn/APi/webApi/dataservice/query/comp/list?pg=1&pgsz=15&total=450
二. 代碼實現步驟
1. 發送請求 -> 模擬瀏覽器對於url地址發送請求
url地址: 通過抓包分析找到鏈接地址
2. 獲取數據 -> 獲取伺服器返迴響應數據
開發者工具: response 響應
3. 解析數據 -> 獲取加密數據內容
4. 保存數據 -> 通過解密, 還原明文數據 保存表格文件中
爬蟲部分代碼
# 導入數據請求模塊 import requests # 導入模塊 import execjs # 導入json模塊 import json # 導入csv模塊 import csv # 創建文件對象 csv_file = open('data.csv', mode='w', encoding='utf-8', newline='') csv_writer = csv.DictWriter(csv_file, fieldnames=[ '企業名稱', '統一社會信用代碼', '法人', '註冊屬地省份', '註冊屬地城市', ]) csv_writer.writeheader() # 模擬瀏覽器 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } for page in range(30): # 請求鏈接 url = f'https://jzsc.mohurd.gov.cn/APi/webApi/dataservice/query/comp/list?pg={page}&pgsz=15&total=450' # 發送請求 關鍵字傳參, 指定參數傳入到那個位置 response = requests.get(url=url, headers=headers) # 2. 獲取響應數據 --> 加密數據 data = response.text # 3. 解密數據 -> 把密文轉成明文 通過python代碼調用JS代碼 f = open('建築平臺.js', mode='r', encoding='utf-8').read() # 編譯js文件 js_code = execjs.compile(f) # 調用js代碼的函數 data->密文數據 result = js_code.call('m', data) # 把json字元串數據, 轉成json字典數據 json_data = json.loads(result) # for 迴圈遍歷 for index in json_data['data']['list']: try: info = index['QY_REGION_NAME'].split('-') if len(info) == 2: area_1 = info[0] # 省份 area_2 = info[1] # 城市 else: area_1 = info[0] # 省份 area_2 = '未知' dit = { '企業名稱': index['QY_NAME'], '統一社會信用代碼': index['QY_ORG_CODE'], '法人': index['QY_FR_NAME'], '註冊屬地省份': area_1, '註冊屬地城市': area_2, } csv_writer.writerow(dit) print(dit) except: pass
可視化部分代碼
import pandas as pd from pyecharts import options as opts # 配置項 from pyecharts.charts import Pie # 導入餅圖 # 讀取文件 df = pd.read_csv('data.csv') print(df.head()) info = df['註冊屬地省份'].value_counts().index.to_list() # 數據類目 num = df['註冊屬地省份'].value_counts().to_list() # 數據數量 print(info) print(num) c = ( Pie() .add( "", [list(z) for z in zip(info,num,)], center=["40%", "50%"], ) .set_global_opts( # 設置標題 title_opts=opts.TitleOpts(title="註冊省份占比分佈"), legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical"), ) .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}")) # 保存html文件 .render("註冊省份占比分佈.html") ) # 對此我錄製了詳細的視頻講解,跟源碼一起打包好了。 # 都放在這個摳裙了 872937351
JS解密
const CryptoJS = require('crypto-js') function b(t) { var e = CryptoJS.enc.Hex.parse(t) , n = CryptoJS.enc.Base64.stringify(e) , a = CryptoJS.AES.decrypt(n, f, { iv: m, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }) , r = a.toString(CryptoJS.enc.Utf8); return r.toString() } var f = CryptoJS.enc.Utf8.parse("jo8j9wGw%6HbxfFn") var m = CryptoJS.enc.Utf8.parse("0123456789ABCDEF"); data = '95780ba0943730051dccb5fe3918f9fe9f9c759baf71007abbbc84deedcdd81cf58832bbc54e50a84c41faa2c40030710f9dcd7c6d7c8c59d5ec869f8d20495c96d9c5cefdb18e82f51bc97e693fe3f42cf0c5f2e7b9d630185fd13c4d3e8aa7c2fea290184736151f6b4ac09c903e2fb2ea29428c2daa2244f2770b59500b9959e9fa5ab0e0482499dc8cfb0b6b362a3b953b8f67e5e64f9fe3b9c4b7e2e43d139e74713e5d25d54286cff02b2d01cfd75abfd07161e55990343d47c42affd49c67db8e6d7b3281d8e0d4d7f7f665362b38b8e25002fea25a54db8ff11bbd365330b02e965314c0dd2f5f142849986dd383fd5707f1f3fe17898bab6f51cc3acaa08510ac99d9988d1114dc81e9849e2203490d0599a6a7557c65083ae61a59d6119cfde6b43c05cdb62c49ffbaf203cf1c91e31ea2a8d9f1390e134f84d236dc9bcaa5b538478e5bb9db45d5350578ec02f288dbac4fc86dbc8c6e8586ace2a8e05e0594e143a9218aead1815919c1fd8a9b7071aab85e09afb24f42199cd68b72cb5e6fe378afe274b5985c1e12e7cfcbf6d9ffcaed6edd0eca8cc1249a5407c50837ec5547bf81b45e8d096d19b5cc6d1321119b8836f5ee4b3df301d9c32a517a7968587d904e168702c16071c6ef9fd5981b432a5d82898caad049c603e718d2b23b01958444d941dae01e9328dbfeaee7adc6a4d1742002a3c553ef8e7cff9277befdd1e63ae5bbcebf9588f4bb4f686f5be5b1929ab388035d392eb1d0eef5cf1cb6a6cba6487d868dfb28acfaf945b1915a2482682e8d88840c9060b39b53fd90c969dd1e2ffa3535c750ce95265b2beb738ee1166c000754399cbe061db59078926f643936b2cdb2ef5bda6ed3354df7b56d1881edb6be9febb5a66a5352851c2156e7fe61b74fd0a0c6acffbc80513895f5bb0fd7eb68b7dab775c7385d6b216df90a8d1a09995716bd374796c2d94aec68d6c97d78540c3896affc2e567caf527553f6ca784117cbecac91293ca519d4c8342bb64046ab7bffb306a32d2cad525b844b43ecf10dcb6e60f2248de9f52b592d9d67d923a777e3a2a130b1a6bc435bb711d7bfcaf5f7f2b1a8228fdd02c0b7506b06fb5a3f7093a9398a2e8421ab22c466e2e473f400d3dc45dbd8215f37583e9537d89424feb5a0a09ad388a5cc1ae8a015a867c69c76158be6a31cd0743b86d8ea33473053057eb0299970972aec9a7803b7465d797da0bc8f9a08a247ba9cef19710cec257c4405b01d1da39bd1ce13d2bd8786483e1b' console.log(b(data))
好了,今天的分享就到這結束了,咱們下次見!