玩轉(zhuǎn)貼吧

小白爬完文字爬圖片,目標(biāo)百度貼吧。
其實是偶然的機(jī)會發(fā)現(xiàn)了這個:

旅行吧

當(dāng)時就想,為什么創(chuàng)建這個“旅行吧”呀,從事物發(fā)展的規(guī)律來說,就是方便大伙兒各種曬圖各種秀啊!能拿來曬的東西,敢情應(yīng)該不會差到哪去(至少比一般的百度圖片要好一些吧)

好了不多胡扯回歸正題,幾行代碼,帶足不出戶的你,走遍萬水千山!
先隨便搜了個貼,好吧就是這個了


目標(biāo)帖子

一、目標(biāo):

1、獲取帖子標(biāo)題、總頁數(shù)、評論、圖片
2、圖片寫入文件并保存
3、將各種信息實現(xiàn)打印(測試追蹤)
4、輸入帖子號便能實現(xiàn)以上操作(亦適用于其它帖子)

二、步驟:

1、獲取源碼。這個簡單,用requests的get請求方式即可。這里設(shè)置了random.randint()獲取隨機(jī)數(shù),在一堆范圍中獲取user_agent,主要是為了偽裝防止網(wǎng)站認(rèn)出是爬蟲而限制抓取。至于這一堆user_agents,額,網(wǎng)上搜的哈哈~
'''
#usr/bin/env python
# -- coding: utf-8 --
def getSource(self,url):
user_agents=['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0','Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ (KHTML, like Gecko) Element Browser 5.0','IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)','Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)','Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14','Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \Version/6.0 Mobile/10A5355d Safari/8536.25','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \Chrome/28.0.1468.0 Safari/537.36','Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)'
index=random.randint(0,9)
user_agent=user_agents[index]
headers = {'User_agent': user_agent}
html=requests.get(url,headers=headers)
return html.text
'''

2、獲取標(biāo)題、總頁數(shù)、評論
主要是匹配正則
標(biāo)題的正則
'''

pattern=re.compile('<h1.*?title.*?>(.*?)</h1>',re.S)
items=re.search(pattern,result) 

'''
頁數(shù)的正則
'''

pattern=re.compile('<h1.*?title.*?>(.*?)</h1>',re.S)
items=re.search(pattern,result)   

'''
評論的正則
'''

pattern=re.compile('<h1.*?title.*?>(.*?)</h1>',re.S)
items=re.search(pattern,result)

'''

3、獲取曬圖
用到BeautifulSoup,首先想到find_all()搜'img'標(biāo)簽,得到如下

圖1.png

龍蛇混雜呀,不僅包括各種旅行曬圖,還有鏈接中包含'head'的頭像圖,含'emoticon'的表情圖等等,寶寶內(nèi)心是崩潰噠。
如何洗出我們想要的內(nèi)容呢?
別著急,仔細(xì)觀察這些個鏈接,逐個點開一試就會發(fā)現(xiàn),凡是屬于'曬圖'的,接帶有屬性class='BDE_Image'。
我的天,直接find_all()限定范圍,再循環(huán)打出item['src'],分分鐘搞定鏈接!要有多簡單就有簡單,最后將鏈接保存至一個list中。

圖2.png

4、創(chuàng)建目錄
用到makedirs(),值得注意的是,如果想將文件夾創(chuàng)建至非系統(tǒng)默認(rèn)的地方,需要用到chdir()來更改環(huán)境變量。

5、保存曬圖
萬水千山走遍,目錄也創(chuàng)建,接下來就是保存圖片。又用到文件操作相關(guān)知識,千萬注意,要想將圖片成功保存至上面創(chuàng)建的目錄,必需指定絕對路徑,所以設(shè)置self.path是為了方便此處調(diào)用。

6、集合各操作并獲取多頁
兩個循環(huán),一個是多頁,一個是多個圖片的保存。關(guān)鍵在格式化每一頁索引鏈接。
觀察可發(fā)現(xiàn)規(guī)律,網(wǎng)頁URL格式為:'http://tieba.baidu.com/p'+帖子號+'?pn='+頁數(shù),所以可以設(shè)置如下:
'''

self.siteURL = 'http://tieba.baidu.com/p/' + str(Num)
self.url=self.siteURL+'?pn='+str(page)

'''

三、代碼

