“寫完這篇文章有一兩個月了,中間忙著期末考試等各種事情就沒去管它,剛運行了一下代碼發現出現了編碼錯誤,在爬取完第一頁後,出現以下錯誤:
UnicodeEncodeError: 'gbk' codec can't encode character '\u22ef' in position 93: illegal multibyte sequence。
在查詢了一些資料後,借鑒部落格園中相關說明後,在代碼開頭加上如下聲明:
import ioimport syssys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') #改變標準輸出的預設編碼
因為是我是在cmd下運行,所以需要改變標準輸出的預設編碼,具體說明請大家參照部落格園中相關說明”
更新時間:2017/1/12
====================================================================================================================================
python爬蟲一直是我想要入手的方向,通過對靜覓崔慶才的個人部落格的學習,完成了一些小項目。在此對其及其部落格表示感謝,也推薦大家學習。
本文完成的是抓取糗事百科熱門段子中python爬蟲代碼的python 3.x版本,希望給學習過相同博文且想用python3.x完成的人帶來一點啟發。
具體步驟請參照抓取糗事百科熱門段子,本文僅是成品。本文的Regex目前可用。
該項目中用到的python2.x與python3.x一些不同之處:
1.引用的模組不同,
python2.x中的urllib2在python3.x中為urllib.request
2.輸出方式不同
python2.x中的print在python3.x中為print()
3.輸入方式不同
python2.x中的raw_input()在python3.x中為input()
4.處理異常的不同
python2.x中的try: ......
except urllib2.URLError,e: ......
在python3.x中為try: ......
except urllib.request.URLError ase: ......
#糗事百科段子爬取# -*- coding: utf-8 -*-import urllib.requestimport re#修改部分import ioimport syssys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') #改變標準輸出的預設編碼#糗事百科爬蟲類class QSBK: #初始化方法,定義變數 def __init__(self): self.pageIndex = 1 self.user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' #初始化headers self.headers = { 'User-Agent' : self.user_agent } #存放段子的變數,每一個元素是每一頁的段子們 self.stories = [] #存放程式是否繼續啟動並執行變數 self.enable = False #傳入某一頁的索引獲得頁面代碼 def getPage(self,pageIndex): try: url='http://www.qiushibaike.com/hot/page/' + str(pageIndex) #構建請求的request request = urllib.request.Request(url,headers =self.headers) #利用urlopen擷取頁面代碼 response = urllib.request.urlopen(request) #將頁面轉化為UTF-8編碼 pageCode=response.read().decode('utf-8') return pageCode except urllib.request.URLError as e: if hasattr(e,"reason"): print(u"串連糗事百科失敗,錯誤原因",e.reason) return None #傳入某一頁代碼,返回本頁不帶圖片的段子列表 def getPageItems(self,pageIndex): pageCode=self.getPage(pageIndex) if not pageCode: print("頁面載入失敗....") return None pattern = re.compile('<div class="author clearfix">.*?title=.*?<h2>(.*?)</h2>.*?<div class="content">(.*?)</div>.*?<div class="stats">.*?class="number">(.*?)</i>.*?class="number">(.*?)</i>',re.S) items = re.findall(pattern,pageCode) #用來儲存每頁的段子們 pageStories=[] #遍曆Regex匹配的資訊 for item in items: text=re.sub(r'<span>|</span>'," ",item[1]) text1= re.sub(r'<br/>',"\n",text) #item[0]是一個段子的發行者,item[1]是內容,item[2]是點贊數,item[4]是評論數 pageStories.append([item[0].strip(),text1.strip(),item[2].strip(),item[3].strip()]) return pageStories #載入並提取頁面的內容,加入到列表中 def loadPage(self): #如果當前未看的頁數少於2頁,則載入新一頁 if self.enable == True: if len(self.stories) < 2: #擷取新一頁 pageStories = self.getPageItems(self.pageIndex) #將該頁的段子存放到全域list中 if pageStories: self.stories.append(pageStories) #擷取完之後頁碼索引加一,表示下次讀取下一頁 self.pageIndex += 1 #調用該方法,每次敲斷行符號列印輸出一個段子 def getOneStory(self,pageStories,page): #遍曆一頁的文章 for story in pageStories: #等待使用者輸入 Input=input() #每當輸入斷行符號一次,判斷一下是否要載入新頁面 self.loadPage() #如果輸入Q則程式結束 if Input=="Q": self.enable=False return print(u"第%d頁\t發帖人:%s\t好笑:%s\t評論:%s\n%s" %(page,story[0],story[2],story[3],story[1])) def Start(self): print(u"正在讀取糗事百科,按斷行符號查看新段子,Q退出") #使變數為True,程式可以正常運行 self.enable = True #先載入一頁內容 self.loadPage() #局部變數,控制當前讀到了第幾頁 nowPage = 0 while self.enable: if len(self.stories)>0: #從全域list中擷取一頁的段子 pageStories = self.stories[0] #當前讀到的頁數加一 nowPage += 1 #將全域list中第一個元素刪除,因為已經取出 del self.stories[0] #輸出該頁的段子 self.getOneStory(pageStories,nowPage)spider=QSBK()spider.Start()
項目效果圖: