天天看點

中國裁判文書網爬蟲思路詳細分析 (2018年11月上旬可用)一、前言二、編寫爬蟲的主要難點三、擷取清單的詳細步驟四、擷取正文的詳細步驟五、後記

目錄

  • 一、前言
  • 二、編寫爬蟲的主要難點
      • 1.需要使用JS進行運算
      • 2.使用eval函數加密自定義函數
      • 3.使用複雜的算法消耗計算時間
      • 4.代碼中的密鑰值具有迷惑性
      • 5.對同一個IP位址的請求有限制
      • 6.加密算法政策更新比較頻繁
  • 三、擷取清單的詳細步驟
    • 1. 重要變量
      • 1) guid
      • 2) number
      • 3) conditions
      • 4) vjkl5
      • 5) vl5x
    • 2. 發送請求
    • 3. 分析結果
  • 四、擷取正文的詳細步驟
    • 1. 重要變量
      • 1) RunEval
      • 2) key
      • 3) wsid
      • 4) docid
      • 5) KeyWord
    • 2. 發送請求
    • 3. 分析結果
  • 五、後記

一、前言

最近有一些風險防範的需求,需要從中國裁判文書網批量下載下傳一些裁判文書。但人工操作過于繁瑣,于是對網站研究了一下,編寫了一個爬蟲實作了批量下載下傳目錄和正文。

這個網站的反爬蟲政策非常先進,使用了很多方法來增加爬取成本。編寫這個網站的爬蟲,需要具備豐富的經驗技巧和堅強的毅力。

這個網站的反爬蟲政策更新很快,網際網路上關于這個網站爬蟲的文章基本都失效了,于是整理出了這篇非常詳細的文章。可以幫助大家快速了解網站的層次結構和爬取的流程方法,編寫出相關的程式。

二、編寫爬蟲的主要難點

這個網站的爬取方法比較複雜,除了需要使用正常的GET和POST方法之外,還有以下方面需要考慮。

1.需要使用JS進行運算

要求用戶端運算JS,是現代反爬蟲技術比較流行的方法。爬蟲需要添加相關的邏輯來實作JS代碼裡的算法。

由于這個網站更新的頻率相當高,而且JS算法非常複雜,是以這個網站的爬蟲最好是直接引用官方的JS,而不是重新實作算法。實作的方法有很多,比如可以使用程式構造特定的HTML和JS組合,使用無界面的谷歌浏覽器來完成。

2.使用eval函數加密自定義函數

網站中的JS函數,有很多是加密的。這些函數代碼使用eval函數嵌套多層,需要用eval函數解析JS代碼多次,才能獲得原始的函數,這樣的代碼難以閱讀來分析算法,必須采用直接引用JS的方法來實作爬蟲的算法。

3.使用複雜的算法消耗計算時間

網站中有一處密鑰是用JS計算的,涉及MD5、SHA、BASE64等算法,非常複雜。經測試,一台i3處理器的計算機,計算這個密鑰需要花費六七秒種。可見官方的反爬蟲決心非常強。

4.代碼中的密鑰值具有迷惑性

代碼中有一個密鑰變量設定了初始值,看起來這個值就是最後要用的值,但實際上不是,這個密鑰變量在通訊的時候,會被更新為另一個值。為了提高分析效率,可以使用浏覽器的調試功能,加入斷點,一步一步調試,就可以迅速找到更新這個變量的位置。

5.對同一個IP位址的請求有限制

擷取清單頁面沒有限制,可以無限爬取。擷取正文頁面有限制,同一個IP位址每天不能請求太多,否則會出現驗證碼。這個驗證碼的識别還是很簡單的,可以通過識别圖像的方法解決,也可以通過更換IP的方法解決。

6.加密算法政策更新比較頻繁

這個網站的更新相當頻繁,主要是更新反爬蟲政策。為這個網站編寫爬蟲,要做好長久的分析網站、改寫爬蟲準備,代碼的結構和注釋盡量要友善自己的閱讀。

三、擷取清單的詳細步驟

1. 重要變量

1) guid

在用戶端生成的一串随機生成的16進制字元串,用減号分隔。

例如:c3495d84-0174-52af282e-1d5dffbefa00

