1. 程式人生 > >python爬蟲爬取NBA貼吧的所有精品貼

python爬蟲爬取NBA貼吧的所有精品貼

首先用直接的方法寫,先嚐試下能否爬取成功
#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()