【爬蟲(chóng)開(kāi)發(fā)】爬蟲(chóng)開(kāi)發(fā)從0到1全知識(shí)教程第8篇:反爬與反反爬,JS的解析【附代碼文檔】

本教程的知識(shí)點(diǎn)為:爬蟲(chóng)概要 爬蟲(chóng)基礎(chǔ) 爬蟲(chóng)概述 知識(shí)點(diǎn): 1. 爬蟲(chóng)的概念 requests模塊 requests模塊 知識(shí)點(diǎn): 1. requests模塊介紹 1.1 requests模塊的作用: 數(shù)據(jù)提取概要 數(shù)據(jù)提取概述 知識(shí)點(diǎn) 1. 響應(yīng)內(nèi)容的分類 知識(shí)點(diǎn):了解 響應(yīng)內(nèi)容的分類 Selenium概要 selenium的介紹 知識(shí)點(diǎn): 1. selenium運(yùn)行效果展示 1.1 chrome瀏覽器的運(yùn)行效果 Selenium概要 selenium的其它使用方法 知識(shí)點(diǎn): 1. selenium標(biāo)簽頁(yè)的切換 知識(shí)點(diǎn):掌握 selenium控制標(biāo)簽頁(yè)的切換 反爬與反反爬 常見(jiàn)的反爬手段和解決思路 學(xué)習(xí)目標(biāo) 1 服務(wù)器反爬的原因 2 服務(wù)器常反什么樣的爬蟲(chóng) 反爬與反反爬 驗(yàn)證碼處理 學(xué)習(xí)目標(biāo) 1.圖片驗(yàn)證碼 2.圖片識(shí)別引擎 反爬與反反爬 JS的解析 學(xué)習(xí)目標(biāo): 1 確定js的位置 1.1 觀察按鈕的綁定js事件 Mongodb數(shù)據(jù)庫(kù) 介紹 內(nèi)容 mongodb文檔 mongodb的簡(jiǎn)單使用 Mongodb數(shù)據(jù)庫(kù) 介紹 內(nèi)容 mongodb文檔 mongodb的聚合操作 Mongodb數(shù)據(jù)庫(kù) 介紹 內(nèi)容 mongodb文檔 mongodb和python交互 scrapy爬蟲(chóng)框架 介紹 內(nèi)容 scrapy官方文檔 scrapy的入門使用 scrapy爬蟲(chóng)框架 介紹 內(nèi)容 scrapy官方文檔 scrapy管道的使用 scrapy爬蟲(chóng)框架 介紹 內(nèi)容 scrapy官方文檔 scrapy中間件的使用 scrapy爬蟲(chóng)框架 介紹 內(nèi)容 scrapy官方文檔 scrapy_redis原理分析并實(shí)現(xiàn)斷點(diǎn)續(xù)爬以及分布式爬蟲(chóng) scrapy爬蟲(chóng)框架 介紹 內(nèi)容 scrapy官方文檔 scrapy的日志信息與配置 利用appium抓取app中的信息 介紹 內(nèi)容 appium環(huán)境安裝 學(xué)習(xí)目標(biāo)

完整筆記資料代碼:https://gitee.com/yinuo112/Backend/tree/master/爬蟲(chóng)/爬蟲(chóng)開(kāi)發(fā)從0到1全知識(shí)教程/note.md

感興趣的小伙伴可以自取哦~


全套教程部分目錄:


部分文件圖片:

反爬與反反爬

本階段主要學(xué)習(xí)爬蟲(chóng)的反爬及應(yīng)對(duì)方法饺律。

JS的解析

學(xué)習(xí)目標(biāo):
  1. 了解 定位js的方法
  2. 了解 添加斷點(diǎn)觀察js的執(zhí)行過(guò)程的方法
  3. 應(yīng)用 js2py獲取js的方法

1 確定js的位置

對(duì)于前面人人網(wǎng)的案例霉囚,我們知道了url地址中有部分參數(shù)雷逆,但是參數(shù)是如何生成的呢竹捉?