每次通訊時都需要生成一次新值。

建立方法:Javascript

var guidCreate = function () {
    var createGuid = function () {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }
	var guid = createGuid() + createGuid() + "-" + createGuid() + "-" + createGuid() + createGuid() + "-" + createGuid() + createGuid() + createGuid();
	return guid;
}
           

2) number

将上一個步驟生成的guid通過POST方法送出給伺服器,得到一個8位長度的字元串。

例如:YUCLQLY4

送出位址:http://wenshu.court.gov.cn/ValiCode/GetCode

送出參數:guid

後期運算的時候,有時候會用number的前4位。

3) conditions

這是搜尋字元串,根據實際關鍵字拼接即可。

比如:要搜尋案件名稱為“測試”的文書,字元串為“searchWord 測試 AJMC 案件名稱:測試”,空格用加号替換,中文需要使用UTF-8字元集編碼,如:“searchWord+%E6%B5%8B%E8%AF%95+AJMC++%E6%A1%88%E4%BB%B6%E5%90%8D%E7%A7%B0:%E6%B5%8B%E8%AF%95”

4) vjkl5

将guid和number和conditions三者通過GET方法送出給伺服器,得到一個變量名為vjkl5的Cookie。

例如送出位址:http://wenshu.court.gov.cn/list/list/?sorttype=1&number=YUCLQLY4&guid=c3495d84-0174-52af282e-1d5dffbefa00&conditions=searchWord+測試+AJMC++案件名稱:測試

傳回的Cookie:

_gscu_2116842793=38217821u8ob4015; _gscbrs_2116842793=1; ASP.NET_SessionId=obvr1tuaealkxakdqpuqfsnz; Hm_lvt_d2caefee2de09b8a6ea438d74fd98db2=1539738124,1539939830,1540547054; Hm_lpvt_d2caefee2de09b8a6ea438d74fd98db2=1540547316; _gscs_2116842793=t405470532wtpyg81|pv:5; vjkl5=ff9d8c3899ffecaf6901681896c33528ecc7678d
           

其中最後一段vjkl5=ff9d8c3899ffecaf6901681896c33528ecc7678d就是。

這個送出位址需要儲存下來,擷取清單的時候也會用到。

5) vl5x

這個擷取方法比較複雜,是對vjkl5進行複雜運算之後得到。

涉及的JS加密函數比較多,最好能直接引用官方的JS代碼進行運算。

涉及到主要的代碼在

http://wenshu.court.gov.cn/Assets/js/20180914/Lawyee.CPWSW.ListExtend.js

http://wenshu.court.gov.cn/Assets/Js/pako.min.js

http://wenshu.court.gov.cn/Assets/js/dist/libs/sha1.js

http://wenshu.court.gov.cn/Assets/js/dist/libs/base64.js

http://wenshu.court.gov.cn/Assets/js/dist/libs/md5.js

運算之後的結果是類似這樣的字元串:f4f43bd13437aabc06e327ed。

2. 發送請求

清單的擷取是通過POST方法實作的。

送出位址:http://wenshu.court.gov.cn/List/ListContent

HTTP頭需要具有:

‘Host’ => ‘wenshu.court.gov.cn’

‘Referer’ => 擷取vjkl5時送出的http://wenshu.court.gov.cn/list/list開頭的位址

‘Origin’ => ‘http://wenshu.court.gov.cn’

POST參數:

‘Param’ => ‘案件名稱:測試’

‘Index’ =>目前要擷取的頁碼

‘Page’ => ‘20’

‘Order’ => ‘法院層級’,

‘Direction’ => ‘asc’,

‘vl5x’ => 之前得到的vl5x

‘number’ => 之前得到的number的前四位

‘guid’ => 重新生成一次guid

3. 分析結果

如果參數無誤,會得到一個JSON格式的文本。如:

