requests的content與text導致lxml的解析問題


title: requests的content與text導致lxml的解析問題
date: 2015-04-29 22:49:31
categories: 經驗
tags: [Python,lxml,etree]

最近實習工作任務比較重,又在做數據挖掘的教學工作,同時還在做畢設,所以博客更新比較慢。不過最近肯定會有大動作。

閑話畢,轉正題。在制作新浪微博模擬登錄的部分時,遇到了一些問題。

我使用requests獲取了新浪微博的源代碼,通過lxml庫的etree.HTML來處理一段網頁源代碼,從而生成一個可以被xpath解析的對象。

selector = etree.HTML(html)

遇到報錯:

selector = etree.HTML(html)
  File "lxml.etree.pyx", line 2953, in lxml.etree.HTML (src\lxml\lxml.etree.c:66734)
  File "parser.pxi", line 1780, in lxml.etree._parseMemoryDocument (src\lxml\lxml.etree.c:101591)
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

根據報錯信息推測,可能是因為不支持編碼聲明的Unicode字符串。Google發現這個問題在2012年就已經有人提交給作者了,但是一直沒有被修復。地址在->https://gist.github.com/karlcow/3258330

不過下面的人也給出了解決辦法:

html = bytes(bytearray(html, encoding='utf-8'))
selector = etree.HTML(html)

首先將源代碼轉化成比特數組,然后再將比特數組轉化成一個比特對象。這樣就可以繞過這個bug。

然而,又有人認為這不是一個bug, 所以一直沒有被修復。這是由於,我獲取源代碼是使用r.text

html = requests.get('xxxxxx',cookies=cookies).text

而如果使用r.content:

html = requests.get('xxxxxx',cookies=cookies).content

就不會報錯。

那r.text與r.content有什么區別呢?分析requests的源代碼發現,r.text返回的是Unicode型的數據,而使用r.content返回的是bytes型的數據。也就是說,在使用r.content的時候,他已經只帶了

html = bytes(bytearray(html, encoding='utf-8'))

這樣一個轉化了。

最近CentOS都聲明放棄Python2了,編碼問題確實浪費了很多時間,等空下來轉Python3吧~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM