什麼情況?python這次居然被web scraper比下去了

週末,永恆君和一位B站網友討論交流了一下關於web scraper爬取網頁的問題。今天來和各位分享一下,希望能給大家有幫助。

需求

1、爬取的網站地址:

http://wenshu.court.gov.cn/website/wenshu/181217BMTKHNT2W0/index.html?pageId=7bcf3b0574e320a487ada1f504759be4&s21=%E8%B5%94%E5%81%BF

2、需要抓取的信息

爬取文書列表內容,報告標題、文號、日期、摘要等等信息。

3、需要抓取多頁,比如說前10頁。

分析網站的情況

1、抓取的頁面翻頁的時候,url是不會變的。而在頁面的源碼當中又找不到內容,說明網頁是通過異步加載的。

2、打開F12,就會彈出下面的暫停提示,阻止後續的查看。沒事,點擊右下角的取消斷點,再運行即可。

3、點擊“network”,點擊網頁的第二頁,查看請求的數據。

可以看到,是post請求,後面需要有一堆的參數

一般而言,通過這樣請求之後,可以獲取到真實的json文件,裏面就包含了網頁中文書的列表當中,然而這次卻是不一樣,請求得到的居然是加密的信息,還需要通過一定方式來進行解密纔行。

到這裏,已經可以感受到網頁開發人員的“苦心”,反爬的措施可謂是非常的多。不過,我還是在網上找到了一篇網友關於用python解決這上面問題的辦法和代碼,有需要的時候可以參考一下。這裏有些內容在自己的能力圈之外,就暫時不考慮了。

https://blog.csdn.net/Since_you/article/details/100566633

web scraper爬取

用python比較複雜的話,那麼就考慮用web scraper來試試。

python爬取的效率當然高,但是反爬的太厲害了,大部分的網站都會對python進行一定的限制和爬取,這樣寫代碼的成本就無形增加了很多。

web scraper則不用考慮這麼多,只要瀏覽器裏面能看到數據,就能夠進行爬取。

回頭看看網站的情況:一是url不變,二是數據不在網頁源碼當中。那麼就考慮“動態加載進行翻頁”的這種情況,之前永恆君寫過這個教程:

傳送門在這裏

主要配置如圖:

關鍵點就是"selector type"和"click selector"的配置

"selector type"(用於選擇網頁中的文書列表)選擇"Element click"
"click selector"(用於翻頁)這裏需要注意,一般如果是直接在網頁點選的話,得到的css代碼是這樣的

.left_7_3 a:nth-of-type(n+2)

表示的意思就是從第二個翻頁器(上一頁爲第一個,1爲第二個)開始點擊,一直到最後一個。

因爲這個url有非常多的頁,比如,如果希望只取前5頁的話,可以如下更改:

.left_7_3 a:nth-of-type(-n+6)

n的取值是從0開始的。

然後再在這個選擇器下面,配置標題、文號、日期、摘要的選擇器。

最終的結構圖就是這樣的:

爬取的過程及結果就是這樣的:


這個方法相對python而言,節省的時間可不止一點點,結果基本上一致。

這裏把上面的web scraper的配置也分享一下:

{"_id":"caipan","startUrl":["http://wenshu.court.gov.cn/website/wenshu/181217BMTKHNT2W0/index.html?pageId=7bcf3b0574e320a487ada1f504759be4&s21=%E8%B5%94%E5%81%BF"],"selectors":[{"id":"list","type":"SelectorElementClick","parentSelectors":["_root"],"selector":"div.LM_list:nth-of-type(n+3)","multiple":true,"delay":0,"clickElementSelector":".left_7_3 a:nth-of-type(-n+4)","clickType":"clickOnce","discardInitialElements":"do-not-discard","clickElementUniquenessType":"uniqueText"},{"id":"title","type":"SelectorLink","parentSelectors":["list"],"selector":"a.caseName","multiple":false,"delay":0},{"id":"number","type":"SelectorText","parentSelectors":["list"],"selector":"span.ah","multiple":false,"regex":"","delay":0},{"id":"date","type":"SelectorText","parentSelectors":["list"],"selector":"span.cprq","multiple":false,"regex":"","delay":0},{"id":"content","type":"SelectorText","parentSelectors":["list"],"selector":"p","multiple":false,"regex":"","delay":0}]}

批量下載word文書

每個文書都提供有word下載的鏈接,但是實現批量下載還是有一點困難。

1、word的下載鏈接直接在按鈕或者網頁源碼裏面是提取不到的,是需要根據文書的url中的"docId"參數來構造的,即

http://wenshu.court.gov.cn/down/one?” + docID地址

例如:

爬取到的文書的詳細頁地址爲:

http://wenshu.court.gov.cn/website/wenshu/181107ANFZ0BXSK4/index.html?docId=f9ffb134f0cb4a2ab832abea01298704

那麼下載地址就是:

http://wenshu.court.gov.cn/down/one?docId=f9ffb134f0cb4a2ab832abea01298704

2、有了這個地址之後,原本以爲可以直接用迅雷、IDM等軟件來批量下載,但是很顯然,網站的開發人員限制了。經過不同方法的驗證,發現目前只能是通過瀏覽器來挨個下載。(另外,可能可以通過python設置各種反爬的方法來實現批量下載的目的,但是工程量比較大,我沒試驗成功,理論上應該是可的。)

那麼就用了最笨的方法,藉助python來模擬鼠標鍵盤的操作,將url批量的輸入到瀏覽器當中,實現批量下載。

下面是單次下載的代碼,批量的話只需要讀取web scraper爬取的文件,構造好url,通過一個循環,依次輸入下載即可。

import time
import pyautogui

time.sleep(1)
url_position = (160, 50) #url位置

def input_id(x,y,url): #輸入url的動作
    pyautogui.moveTo(x, y, duration=0.2)  #0.25表示完成移動的時間          
    pyautogui.click(button='left')
    time.sleep(0.5)
    pyautogui.typewrite(url,0.01)#輸入字符,0.1表示輸入每個字符間隔的時間
    time.sleep(0.5)
    pyautogui.press("enter")

url1 = "http://wenshu.court.gov.cn/down/one?docId=694b012a59e34ae19967abeb00d512dc"

input_id(url_position[0],url_position[1],url1)


小結一下:

1、python固然強大,但是有時用web scraper可以效率更高,節省更多的時間。

2、web scraper爬取url不變、異步加載的網頁,關鍵是"selector type"和"click selector"的配置,可以參考永恆君之前分享web scraper的教程。

3、python可以通過pyautogui庫,來實現自動化操作任意鼠標、鍵盤的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章