"[{\"RunEval\":\"w61aw4vCrsKCMBDDvRbCjMKLNsOcw7gDw4TClcKfcMKXwpPChhh8wrFQTMOlwq7CjMO/LiBBwqQIeMKhwrXDoknDiBjDmsOpw4w5wqfDk8KSScKcw67DgsOVw7oUw4jDsBjDj39jGR7CtsKzwo3CjMO2wovDnVIuwqLDlcKawrnCjksCw4Zqw7MDEWDCvsKjQsOGQMOkS8KOK24lw6wtDHTCh8KyMMOYPSjChsONwoUIUALDlMKhCcO4woMwWEMOCAN1wqATw4jCgRJ2AAbChWDCocOhwp7Dp8OPJ0F0OMOFw7IvwogjOcOxfMOyRcOyMMOmwp4vwqlbw7HCnC/CnG4rKTFCwrjDjMOJJjg9w4ZMJ8OaZ8Kyw5fDqcO9w58Jw4TDksOhw4TCg8KcdMKGBCU/wpXChMKPw65Owr7DoHnCsgrDrlrDn0ZMw6Vow7XDo0XCqgzCtSrCkQLCocKWQ0PDrAJkN0VLwq/CrcKwO3rCvMOiw7bCssOvw78Ww7RYw5V3wqlaW8KDRR0uw4jDgMKRWsKPw7XCoMKJwrTDhcKsHsKlwobCjXwyw5rDocKieBNVwrPCkA3CnwlLE2ssflPCjDQeM8ONwrVmw7AuMsOPw49Iwo19w7DDl0EvNcOzwojDm8OTwr4Jw5M4ah3DkcOHASBHw4EqLU7CpwbDjkrCvWrDujXChRzDpcO9N8Odw7thZcK0HMKQenTCnBbCiQc8wqXCtMKcccOvCg==\",\"Count\":\"965\"},{\"裁判要旨段原文\":\"本院認為,根據再審申請人的申請再審事由,本院對再審申請人是否侵犯某公司的名譽權進行審查:
《最高人民法院關于審理名譽權案件若幹問題的解釋》規定:消費者對生産者、經營者、銷售者的産品品質或者服務品質進行批評、評論,不應當認定為侵害他人名譽權。但借機\",\"不公開理由\":\"\",\"案件類型\":\"2\",\"裁判日期\":\"2017-07-27\",\"案件名稱\":\"王某、某公司測試合同糾紛再審審查與審判監督民事裁定書\",\"文書ID\":\"DcOOw4cRw4BACMOAw4DClsOIHE9iw78lw5kFaFbCsSdEQH3Dm8KGdsOwwqRzXRjCvGV9DgxcB0ENwrDCuEM5wo9vNDlaIMKFw4/DlMOFLifDujjCnDpNwrYzwpXDh3DCuABfMcOlVsKRXcOZwrTDpD1DwqUnD3wofTAPwrUqJjbDg8Ovw6zDgsO5CEoDIQl7wqZgw7dHQkgRW33CvcKjw7/DrXbDosOmw7s/wrjDv8KQwojDng9Sw6gdG8K3fA==\",\"審判程式\":\"再審審查與審判監督\",\"案号\":\"(2017)最高法民申0000号\",\"法院名稱\":\"最高人民法院\"},{\"裁判要旨段原文\":\"本院認為:雙方解除勞動關系後辦理工作交接手續是勞動者應盡的義務。雙方在交接過程中發生摩擦,某公司要求李某支付是以産生的誤工費、換鎖和解碼費用,原審認為該訴請不屬勞動争議調整範圍不予處理。某公司的權利并未被剝奪,可以另行主張,故該公司以原審\",\"案件類型\":\"2\",\"裁判日期\":\"2014-03-13\",\"案件名稱\":\"某公司與李某勞動争議糾紛民事再審裁定書\",\"文書ID\":\"DcOMw4cRw4AwDMOEw4DClsKOSTTCn2LDqsK/JMOrwovDgcKsD2DCqsKGA8O5ICDCmxErUQ8aw77DmMKUHMOZfsOMwqjDqybCq8K9wpzDiULDisKLe8KuWzHDpcOOw7cZOsOjaTLConAywovDlT7Cq1XCjkDDpDA8wqRQwo/Dq8KPPW9cwqbCmMKsGxNAw7JmPQnDrFotwpzDjcOGw6DClGrCo1lAw73CrsOdFMObPmPCp2TDvcOtOgfCmsKaG35pwrl5wofCjsOKHsOKw4gf\",\"審判程式\":\"再審審查與審判監督\",\"案号\":\"(2013)豫法立二民申字第0000号\",\"法院名稱\":\"河南省進階人民法院\"},……
           

