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吧~