毫無(wú)疑問(wèn)巢价,參數(shù)肯定是js生成的,那么如何獲取這些參數(shù)的規(guī)律呢蜜唾?通過(guò)下面的學(xué)習(xí)來(lái)了解

1.1 觀察按鈕的綁定js事件

通過(guò)點(diǎn)擊按鈕艺晴,然后點(diǎn)擊Event Listener,部分網(wǎng)站可以找到綁定的事件魔种,對(duì)應(yīng)的析二,只需要點(diǎn)擊即可跳轉(zhuǎn)到j(luò)s的位置

1.2 通過(guò)search all file 來(lái)搜索

部分網(wǎng)站的按鈕可能并沒(méi)有綁定js事件監(jiān)聽(tīng),那么這個(gè)時(shí)候可以通過(guò)搜索請(qǐng)求中的關(guān)鍵字來(lái)找到j(luò)s的位置,比如livecell

點(diǎn)擊美化輸出選項(xiàng)

可以繼續(xù)在其中搜索關(guān)鍵字

2 觀察js的執(zhí)行過(guò)程

找到j(luò)s的位置之后叶摄,我們可以來(lái)通過(guò)觀察js的位置属韧,找到j(luò)s具體在如何執(zhí)行,后續(xù)我們可以通過(guò)python程序來(lái)模擬js的執(zhí)行蛤吓,或者是使用類似js2py直接把js代碼轉(zhuǎn)化為python程序去執(zhí)行

觀察js的執(zhí)行過(guò)程最簡(jiǎn)單的方式是添加斷點(diǎn)

添加斷點(diǎn)的方式:在左邊行號(hào)點(diǎn)擊即可添加宵喂,對(duì)應(yīng)的右邊BreakPoints中會(huì)出現(xiàn)現(xiàn)有的所有斷點(diǎn)

添加斷點(diǎn)之后繼續(xù)點(diǎn)擊登錄,每次程序在斷點(diǎn)位置都會(huì)停止会傲,通過(guò)如果該行有變量產(chǎn)生锅棕,都會(huì)把變量的結(jié)果展示在Scoope中

在上圖的右上角有1,2,3三個(gè)功能,分別表示:

- 1:繼續(xù)執(zhí)行到下一個(gè)斷點(diǎn)
- 2:進(jìn)入調(diào)用的函數(shù)中
- 3:從調(diào)用的函數(shù)中跳出來(lái)

3 js2py的使用

在知道了js如何生成我們想要的數(shù)據(jù)之后冯事,那么接下來(lái)我們就需要使用程序獲取js執(zhí)行之后的結(jié)果了

3.1 js2py的介紹

js2py是一個(gè)js的翻譯工具,也是一個(gè)通過(guò)純python實(shí)現(xiàn)的js的解釋器德绿,[github上源碼與示例](

3.2 js的執(zhí)行思路

js的執(zhí)行方式大致分為兩種:

  1. 在了解了js內(nèi)容和執(zhí)行順序之后,通過(guò)python來(lái)完成js的執(zhí)行過(guò)程退渗,得到結(jié)果
  2. 在了解了js內(nèi)容和執(zhí)行順序之后脆炎,使用類似js2py的模塊來(lái)執(zhí)js代碼,得到結(jié)果

但是在使用python程序?qū)崿F(xiàn)js的執(zhí)行時(shí)候氓辣,需要觀察的js的每一個(gè)步驟,非常麻煩袱蚓,所以更多的時(shí)候我們會(huì)選擇使用類似js2py的模塊去執(zhí)行js钞啸,接下來(lái)我們來(lái)使用js2py實(shí)現(xiàn)人人網(wǎng)登錄參數(shù)的獲取

3.3 具體的實(shí)現(xiàn)