對其進行格式化:

"[
    {
        \"RunEval\": \"w61aw4vCrsKCMBDDvRbCjMKLNsOcw7gDw4TClcKfcMKXwpPChhh8wrFQTMOlwq7CjMO/LiBBwqQIeMKhwrXDoknDiBjDmsOpw4w5wqfDk8KSScKcw67DgsOVw7oUw4jDsBjDj39jGR7CtsKzwo3CjMO2wovDnVIuwqLDlcKawrnCjksCw4Zqw7MDEWDCvsKjQsOGQMOkS8KOK24lw6wtDHTCh8KyMMOYPSjChsONwoUIUALDlMKhCcO4woMwWEMOCAN1wqATw4jCgRJ2AAbChWDCocOhwp7Dp8OPJ0F0OMOFw7IvwogjOcOxfMOyRcOyMMOmwp4vwqlbw7HCnC/CnG4rKTFCwrjDjMOJJjg9w4ZMJ8OaZ8Kyw5fDqcO9w58Jw4TDksOhw4TCg8KcdMKGBCU/wpXChMKPw65Owr7DoHnCsgrDrlrDn0ZMw6Vow7XDo0XCqgzCtSrCkQLCocKWQ0PDrAJkN0VLwq/CrcKwO3rCvMOiw7bCssOvw78Ww7RYw5V3wqlaW8KDRR0uw4jDgMKRWsKPw7XCoMKJwrTDhcKsHsKlwobCjXwyw5rDocKieBNVwrPCkA3CnwlLE2ssflPCjDQeM8ONwrVmw7AuMsOPw49Iwo19w7DDl0EvNcOzwojDm8OTwr4Jw5M4ah3DkcOHASBHw4EqLU7CpwbDjkrCvWrDujXChRzDpcO9N8Odw7thZcK0HMKQenTCnBbCiQc8wqXCtMKcccOvCg==\",
        \"Count\": \"965\"
    },
    {
        \"裁判要旨段原文\": \"本院認為,根據再審申請人的申請再審事由,本院對再審申請人是否侵犯某公司的名譽權進行審查:
《最高人民法院關于審理名譽權案件若幹問題的解釋》規定:消費者對生産者、經營者、銷售者的産品品質或者服務品質進行批評、評論,不應當認定為侵害他人名譽權。但借機\",
        \"不公開理由\": \"\",
        \"案件類型\": \"2\",
        \"裁判日期\": \"2017-07-27\",
        \"案件名稱\": \"王某、某公司測試合同糾紛再審審查與審判監督民事裁定書\",
        \"文書ID\": \"DcOOw4cRw4BACMOAw4DClsOIHE9iw78lw5kFaFbCsSdEQH3Dm8KGdsOwwqRzXRjCvGV9DgxcB0ENwrDCuEM5wo9vNDlaIMKFw4/DlMOFLifDujjCnDpNwrYzwpXDh3DCuABfMcOlVsKRXcOZwrTDpD1DwqUnD3wofTAPwrUqJjbDg8Ovw6zDgsO5CEoDIQl7wqZgw7dHQkgRW33CvcKjw7/DrXbDosOmw7s/wrjDv8KQwojDng9Sw6gdG8K3fA==\",
        \"審判程式\": \"再審審查與審判監督\",
        \"案号\": \"(2017)最高法民申0000号\",
        \"法院名稱\": \"最高人民法院\"
    },
    {
        \"裁判要旨段原文\": \"本院認為:雙方解除勞動關系後辦理工作交接手續是勞動者應盡的義務。雙方在交接過程中發生摩擦,某公司要求李某支付是以産生的誤工費、換鎖和解碼費用,原審認為該訴請不屬勞動争議調整範圍不予處理。某公司的權利并未被剝奪,可以另行主張,故該公司以原審\",
        \"案件類型\": \"2\",
        \"裁判日期\": \"2014-03-13\",
        \"案件名稱\": \"某公司與李某勞動争議糾紛民事再審裁定書\",
        \"文書ID\": \"DcOMw4cRw4AwDMOEw4DClsKOSTTCn2LDqsK/JMOrwovDgcKsD2DCqsKGA8O5ICDCmxErUQ8aw77DmMKUHMOZfsOMwqjDqybCq8K9wpzDiULDisKLe8KuWzHDpcOOw7cZOsOjaTLConAywovDlT7Cq1XCjkDDpDA8wqRQwo/Dq8KPPW9cwqbCmMKsGxNAw7JmPQnDrFotwpzDjcOGw6DClGrCo1lAw73CrsOdFMObPmPCp2TDvcOtOgfCmsKaG35pwrl5wofCjsOKHsOKw4gf\",
        \"審判程式\": \"再審審查與審判監督\",
        \"案号\": \"(2013)豫法立二民申字第0000号\",
        \"法院名稱\": \"河南省進階人民法院\"
    },
