python爬蟲爬取NBA貼吧的所有精品貼
阿新 • • 發佈:2019-01-08
首先用直接的方法寫,先嚐試下能否爬取成功 #coding:utf-8 import urllib2,urllib import re ''' 1.準備url地址 2.準備請求頭 3.建立請求物件 4.發起請求獲取第一頁原始碼,接收響應 5.通過第一頁原始碼,找到總頁數和標題 6.for迴圈執行總頁數次 6.1 根據頁碼拼接完整的URL地址 6.2 建立request物件,發起請求,接受響應 6.3 根據正則匹配資料,包含使用者名稱和帖子內容 6.4 去除、替換資料中的html標籤 6.5 寫入本地檔案 ''' ide = raw_input('請輸入要爬取的帖子的編號:') #1準備url地址 url = 'https://tieba.baidu.com/p/'+ide #2準備請求頭 headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50' } #3建立請求物件 request = urllib2.Request(url,headers=headers) #4發起請求獲取第一頁原始碼,接受響應 response = urllib2.urlopen(request) # 5.通過第一頁原始碼,找到總頁數和標題#5.1準備正則 pattern = re.compile(r'<li class="l_reply_num.*?<span.*?<span class="red">(.*?)</span>',re.S) #5.2查詢對應正則的資料 html = response.read() rs = re.search(pattern,html) #5.3把字串頁數轉換為數字 total = int(rs.group(1)) # 5.4 正則匹配標題 tit_pattern = re.compile(r'<h\d class="core_title_txt.*?>(.*?)</h\d>',re.S) #5.5從原始碼中搜索標題 rs = re.search(tit_pattern,html) print rs.group(1) title = rs.group(1) #拼接檔名 #decode()解碼,網頁中的字元是utf-8編碼,在python中使用的字串都是Unicode編碼,所以需要轉換 filename = "%s.txt"%title.decode('utf-8') #開啟檔案 file = open(filename,'w') print '正在爬取%s,共%s頁資料'%(title,total) #6.for迴圈執行總頁數次 for x in range(1,total+1): print '正在爬取第%s頁資料'%x # 6.1根據頁碼拼接完整的URL地址 getUrl = url+'?pn=%s'%x # 6.2建立request物件,發起請求,接受響應 request = urllib2.Request(getUrl,headers=headers) response = urllib2.urlopen(request) html = response.read() # 6.3根據正則匹配資料,包含使用者名稱和帖子內容 con_pattern = re.compile(r'<ul class="p_author.*?<li class="d_name.*?<a.*?>(.*?)</a>.*?<div id="post_content_.*?>(.*?)</div>',re.S) rs = re.findall(con_pattern,html) # 6.4去除、替換資料中的html標籤 #1.使用者名稱中的img標籤 #2.去除帖子內容中的img標籤 #3.去掉帖子內容部分的空格 #4.替換帖子中的內容部分 for r in rs: remove_img = re.compile(r'<img.*?>',re.S) remove_k = re.compile(r' {10}',re.S) replace_br = re.compile(r'<br>|<br/>',re.S) remove_ele = re.compile(r'<.*?>',re.S) #1 去除name中的img name = re.sub(remove_img,'',r[0]) #2 去除內容中的img content = re.sub(remove_img,'',r[1]) # 3 去除內容中的空格 content = re.sub(remove_k,'',content) # 4 替換內容的br content = re.sub(replace_br,r'\n',content) # 5 去除所有標html籤 content = re.sub(remove_ele,'',content) # 6.5寫入本地檔案 file.write('---------------------------------------------------------') file.write('\n') file.write(name) file.write('\n') file.write(content) file.close() print '資料爬取完成!' **************************************************************************************** #執行程式,能夠爬取成功,再進一步升級,用類和物件的方法來寫,作進一步的嘗試,先通過輸入編號,爬取一個帖子的內容
**************************************************************************************** #coding:utf-8 import urllib2 import re #工具類 class Tools(object): #1.正則 remove_img = re.compile(r'<img.*?>',re.S) remove_k = re.compile(r' {10}') replace_br = re.compile(r'<br>|<br/>') remove_ele = re.compile(r'<.*?>',re.S) #替換文字的函式 def replace_txt(self,rs): name = re.sub(self.remove_img,'',rs[0]) content = re.sub(self.remove_img,'',rs[1]) content = re.sub(self.remove_k,'',content) content = re.sub(self.replace_br,r'\n',content) content = re.sub(self.remove_ele,r'',content) #返回替換完成的元組 return (name,content) #百度貼吧爬蟲類 class BDTB(object): def __init__(self,numbers): #根據帖子編號拼接url地址 self.url = 'https://tieba.baidu.com/p/'+numbers self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0' } #初始化工具類物件 self.tool = Tools() #獲取某一頁的html原始碼 def get_page(self,pageNum): #根據頁碼拼接完整的url地址 getUrl = self.url+"?"+"pn=%s"%pageNum #建立request物件 request = urllib2.Request(getUrl,headers=self.headers) try: #發起請求接收響應 response = urllib2.urlopen(request) except(urllib2.HTTPError,Exception),e: print '獲取第%s頁資料失敗,原因%s'%(pageNum,e) return None else: #如果沒有異常,返回html原始碼 return response.read() #從第一頁中提取總頁數和標題 def get_title_total(self,html): #1.準備正則 tit_pattern = re.compile(r'<h\d class="core_title_txt.*?>(.*?)</h\d>',re.S) # 2.查詢 tit_rs = re.search(tit_pattern,html) # 3 .記錄標題 self.title = tit_rs.group(1) #1 查詢總頁數正則 total_pattern = re.compile(r'<li class="l_reply_num.*?<span.*?<span class="red">(.*?)</span>',re.S) # 2 查詢 total_rs = re.search(total_pattern,html) # 3 記錄總頁數 self.total = int(total_rs.group(1)) #從html原始碼中提取資料 def get_data(self,html): # 1 準備正則 pattern = re.compile(r'<ul class="p_author.*?<li class="d_name.*?<a.*?>(.*?)</a>.*?<div id="post_content_.*?>(.*?)</div>',re.S) # 2 查詢 results = re.findall(pattern,html) ok_results = [] for rs in results: #替換資料中的html標籤 ok_rs = self.tool.replace_txt(rs) ok_results.append(ok_rs) #返回替換完成後的結果列表 return ok_results # 寫入本地檔案 def write_data(self,results): for rs in results: self.file.write('------------------------------------') self.file.write(rs[0]) self.file.write('\n') self.file.write(rs[1]) self.file.write('\n') #開始爬蟲函式 def start(self): #1.獲取第一頁的HTML原始碼 html = self.get_page(1) if html == None: print '連線百度失敗,請稍後重試、、、、、' return #2.從第一頁原始碼中獲取總頁數和標題 self.get_title_total(html) print '正在爬取帖子:%s,共%s頁資料。。。'%(self.title,self.total) #3.開啟檔案,用屬性記錄這個檔案物件,方便後面使用 filename = '%s.txt'%self.title.decode('utf-8') self.file = open(filename,'w') #for迴圈 迴圈總頁數次 for x in range(1,self.total+1): print '正在爬取第%s頁:'%x #1 根據頁碼獲取該頁的HTML原始碼 html = self.get_page(x) if html == None: continue #2 從html原始碼中提取資料 results = self.get_data(html) #3 寫入本地檔案 self.write_data(results) #3 .關閉檔案 self.file.close() if __name__ =='__main__': numbers = raw_input('請輸入要爬取的帖子編號:') bdtb = BDTB(numbers) bdtb.start() ***************************************************************************************** #再進一步升級爬取所有精品貼內容
***************************************************************************************** #coding:utf-8 import urllib2 import re from tieba_class import BDTB import time #爬取精品貼頁面所有的帖子編碼 class JPT(object): def __init__(self): self.url = 'https://tieba.baidu.com/f/good?kw=nba&tab=good' self.headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50' } #獲取精品貼的HTMl原始碼 def get_page(self): # 建立物件發起請求 request = urllib2.Request(self.url, headers=self.headers) try: response = urllib2.urlopen(request) except(urllib2.URLError, Exception), e: print '獲取精品貼失敗,%s' % e else: return response.read() def get_data(self,html): #1.準備正則 pattern = re.compile(r'<div class="threadlist_title.*?href="/p/(.*?)"',re.S) results = re.findall(pattern,html) return results def start(self): #1.獲取精品貼的HTML原始碼 html = self.get_page() #2.從精品貼原始碼中提取帖子編號 results = self.get_data(html) #for 迴圈遍歷帖子編號,爬取內容 #建立BDTB物件,傳入帖子編號 for numbers in results: bdtb = BDTB(numbers) bdtb.start() time.sleep(2) if __name__ == '__main__': jpt = JPT() jpt.start()