日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python网络爬虫系列(十一)——JS的解析

發布時間:2024/7/5 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python网络爬虫系列(十一)——JS的解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JS的解析

學習目標:
  • 了解 定位js的方法
  • 了解 添加斷點觀察js的執行過程的方法
  • 應用 js2py獲取js的方法
  • 1 確定js的位置

    對于前面人人網的案例,我們知道了url地址中有部分參數,但是參數是如何生成的呢?

    毫無疑問,參數肯定是js生成的,那么如何獲取這些參數的規律呢?通過下面的學習來了解

    1.1 觀察按鈕的綁定js事件

    通過點擊按鈕,然后點擊Event Listener,部分網站可以找到綁定的事件,對應的,只需要點擊即可跳轉到js的位置

    1.2 通過search all file 來搜索

    部分網站的按鈕可能并沒有綁定js事件監聽,那么這個時候可以通過搜索請求中的關鍵字來找到js的位置,比如livecell

    點擊美化輸出選項

    可以繼續在其中搜索關鍵字

    2 觀察js的執行過程

    找到js的位置之后,我們可以來通過觀察js的位置,找到js具體在如何執行,后續我們可以通過python程序來模擬js的執行,或者是使用類似js2py直接把js代碼轉化為python程序去執行

    觀察js的執行過程最簡單的方式是添加斷點

    添加斷點的方式:在左邊行號點擊即可添加,對應的右邊BreakPoints中會出現現有的所有斷點

    添加斷點之后繼續點擊登錄,每次程序在斷點位置都會停止,通過如果該行有變量產生,都會把變量的結果展示在Scoope中

    在上圖的右上角有1,2,3三個功能,分別表示:
    - 1:繼續執行到下一個斷點
    - 2:進入調用的函數中
    - 3:從調用的函數中跳出來

    3 js2py的使用

    在知道了js如何生成我們想要的數據之后,那么接下來我們就需要使用程序獲取js執行之后的結果了

    3.1 js2py的介紹

    js2py是一個js的翻譯工具,也是一個通過純python實現的js的解釋器,github上源碼與示例

    3.2 js的執行思路

    js的執行方式大致分為兩種:

  • 在了解了js內容和執行順序之后,通過python來完成js的執行過程,得到結果
  • 在了解了js內容和執行順序之后,使用類似js2py的模塊來執js代碼,得到結果
  • 但是在使用python程序實現js的執行時候,需要觀察的js的每一個步驟,非常麻煩,所以更多的時候我們會選擇使用類似js2py的模塊去執行js,接下來我們來使用js2py實現人人網登錄參數的獲取

    3.3 具體的實現

    定位進行登錄js代碼

    formSubmit: function() {var e, t = {};$(".login").addEventListener("click", function() {t.phoneNum = $(".phonenum").value,t.password = $(".password").value,e = loginValidate(t),t.c1 = c1 || 0,e.flag ? ajaxFunc("get", "http://activity.renren.com/livecell/rKey", "", function(e) {var n = JSON.parse(e).data;if (0 == n.code) {t.password = t.password.split("").reverse().join(""),setMaxDigits(130);var o = new RSAKeyPair(n.e,"",n.n), r = encryptedString(o, t.password);t.password = r,t.rKey = n.rkey} elsetoast("公鑰獲取失敗"),t.rKey = "";ajaxFunc("post", "http://activity.renren.com/livecell/ajax/clog", t, function(e) {var e = JSON.parse(e).logInfo;0 == e.code ? location.href = localStorage.getItem("url") || "" : toast(e.msg || "登錄出錯")})}) : toast(e.msg)})}
    從代碼中我們知道:
  • 我們要登錄需要對密碼進行加密和獲取rkey字段的值
  • rkey字段的值我們直接發送請求rkey請求就可以獲得
  • 密碼是先反轉然后使用RSA進行加密, js代碼很復雜, 我們希望能通過在python中執行js來實現
  • 實現思路:
  • 使用session發送rKey獲取登錄需要信息

    • url: http://activity.renren.com/livecell/rKey
    • 方法: get
  • 根據獲取信息對密碼進行加密
    2.1 準備用戶名和密碼

    2.2 使用js2py生成js的執行環境:context

    2.3 拷貝使用到js文件的內容到本項目中

    2.4 讀取js文件的內容,使用context來執行它們

    2.5 向context環境中添加需要數據

    2.6 使用context執行加密密碼的js字符串

    2.7 通過context獲取加密后密碼信息

  • 使用session發送登錄請求

    • URL: http://activity.renren.com/livecell/ajax/clog

    • 請求方法: POST

    • 數據:

      phoneNum: xxxxxxx password: (加密后生產的) c1: 0 rKey: rkey請求獲取的
  • 具體代碼

    需要提前下載幾個js文件到本地:

    BigInt.js

    RSA.js

    Barrett.js

    import requests import json import js2py# - 實現思路: # - 使用session發送rKey獲取登錄需要信息 # - url: http://activity.renren.com/livecell/rKey # - 方法: get # 獲取session對象 session = requests.session() headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Mobile Safari/537.36","X-Requested-With": "XMLHttpRequest","Content-Type":"application/x-www-form-urlencoded" } # 設置session的請求頭信息 session.headers = headersresponse = session.get("http://activity.renren.com/livecell/rKey") # print(response.content.decode()) n = json.loads(response.content)['data']# - 根據獲取信息對密碼進行加密 # - 準備用戶名和密碼 phoneNum = "131..." password = "****" # - 使用js2py生成js的執行環境:context context = js2py.EvalJs() # - 拷貝使用到js文件的內容到本項目中 # - 讀取js文件的內容,使用context來執行它們 with open("BigInt.js", 'r', encoding='utf8') as f:context.execute(f.read())with open("RSA.js", 'r', encoding='utf8') as f:context.execute(f.read()) with open("Barrett.js", 'r', encoding='utf8') as f:context.execute(f.read())# - 向context環境中添加需要數據 context.t = {'password': password} context.n = n # - 執行加密密碼的js字符 js = '''t.password = t.password.split("").reverse().join(""),setMaxDigits(130);var o = new RSAKeyPair(n.e,"",n.n), r = encryptedString(o, t.password);''' context.execute(js) # - 通過context獲取加密后密碼信息 # print(context.r) password = context.r # - 使用session發送登錄請求 # - URL: http://activity.renren.com/livecell/ajax/clog # - 請求方法: POST # - 數據: # - phoneNum: 15565280933 # - password: (加密后生產的) # - c1: 0 # - rKey: rkey請求獲取的 data = {'phoneNum': '131....','password': password,'c1':0,'rKey':n['rkey'] }# print(session.headers) response = session.post("http://activity.renren.com/livecell/ajax/clog", data=data) print(response.content.decode())# 訪問登錄的資源 response = session.get("http://activity.renren.com/home#profile") print(response.content.decode())

    小結

  • 通過在chrome中觀察元素的綁定事件可以確定js
  • 通過在chrome中search all file 搜索關鍵字可以確定js的位置
  • 觀察js的數據生成過程可以使用添加斷點的方式觀察
  • js2py的使用
    • 需要準備js的內容
    • 生成js的執行環境
    • 在執行環境中執行js的字符串,傳入數據,獲取結果
  • 【綜合案例】:有道翻譯
    知識點:
    1、python中的哈希處理:md5()

    import js2pyimport hashlibdata = 'python37'# 創建hash對象 md5 = hashlib.md5()# 向hash對象中添加需要做hash運算的字符串 md5.update(data.encode())# 獲取字符串的hash值 result = md5.hexdigest() print(result)


    分析過程:進行抓包:



    接下來通過search相關內容進行尋找:

    import requests import hashlib import time import random import jsonclass Youdao(object):def __init__(self):self.url='http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'self.headers = {'User-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36','Cookie': "OUTFOX_SEARCH_USER_ID=-1628507307@10.108.160.17; OUTFOX_SEARCH_USER_ID_NCOO=1058312939.7835485; _ntes_nnid=7c814c8475605712d1b72e0446d52cf2,1590040388694; JSESSIONID=aaaRXPpDC6D_h4ZVYTYmx; ___rl__test__cookies=1594283781148",'Referer': 'http://fanyi.youdao.com/'}self.formdata = Noneself.word = input("請輸入需要翻譯的單詞或句子:")def generate_formdata(self):'''ts: r = "" + (new Date).getTime(),salt: ts + parseInt(10 * Math.random(), 10),sign: n.md5("fanyideskweb" + e + i + "mmbP%A-r6U3Nw(n]BjuEU")'''ts = str(int(time.time()*1000))# print(ts)salt = ts + str(random.randint(0,9))# print(salt)temstr = "fanyideskweb" + self.word + salt + "mmbP%A-r6U3Nw(n]BjuEU"# 創建hash對象md5 = hashlib.md5()# 向hash對象中添加需要做hash運算的字符串.注意,字符串需要轉換成bytes類型md5.update(temstr.encode())# 將結果轉成16進制sign = md5.hexdigest()self.formdata = {"i": self.word,"from": "AUTO","to": "AUTO","smartresult": "dict","client": "fanyideskweb","salt": salt,"sign": sign,"ts": ts,"bv": "02a6ad4308a3443b3732d855273259bf","doctype": "json","version": "2.1","keyfrom": "fanyi.web","action": "FY_BY_REALTlME"}def get_data(self):response = requests.post(self.url,data=self.formdata,headers =self.headers)return response.contentdef parse_data(self,data):# print(type(data.decode()))str = data.decode()# print(type(json.loads(str)))dict_data = json.loads(str)print("有道翻譯結果:" + dict_data['translateResult'][0][0]['tgt'])def run(self):# url# headers# formdataself.generate_formdata()# print(self.formdata)# 發送請求,獲取響應data = self.get_data()# print(data)# 解析數據self.parse_data(data)if __name__ == '__main__':youdao = Youdao()youdao.run()

    運行結果:

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的python网络爬虫系列(十一)——JS的解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。