最近在看一個大神的博客,從他那里學會了很多關於python爬蟲的知識,其實python如果想用在實際應用中,你需要了解許多,比如正則表達式、引入庫、過濾字段等等,下面不多說,我下面的程序是爬取Ubuntu吧的一個帖子,要是問我為什么選擇Ubuntu吧,沒為什么,win、mac、linux我都用,但毫無疑問,我最喜歡的系統就是ubuntu linux,這個系統讓我學會了很多東西,從基本命令到shell編程等等,這個系統讓我深入了解了操作系統,也讓我對操作系統的概念有了進一步的學習和了解,ok,下面就是我的代碼,作為參考:
#coding=utf-8 # __author__ = 'Abel' import urllib import urllib2 import re #處理頁面標簽類 class Tool: #去除img標簽,7位長空格 removeImg = re.compile('<img.*?>| {7}|') #刪除超鏈接標簽 removeAddr = re.compile('<a.*?>|</a>') #把換行的標簽換為\n replaceLine = re.compile('<tr>|<div>|</div>|</p>') #將表格制表<td>替換為\t replaceTD= re.compile('<td>') #把段落開頭換為\n加空兩格 replacePara = re.compile('<p.*?>') #將換行符或雙換行符替換為\n replaceBR = re.compile('<br><br>|<br>') #將其余標簽剔除 removeExtraTag = re.compile('<.*?>') def replace(self,x): x = re.sub(self.removeImg,"",x) x = re.sub(self.removeAddr,"",x) x = re.sub(self.replaceLine,"\n",x) x = re.sub(self.replaceTD,"\t",x) x = re.sub(self.replacePara,"\n ",x) x = re.sub(self.replaceBR,"\n",x) x = re.sub(self.removeExtraTag,"",x) #strip()將前后多余內容刪除 return x.strip() #百度貼吧爬蟲類 class BDTB: #初始化,傳入基地址,是否只看樓主的參數 def __init__(self,baseUrl,seeLZ,floorTag): #base鏈接地址 self.baseURL = baseUrl #是否只看樓主 self.seeLZ = '?see_lz='+str(seeLZ) #HTML標簽剔除工具類對象 self.tool = Tool() #全局file變量,文件寫入操作對象 self.file = None #樓層標號,初始為1 self.floor = 1 #默認的標題,如果沒有成功獲取到標題的話則會用這個標題 self.defaultTitle = u"百度貼吧" #是否寫入樓分隔符的標記 self.floorTag = floorTag #傳入頁碼,獲取該頁帖子的代碼 def getPage(self,pageNum): try: #構建URL url = self.baseURL+ self.seeLZ + '&pn=' + str(pageNum) request = urllib2.Request(url) response = urllib2.urlopen(request) #返回UTF-8格式編碼內容 return response.read().decode('utf-8') #無法連接,報錯 except urllib2.URLError, e: if hasattr(e,"reason"): print u"連接百度貼吧失敗,錯誤原因",e.reason return None #獲取帖子標題 def getTitle(self,page): #得到標題的正則表達式 pattern = re.compile('<h1 class="core_title_txt.*?>(.*?)</h1>',re.S) result = re.search(pattern,page) if result: #如果存在,則返回標題 return result.group(1).strip() else: return None #獲取帖子一共有多少頁 def getPageNum(self,page): #獲取帖子頁數的正則表達式 pattern = re.compile('<li class="l_reply_num.*?</span>.*?<span.*?>(.*?)</span>',re.S) result = re.search(pattern,page) if result: return result.group(1).strip() else: return None #獲取每一層樓的內容,傳入頁面內容 def getContent(self,page): #匹配所有樓層的內容 pattern = re.compile('<div id="post_content_.*?>(.*?)</div>',re.S) items = re.findall(pattern,page) contents = [] for item in items: #將文本進行去除標簽處理,同時在前后加入換行符 content = "\n"+self.tool.replace(item)+"\n" contents.append(content.encode('utf-8')) return contents def setFileTitle(self,title): #如果標題不是為None,即成功獲取到標題 if title is not None: self.file = open(title + ".txt","w+") else: self.file = open(self.defaultTitle + ".txt","w+") def writeData(self,contents): #向文件寫入每一樓的信息 for item in contents: if self.floorTag == '1': #樓之間的分隔符 floorLine = "\n" + str(self.floor) + u"-----------------------------------------------------------------------------------------\n" self.file.write(floorLine) self.file.write(item) self.floor += 1 def start(self): indexPage = self.getPage(1) pageNum = self.getPageNum(indexPage) title = self.getTitle(indexPage) self.setFileTitle(title) if pageNum == None: print "URL已失效,請重試" return try: print "該帖子共有" + str(pageNum) + "頁" for i in range(1,int(pageNum)+1): print "正在寫入第" + str(i) + "頁數據" page = self.getPage(i) contents = self.getContent(page) self.writeData(contents) #出現寫入異常 except IOError,e: print "寫入異常,原因" + e.message finally: print "寫入任務完成" print u"請輸入帖子代號" baseURL = 'http://tieba.baidu.com/p/3560761301' + str(raw_input(u'http://tieba.baidu.com/p/3560761301')) seeLZ = raw_input("是否只獲取樓主發言,是輸入1,否輸入0\n") floorTag = raw_input("是否寫入樓層信息,是輸入1,否輸入0\n") bdtb = BDTB(baseURL,seeLZ,floorTag) bdtb.start()
程序運行結果:
然后打開工程文件里生成的ubuntu.txt文件,爬取的內容如下:
是不是很神奇,反正我是感覺很神奇:-)