話說晚上上完爬蟲抓取班會之後羣裏有童鞋扔出來了一個網址
www.runoob.com/python/python-exercise-example1.html
並且疑問說這個地址用urllib2抓出來的居然是亂碼希望大家一起看看。本着上山打老虎的精神我先是不信邪的寫了一下代碼重新運行了一下然後出來一大羣這種東西。
【代碼1】
import urllib2
ur1='http://www.runoob.com/python/python-exercise-example1.html'
reponse=urllib2.urlopen(ur1)
r=reponse.read()
print r
【運行結果1】
瞬間感覺有一種扯淡的感覺。不過作爲一個白條碼農雖然可能沒有“愚公移山”找bug的精神但不找一找總感覺有點不太對所以根據僅有的一點知識就開始進行嘗試開始認爲是編碼問題而且一般來講很大可能也是編碼問題就先試着轉了一下碼。因爲網頁是utf8編碼不知道如何查看網頁編碼的同學請找度娘詢問一下所以就想着轉碼一下估計就可以了於是就利用了decode轉碼先嚐試一下。
爲小白着想解釋一下decode:decode的作用是將其他編碼的字符串轉換成unicode編碼如str1.decode('gb2312')表示將gb2312編碼的字符串str1轉換成unicode編碼。
【代碼2】
import urllib2
ur1='http://www.runoob.com/python/python-exercise-example1.html'
reponse=urllib2.urlopen(ur1)
r=reponse.read()
r=r.decode('utf-8')
當我在等着biu一下就好了的時候結果又坑了。
【運行結果2】
UnicodeDecodeError: 'utf8' codec can't decode byte 0x8b in position 1: invalid start byte。
看到這個結果之後我第一個想法是是不是網頁內部還存在其他編碼不止utf8在個別位置還採用了其他類型的編碼。於是又去找了一下度娘根據某些大神的說法一般對於中文網站基本是UTF-8,GB2312,可以GB18030通吃。於是我又把最後 r=r.decode('utf-8')中的編碼改成了r=r.decode('GB2312')可是結果還是出現了問題。
【運行結果2-GB2312】
UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 1-2: illegal multibyte sequence
這個時候根據我僅有的一點小白知識發現這個問題貌似我有點不知道該怎麼解決了但在這個時候我想還是試試python3吧如果還不行我就繳械投降了。
於是有用python3的requests模塊兒寫了一下。
【代碼3-python3】
import requests
r=requests.get("http://www.runoob.com/python/python-exercise-example1.html")
print(r.encoding)#打印網頁內容編碼
print(r.text)#打印網頁內容
當我等着報錯的時候居然出了結果。
【運行結果3】
utf-8網頁編碼
<!Doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Python 練習實例1 | 菜鳥教程</title>
結果太長只摘取部分內容
當看到結果我就在想python3可以出來而2出現亂碼而且程序報出的編碼確實是utf8那會不會是兩者對網頁的解析不太一樣python2缺少了某些步驟或者方法。於是就問了度娘”python2抓取網頁亂碼問題“這個時候就看到了答案
很多亂碼問題是編碼造成的但另一個造成亂碼的原因是壓縮格式很多規模較大的網站都是以gzip的壓縮格式輸出頁面的所以在用BS解析之前需要先判斷該網頁是否經過壓縮如果經過壓縮則先進行解壓操作。
緊接着下一步就開始嘗試解壓縮
【代碼4】
import gzip
import StringIO
import urllib2
ur1='http://www.runoob.com/python/python-exercise-example1.html'
reponse=urllib2.urlopen(ur1)
r=reponse.read()
data = StringIO.StringIO(r)
gzipper = gzip.GzipFile(fileobj=data)
html = gzipper.read()
print html
解決問題
【運行結果4】
<!Doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Python 練習實例1 | 菜鳥教程</title>
結果太長只摘取部分內容
【附1:關於亂碼問題簡單介紹的網頁】
http://www.cnblogs.com/bbcar/p/3625084.html
【附2:用python爬蟲抓站的一些技巧總結】
http://www.open-open.com/lib/view/open1375945149312.html
ps感謝張錦添同學提出的問題及最後找到的技巧總結