以上就是基本的思路,接下來分享代碼,如有錯誤還望指正
'''
#usr/bin/env python
# -- coding: utf-8 --
author='WYY'
date='2017.03.14'

#實戰(zhàn)小項目:百度貼吧爬蟲
import urllib2
import requests
import re
import os
import time
import random
from bs4 import BeautifulSoup

#定義一個Tool()類方便清洗數(shù)據(jù)
class Tool():
    removeImg = re.compile('<img.*?>|{7}| ') # 去除img標(biāo)簽,1-7位空格, 
    removeAddr = re.compile('<a.*?>|</a>') # 刪除超鏈接標(biāo)簽
    replaceLine = re.compile('<tr>|<div>|</div>|</p>') # 把換行的標(biāo)簽換位\n
    replaceTD = re.compile('<td>') # 把表格制表<td>換為\t
    replaceBR = re.compile('<br><br>|<br>|</br>|</br></br>') # 把換行符或者雙換行符換為\n
    removeExtraTag = re.compile('.*?') # 把其余標(biāo)簽剔除
    removeNoneLine = re.compile('\n+') # 把多余空行刪除
    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.replaceBR, "\n", x)
        x = re.sub(self.removeExtraTag, "", x)
        x = re.sub(self.removeNoneLine, "\n", x)
        return x.strip() # 把strip()前后多余內(nèi)容刪除

#定義一個Spider類
class Spider():
    #初始化參數(shù)
    def __init__(self):
        self.tool = Tool()

    #獲取源碼
    def getSource(self,url):
        user_agents=['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0','Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \(KHTML, like Gecko) Element Browser 5.0','IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)','Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)','Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14','Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \Version/6.0 Mobile/10A5355d Safari/8536.25','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \Chrome/28.0.1468.0 Safari/537.36','Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']
        # user_agent在一堆范圍中隨機(jī)獲取
        # random.randint()獲取隨機(jī)數(shù),防止網(wǎng)站認(rèn)出是爬蟲而訪問受限
        index=random.randint(0,9)
        user_agent=user_agents[index]
        headers = {'User_agent': user_agent}
        html=requests.get(url,headers=headers)
        return html.text

    #獲取帖子標(biāo)題
    def getTitle(self,url):
        result=self.getSource(url)
        pattern=re.compile('<h1.*?title.*?>(.*?)</h1>',re.S)
        items=re.search(pattern,result)
        print u'這篇帖子標(biāo)題為:',self.tool.replace(items.group(1))

    #獲取帖子總頁數(shù)
    def getPageNumber(self,url):
        result=self.getSource(url)
        pattern=re.compile('<ul.*?l_posts_num.*?<span class="red">(.*?)</span>',re.S)
        items=re.search(pattern,result).group(1)
        print u'帖子共有',items,u'頁'
        return items

    #獲取評論內(nèi)容
    def getContent(self,url):
        result = self.getSource(url)
        pattern=re.compile('<a data-field.*?p_author_name.*?">(.*?)</a>.*?<div id="post_content_.*?>(.*?)</div>',re.S)
        items=re.findall(pattern,result)
        #獲取樓層數(shù)可以直接用循環(huán),省去正則匹配的麻煩
        number = 1
        for item in items:
            #item[0]為樓主,item[1]為發(fā)言內(nèi)容,使用\n換行符打出內(nèi)容更干凈利落
            #item[1]中可能有img鏈接,用自定義Tool工具清洗
            print u'\n', number, u'樓', u'\n樓主:', item[0], u'\n內(nèi)容:', self.tool.replace(item[1])
            time.sleep(0.01)
            number += 1

    #獲取曬圖,清洗獲得鏈接并保存入list
    def getImage(self,url):
        result=self.getSource(url)
        soup=BeautifulSoup(result,'lxml')
        #此處用BeautifulSoup顯然更高效
        #find_all()返回一個list,find()返回一個元素
        #注意class屬性和python內(nèi)置的重合,所以加_變成class_
        items=soup.find_all('img',class_="BDE_Image")
        images=[]
        number=0
        for item in items:
            print u'發(fā)現(xiàn)一張圖,鏈接為:',item['src']
            images.append(item['src'])
            number+=1
        if number>=1:
            print u'\n',u'共曬圖',number,u'張,厲害了我的哥?。?!'
        else:
            print u'喏,沒有圖......'
        return images

    #創(chuàng)建目錄
    def makeDir(self,path):
        self.path=path.strip()
        E=os.path.exists(os.path.join('F:\Desktop\code\LvXing', self.path))
        if not E:
            #創(chuàng)建新目錄,若想將內(nèi)容保存至別的路徑(非系統(tǒng)默認(rèn)),需要更環(huán)境變量
            #更改環(huán)境變量用os.chdir()
            os.makedirs(os.path.join('F:\Desktop\code\LvXing', self.path))
            os.chdir(os.path.join('F:\Desktop\code\LvXing', self.path))
            print u'正在創(chuàng)建名為',self.path,u'的文件夾'
            return self.path
        else:
            print u'名為',self.path,u'的文件夾已經(jīng)存在...'
            return False

    #萬水千山走遍,接下來就是保存美圖
    def saveImage(self,detailURL,name):
        data=urllib2.urlopen(detailURL).read()
        fileName=name+'.'+'jpg'
        #保存文件,一定要用絕對路徑      `
        #所以設(shè)置self.path,是為了方便后面函數(shù)無障礙調(diào)用
        f=open(r'F:\Desktop\code\LvXing\%s\%s'%(self.path,fileName),'wb')
        f.write(data)
        f.close()
        print u'成功保存圖片',fileName


    #集合所有的操作,并獲取多頁
    def getAllPage(self,Num):
        self.siteURL = 'http://tieba.baidu.com/p/' + str(Num)
        #獲取帖子標(biāo)題
        self.getTitle(self.siteURL)
        #獲取帖子頁數(shù)
        numbers=self.getPageNumber(self.siteURL)
        for page in range(1,int(numbers)+1):
            #格式化索引鏈接
            self.url=self.siteURL+'?pn='+str(page)
            print u'\n\n',u'正準(zhǔn)備獲取第',page,u'頁的內(nèi)容...'
            #獲取評論
            print u'\n',u'正準(zhǔn)備獲取評論...'
            self.getContent(self.url)
            #每一頁創(chuàng)建一個文件
            self.makeDir(path='page'+str(page))
            #獲取圖片
            print u'\n',u'正準(zhǔn)備獲取圖片...'
            images=self.getImage(self.url)
            print u'\n',u'正準(zhǔn)備保存圖片...'
            number=1
            #保存圖片,先從之前的list中找鏈接
            for detailURL in images:
                name='page'+str(page)+'num'+str(number)
                self.saveImage(detailURL,name)
                time.sleep(0.1)
                number+=1

            print u'\n\n',u'完成第',page,u'頁'

        print u'\n\n',u'恭喜,圓滿成功!'

#raw_input()實現(xiàn)和外部交互,想看哪個貼就看哪個貼
Num=int(raw_input('老哥兒/老妹兒,輸入帖子號唄:'))
spider=Spider()
spider.getAllPage(Num)

'''