……
           

RunEval是用來解密本頁正文網址的重要字元串。

Count是本次查詢得到的記錄條數。

後面是查詢結果的資訊,每條記錄都有:裁判要旨段原文、案件類型、裁判日期、案件名稱、文書ID、審判程式、案号、法院名稱。文書ID包含了加密之後的正文網址資訊,解密之後即可獲得。

四、擷取正文的詳細步驟

1. 重要變量

1) RunEval

在上一個擷取清單的步驟裡,傳回的資訊包含RunEval。

2) key

key是一個16進制字元串,如:64da29c4a3550111c751824d。

這裡的key在JS代碼裡的完整名字是:com.str._KEY。在一處代碼裡,明确寫了com.str._KEY初始值為:12345678900000001234567890000000,但這個值是不能用的。需要由RunEval進行複雜運算獲得。擷取方法比較複雜,可以通過執行JS的方法獲得,涉及到的JS檔案有:

http://wenshu.court.gov.cn/Assets/Js/components/core-min.js

http://wenshu.court.gov.cn/Assets/js/20180919/Lawyee.CPWSW.List.js

http://wenshu.court.gov.cn/Assets/Js/rollups/aes.js

http://wenshu.court.gov.cn/Assets/js/Base64.js

http://wenshu.court.gov.cn/Assets/Js/rawinflate.js

http://wenshu.court.gov.cn/Assets/Js/rawdeflate.js

http://wenshu.court.gov.cn/Assets/Js/pako.min.js

3) wsid

将前面獲得的每條記錄的文書ID,設為wsid。

4) docid

在将key 指派為com.str._KEY後,使用JS代碼中的Navi函數,加入參數是wsid,可以算出docid。

docid是一串16進制字元,用減号分隔,如:a374170b-47d0-405b-8d82-a834012d069c。

擷取方法比較複雜,可以通過執行JS的方法獲得,涉及到的JS檔案有:

http://wenshu.court.gov.cn/Assets/Js/components/core-min.js

http://wenshu.court.gov.cn/Assets/js/20180919/Lawyee.CPWSW.List.js

http://wenshu.court.gov.cn/Assets/Js/rollups/aes.js

http://wenshu.court.gov.cn/Assets/js/Base64.js

http://wenshu.court.gov.cn/Assets/Js/rawinflate.js

http://wenshu.court.gov.cn/Assets/Js/rawdeflate.js

http://wenshu.court.gov.cn/Assets/Js/pako.min.js

5) KeyWord

搜尋時用的關鍵字,中文需要使用UTF-8字元集編碼。

2. 發送請求

清單的擷取是通過GET方法實作的。

送出位址:http://wenshu.court.gov.cn/CreateContentJS/CreateContentJS.aspx

HTTP頭需要具有:

‘Referer’ => http://wenshu.court.gov.cn/content/content?DocID=“獲得的docid”&KeyWord=“獲得的KeyWord”

參數需要有:

‘DocID’ =>“獲得的docid”

3. 分析結果

如果參數無誤,會得到一段JS代碼。如:

