一日一技:HTML里面提取的JSON怎么解析不了?

我們在開發(fā)爬蟲的過程中,經(jīng)常發(fā)現(xiàn)有一些網(wǎng)站,會直接把數(shù)據(jù)以JSON的形式,通過<script>標(biāo)簽放到頁面源代碼中。如下圖所示:

有時候請求URL拿到HTML的過程比較麻煩,有些同學(xué)習(xí)慣先把HTML復(fù)制到代碼里面,先把解析的邏輯寫好,然后再去開發(fā)請求HTML的代碼。
這個思路本身是沒有什么問題的,于是他們就寫了如下的代碼:
代碼中的html_data = '''里面就是原樣復(fù)制的網(wǎng)頁HTML,沒有做任何修改,因為太長了,我這里做了折疊。展開以后如下圖所示:

但當(dāng)運行這段代碼的時候,發(fā)現(xiàn)代碼報錯了,如下圖所示:

看這個報錯信息,難道說是JSON本身有問題?于是,你到網(wǎng)頁上,把這個JSON復(fù)制下來:
使用JSONHero這種驗證網(wǎng)站,進(jìn)行驗證,結(jié)果發(fā)現(xiàn)一切正常:

這就見鬼了,為什么正則表達(dá)式提取的JSON就不對呢?你開啟PyCharm的調(diào)試模式,看看正則表達(dá)式提取出來的JSON:

你把提取出來的JSON復(fù)制粘貼到JSONHero網(wǎng)站上,竟然報錯了:
到底是哪里有問題呢?為什么直接從網(wǎng)頁上復(fù)制JSON就沒有問題,而使用正則表達(dá)式提取的JSON就有問題呢?
其實原因非常簡單,問題就出現(xiàn)在HTML中的JSON里面的反斜杠:

我們知道,反斜杠是不能單獨存在的,它有自己獨特的意義。在代碼里面,我使用了'''三個引號來抱住整個網(wǎng)頁的HTML,這個時候,Python發(fā)現(xiàn)這里的\"這種寫法,會自動把反斜杠去掉。于是,正則表達(dá)式提取出來的JSON,引號就會出現(xiàn)沖突,如下圖所示:
這樣的JSON就會變成不合法的JSON。因為在JSON中,字符串內(nèi)部作為普通字符的雙引號,應(yīng)該使用反斜杠轉(zhuǎn)義。但是對這個多行字符串來說,反斜杠又不能單獨存在,所有需要寫成兩根反斜杠,否則反斜杠被自動刪除。
要解決這個問題,有三種方法:
-
手動修改JSON里面的所有反斜杠,把每一根反斜杠變成兩根反斜杠: \"->\\"。(太麻煩了,就不演示了) -
在三引號前加上 r,此時Python會自動把所有的反斜杠轉(zhuǎn)換為普通的字符串:
-
把HTML寫到文件里面,通過讀文件的形式來讀源代碼。Python自動就會處理反斜杠。
總結(jié),這個問題只有在你直接把HTML粘貼到Python代碼里面的時候會出現(xiàn)。如果你是直接使用Requests請求網(wǎng)頁,或者你把HTML存到文件里面,通過讀文件的形式來讀HTML,那么Python都能自動處理好這個反斜杠的問題。
點擊關(guān)注公眾號,閱讀更多精彩內(nèi)容