定位進(jìn)行登錄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", " "", 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
                } else
                    toast("公鑰獲取失敗"),
                    t.rKey = "";
                ajaxFunc("post", " t, function(e) {
                    var e = JSON.parse(e).logInfo;
                    0 == e.code ? location.href = localStorage.getItem("url") || "" : toast(e.msg || "登錄出錯(cuò)")
                })
            }) : toast(e.msg)
        })
    }
從代碼中我們知道:
  1. 我們要登錄需要對(duì)密碼進(jìn)行加密和獲取rkey字段的值
  2. rkey字段的值我們直接發(fā)送請(qǐng)求rkey請(qǐng)求就可以獲得
  3. 密碼是先反轉(zhuǎn)然后使用RSA進(jìn)行加密, js代碼很復(fù)雜, 我們希望能通過(guò)在python中執(zhí)行js來(lái)實(shí)現(xiàn)
實(shí)現(xiàn)思路:
  1. 使用session發(fā)送rKey獲取登錄需要信息

    • url: [
    • 方法: get
  2. 根據(jù)獲取信息對(duì)密碼進(jìn)行加密 2.1 準(zhǔn)備用戶名和密碼

2.2 使用js2py生成js的執(zhí)行環(huán)境:context

2.3 拷貝使用到j(luò)s文件的內(nèi)容到本項(xiàng)目中

2.4 讀取js文件的內(nèi)容,使用context來(lái)執(zhí)行它們

2.5 向context環(huán)境中添加需要數(shù)據(jù)

2.6 使用context執(zhí)行加密密碼的js字符串

2.7 通過(guò)context獲取加密后密碼信息

  1. 使用session發(fā)送登錄請(qǐng)求

    • URL: [
    • 請(qǐng)求方法: POST
    • 數(shù)據(jù):

phoneNum: xxxxxxx
password: (加密后生產(chǎn)的)
c1: 0
rKey: rkey請(qǐng)求獲取的









##### 具體代碼




需要提前下載幾個(gè)js文件到本地:
> 
BigInt.js

RSA.js

Barrett.js

```python
import requests
import json
import js2py



# - 實(shí)現(xiàn)思路:




#   - 使用session發(fā)送rKey獲取登錄需要信息




#     - url: 




#     - 方法: get




#  獲取session對(duì)象


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"
}


# 設(shè)置session的請(qǐng)求頭信息


session.headers = headers

response = session.get("


# print(response.content.decode())


n = json.loads(response.content)['data']



#   - 根據(jù)獲取信息對(duì)密碼進(jìn)行加密




#     - 準(zhǔn)備用戶名和密碼


phoneNum = "131..."
password = "****"


#     - 使用js2py生成js的執(zhí)行環(huán)境:context


context = js2py.EvalJs()


#     - 拷貝使用到j(luò)s文件的內(nèi)容到本項(xiàng)目中




#     - 讀取js文件的內(nèi)容,使用context來(lái)執(zhí)行它們


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環(huán)境中添加需要數(shù)據(jù)


context.t = {'password': password}
context.n = n


#     - 執(zhí)行加密密碼的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)


# - 通過(guò)context獲取加密后密碼信息




# print(context.r)


password = context.r


#   - 使用session發(fā)送登錄請(qǐng)求




#     - URL: 




#     - 請(qǐng)求方法: POST




#     - 數(shù)據(jù):




#       - phoneNum: 15565280933




#       - password: (加密后生產(chǎn)的)




#       - c1: 0




#       - rKey: rkey請(qǐng)求獲取的


data = {
 'phoneNum': '131....',
 'password': password,
 'c1':0,
 'rKey':n['rkey']
}



# print(session.headers)


response = session.post(" data=data)
print(response.content.decode())



# 訪問(wèn)登錄的資源


response = session.get("
print(response.content.decode())

小結(jié)

  1. 通過(guò)在chrome中觀察元素的綁定事件可以確定js

  2. 通過(guò)在chrome中search all file 搜索關(guān)鍵字可以確定js的位置

  3. 觀察js的數(shù)據(jù)生成過(guò)程可以使用添加斷點(diǎn)的方式觀察

  4. js2py的使用

    • 需要準(zhǔn)備js的內(nèi)容
    • 生成js的執(zhí)行環(huán)境
    • 在執(zhí)行環(huán)境中執(zhí)行js的字符串,傳入數(shù)據(jù)喇潘,獲取結(jié)果

Mongodb數(shù)據(jù)庫(kù)

介紹

在前面的中我們學(xué)習(xí)了mysql這種關(guān)系型數(shù)據(jù)庫(kù)体斩,那么接下來(lái),我們會(huì)來(lái)學(xué)習(xí)一種非關(guān)系型數(shù)據(jù)庫(kù)mongodb颖低,mongodb數(shù)據(jù)庫(kù)主要用于海量存儲(chǔ)絮吵,常被用在數(shù)據(jù)采集項(xiàng)目中。

內(nèi)容

  • mongodb的介紹和安裝
  • mongodb的簡(jiǎn)單使用
  • mongodb的增刪改查
  • mongodb的聚合操作
  • mongodb的索引操作
  • mongodb的權(quán)限管理
  • mongodb和python交互(pymongo模塊)

mongodb文檔

[

Mongodb的介紹和安裝

學(xué)習(xí)目標(biāo)
  1. 了解 非關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)勢(shì)
  2. 了解 mongodb的安裝

1. mongodb的介紹

1.1 什么是mongodb

  • mongodb 是一個(gè)功能最豐富的NoSQL非關(guān)系數(shù)據(jù)庫(kù)忱屑。由 C++ 語(yǔ)言編寫蹬敲。
  • mongodb 本身提供S端存儲(chǔ)數(shù)據(jù),即server莺戒;也提供C端操作處理(如查詢等)數(shù)據(jù)伴嗡,即client。

1.2 SQL和NoSQL的主要區(qū)別

  • 在SQL中層級(jí)關(guān)系: 數(shù)據(jù)庫(kù)>表>數(shù)據(jù)
  • 而在NoSQL中則是: 數(shù)據(jù)庫(kù)>集合>文檔
1.2.1 數(shù)據(jù)之間無(wú)關(guān)聯(lián)性
  • SQL中如何需要增加外部關(guān)聯(lián)數(shù)據(jù)的話从铲,規(guī)范化做法是在原表中增加一個(gè)外鍵瘪校,關(guān)聯(lián)外部數(shù)據(jù)表。
  • NoSQL則可以把外部數(shù)據(jù)直接放到原數(shù)據(jù)集中,以提高查詢效率阱扬。缺點(diǎn)也比較明顯泣懊,對(duì)關(guān)聯(lián)數(shù)據(jù)做更新時(shí)會(huì)比較麻煩。
  • SQL中在一個(gè)表中的每條數(shù)據(jù)的字段是固定的麻惶。而NoSQL中的一個(gè)集合(表)中的每條文檔(數(shù)據(jù))的key(字段)可以是互不相同的馍刮。
1.2.2 拓展閱讀

[

1.3 mongodb作為非關(guān)系型數(shù)據(jù)庫(kù)相較于關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)勢(shì)

易擴(kuò)展: NoSQL數(shù)據(jù)庫(kù)種類繁多, 但是一個(gè)共同的特點(diǎn)都是去掉關(guān)系數(shù)據(jù)庫(kù)的關(guān)系型特性用踩。 數(shù)據(jù)之間無(wú)關(guān)系渠退, 這樣就非常容易擴(kuò)展

大數(shù)據(jù)量,高性能: NoSQL數(shù)據(jù)庫(kù)都具有非常高的讀寫性能脐彩, 尤其在大數(shù)據(jù)量下表現(xiàn)優(yōu)秀碎乃。 這得益于它的非關(guān)系性,數(shù)據(jù)庫(kù)的結(jié)構(gòu)簡(jiǎn)單

靈活的數(shù)據(jù)模型: NoSQL無(wú)需事先為要存儲(chǔ)的數(shù)據(jù)建立字段惠奸, 隨時(shí)可以存儲(chǔ)自定義的數(shù)據(jù)格式梅誓。 而在關(guān)系數(shù)據(jù)庫(kù)中, 增刪字段是一件非常麻煩的事情佛南。 如果是非常大數(shù)據(jù)量的表梗掰, 增加字段簡(jiǎn)直就是一個(gè)噩夢(mèng)

2. mongodb的安裝

以u(píng)buntu18.04為例

mongodb具有兩種安裝方式:命令安裝 或 源碼安裝

2.1 命令安裝

在ubuntu中使用apt-get工具安裝

sudo apt-get install -y mongodb-org

或參考官方文檔 [

2.2 源碼安裝

2.2.1 選擇相應(yīng)版本和操作系統(tǒng)并下載

[

2.2.2 解壓

tar -zxvf mongodb-linux-x86_64-ubuntu1804-4.0.3.tgz

2.2.3 移動(dòng)到/usr/local/目錄下

sudo mv -r mongodb-linux-x86_64-ubuntu1804-4.0.3/ /usr/local/mongodb

2.2.4 在shell的初始化腳本.bashrc中添加mongodb可執(zhí)行文件到環(huán)境變量PATH中

a. 進(jìn)入.bashrc文件中

cd ~
sudo vi .bashrc

b. 在.bashrc文件的最后添加:

export PATH=/usr/local/mongodb/bin:$PATH

3. mongodb的官方文檔

[


小結(jié)

  1. 了解 非關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)勢(shì)

    • 易擴(kuò)展
    • 高性能
    • 靈活的數(shù)據(jù)字段
  2. 了解 mongodb的安裝

    • sudo apt-get install -y mongodb-org

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市嗅回,隨后出現(xiàn)的幾起案子及穗,更是在濱河造成了極大的恐慌,老刑警劉巖绵载,帶你破解...
    沈念sama閱讀 212,185評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埂陆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡娃豹,警方通過(guò)查閱死者的電腦和手機(jī)焚虱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,445評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)懂版,“玉大人鹃栽,你說(shuō)我怎么就攤上這事∏耄” “怎么了民鼓?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,684評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蓬抄。 經(jīng)常有香客問(wèn)我摹察,道長(zhǎng),這世上最難降的妖魔是什么倡鲸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,564評(píng)論 1 284
  • 正文 為了忘掉前任供嚎,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘克滴。我一直安慰自己逼争,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,681評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布劝赔。 她就那樣靜靜地躺著誓焦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪着帽。 梳的紋絲不亂的頭發(fā)上杂伟,一...
    開(kāi)封第一講書(shū)人閱讀 49,874評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音仍翰,去河邊找鬼赫粥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛予借,可吹牛的內(nèi)容都是我干的越平。 我是一名探鬼主播,決...
    沈念sama閱讀 39,025評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼灵迫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼秦叛!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起瀑粥,我...
    開(kāi)封第一講書(shū)人閱讀 37,761評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤挣跋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后狞换,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體浆劲,經(jīng)...
    沈念sama閱讀 44,217評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,545評(píng)論 2 327
  • 正文 我和宋清朗相戀三年哀澈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片度气。...
    茶點(diǎn)故事閱讀 38,694評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡割按,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出磷籍,到底是詐尸還是另有隱情适荣,我是刑警寧澤,帶...
    沈念sama閱讀 34,351評(píng)論 4 332
  • 正文 年R本政府宣布院领,位于F島的核電站弛矛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏比然。R本人自食惡果不足惜丈氓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,988評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧万俗,春花似錦湾笛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,778評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至库倘,卻和暖如春临扮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背教翩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,007評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工杆勇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迂曲。 一個(gè)月前我還...
    沈念sama閱讀 46,427評(píng)論 2 360
  • 正文 我出身青樓靶橱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親路捧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子关霸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,580評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容