$(function(){$("#con_llcs").html("浏覽:1329次")});$(function(){var caseinfo=JSON.stringify({"法院ID":"0","案件基本情況段原文":"","附加原文":"","審判程式":"再審審查與審判監督","案号":"(2017)最高法民申0000号","不公開理由":"","法院地市":"","法院省份":"最高人民法院","文本首部段落原文":"","法院區域":"","文書ID":"a374170b-47d0-405b-8d82-a834012d069c","案件名稱":"王某、某公司測試合同糾紛再審審查與審判監督民事裁定書","法院名稱":"最高人民法院","裁判要旨段原文":"","法院區縣":"","補正文書":"2","DocContent":"","文書全文類型":"1","訴訟記錄段原文":"再審申請人王某因與被申請人某公司(以下簡稱某公司)、一審被告某公司、某中心侵犯名譽權糾紛一案,不服青海省進階人民法院(2016)青民終000号民事判決,向本院申請再審。本院依法組成合議庭對本案進行了審查,現已審查終結","判決結果段原文":"","文本尾部原文":"","上傳日期":"\/Date(1531497600000)\/","案件類型":"2","訴訟參與人資訊部分原文":"","文書類型":null,"裁判日期":null,"結案方式":null,"效力層級":null});$(document).attr("title","王某、某公司測試合同糾紛再審審查與審判監督民事裁定書");$("#tdSource").html("王某、某公司測試合同糾紛再審審查與審判監督民事裁定書 (2017)最高法民申0000号");$("#hidDocID").val("a374170b-47d0-405b-8d82-a834012d069c");$("#hidCaseName").val("王某、某公司測試合同糾紛再審審查與審判監督民事裁定書");$("#hidCaseNumber").val("(2017)最高法民申0000号");$("#hidCaseInfo").val(caseinfo);$("#hidCourt").val("最高人民法院");$("#hidCaseType").val("2");$("#HidCourtID").val("0");$("#hidRequireLogin").val("0");});$(function(){var dirData = {Elements: ["RelateInfo", "LegalBase"],RelateInfo: [{ name: "審理法院", key: "court", value: "最高人民法院" },{ name: "案件類型", key: "caseType", value: "民事案件" },{ name: "案由", key: "reason", value: "測試合同糾紛" },{ name: "審理程式", key: "trialRound", value: "再審審查與審判監督" },{ name: "裁判日期", key: "trialDate", value: "2017-07-27" },{ name: "當事人", key: "appellor", value: "王某,某公司,某公司,某中心" }],LegalBase: [{法規名稱:'《中華人民共和國民事訴訟法》',Items:[{法條名稱:'第二百零四條',法條内容:'第二百零四條   系統尚未收錄或引用有誤
'}]}]};if ($("#divTool_Summary").length > 0) {$("#divTool_Summary").ContentSummary({ data: dirData });}});$(function() {
var jsonHtmlData = "{\"Title\":\"王某、某公司測試合同糾紛再審審查與審判監督民事裁定書\",\"PubDate\":\"2018-07-14\",\"Html\":\"<a type='dir' name='WBSB'></a><div style='TEXT-ALIGN: center; LINE-HEIGHT: 25pt; MARGIN: 0.5pt 0cm; FONT-FAMILY: 宋體; FONT-SIZE: 22pt;'>中華人民共和國最高人民法院</div><div style='TEXT-ALIGN: center; LINE-HEIGHT: 30pt; MARGIN: 0.5pt 0cm; FONT-FAMILY: 仿宋; FONT-SIZE: 26pt;'>民 事 裁 定 書</div><div style='TEXT-ALIGN: right; LINE-HEIGHT: 30pt; MARGIN: 0.5pt 0cm;  FONT-FAMILY: 仿宋;FONT-SIZE: 16pt; '>(2017)最高法民申2170号</div><a type='dir' name='DSRXX'></a><div style='LINE-HEIGHT: 25pt;TEXT-ALIGN:justify;TEXT-JUSTIFY:inter-ideograph; TEXT-INDENT: 30pt; MARGIN: 0.5pt 0cm;FONT-FAMILY: 仿宋; FONT-SIZE: 16pt;'>
           

這裡各個字段寫的很清楚,正文的HTML代碼也在裡面,直接提取出來就可以了。

五、後記

按照這個思路編寫出程式,就可以順利爬取了。到這裡,整個流程就介紹完了。