四、結(jié)果

終于寫完代碼啦,各種參數(shù)要注意處理好。
然后可以看到如下結(jié)果:

圖3.png
圖4.png
圖5.png

看看文件的變化,圖片已經(jīng)乖乖躺在文件夾中啦


圖6.png
圖7.png

五、擴(kuò)展

爬完上面這個貼,又去胡亂搜尋,發(fā)現(xiàn)兩有趣的貼。
喜愛攝影的盆友看過來啦~
一個是:國外朋友的世界一周旅行記1,Uca姐的攝影好美(獻(xiàn)給所有愛旅者)
另一個:背起畫夾去旅行——且行且繪(陸續(xù)更新)

1)、前面這一個介紹了一個日本旅行攝影師的世界一周旅行記的故事,照片色彩明麗、利落干凈,迎面滿是異域風(fēng)情。
舉例幾個圖:


旅行1.png

旅行2.png

一共100頁,一頁也就四五十張圖。。。不過攝影師的圖還是相當(dāng)?shù)馁澃?/p>

圖8.png

2)另一個帖子更是好玩,樓主非常有才,把沿途所見所聞都一一畫下,畫風(fēng)那叫一個清新雅致,不得不獻(xiàn)上膝蓋。
放幾個圖感受一下:


旅行3.png

旅行4.png

旅行5.png

其實還有很多這樣的帖子,隨便輸入帖子號便玩轉(zhuǎn)貼吧,幾行代碼走遍萬水千山,就是這樣啦~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,781評論 25 709
  • 視窗1985閱讀 238評論 0 0
  • 一定有人會說,我的天啦,你才用簡書。你好無知啦! 相信也一定有人會說,簡書有什么好玩的?還不如我看看微博呢! 有人...
    玉兒哥閱讀 215評論 0 0
  • 斷橋衫冷寒霜跡 孤山襟短椅云齊 殘月蕩空情未滅 玉壺傾盡神已迷 恍聞飛鳳舞青影 又見驚鴻逐彩霓 偏有漏長嘆永夜 覺...
    隱天痕閱讀 268評論 0 0

友情鏈接更多精彩內(nèi)容