- 哈羅啊滋饲,又見面了,這幾天考試+各種事情喊巍,耽誤了點時間屠缭,不夠我終于又做了個案例
- 還是看著知乎大神的帖子Wakingup的帖子
- 話不多說,上代碼
'''
根據(jù)知乎大神
代碼作者:高佳樂
'''
##先導(dǎo)入各種庫
import re ##re正則表達式
import requests ##獲取url
from bs4 import BeautifulSoup ##bs4解析
import time ##爬蟲嘛崭参,要有禮貌
import random ##開始我想用隨機數(shù)轉(zhuǎn)換head來著呵曹,試了試沒事
import os ##弄文件及,一頁一個文件夾
from lxml import etree ##xpath的庫
##定義一個類,爬蟲
class spider():
##初始化
def __init__(self): ##初始化函數(shù)
self.url = 'http://tieba.baidu.com' ##使他的初始化函數(shù)是貼吧首頁
return
##獲取貼吧的url
def getUrl(self,url): ##獲取url的函數(shù)(參數(shù)是一個url阵翎,網(wǎng)址)
html = requests.get(url) ##html是requests.get獲取到的源碼
html_text = html.text ##html_text是上邊獲取到代碼后然后書寫進來
return html_text ##這個函數(shù)返回html_text以便賦值
##獲取帖子的標(biāo)題
def title(self,url):
html = self.getUrl(url) ##html是用getUrl獲取到的代碼
soup = BeautifulSoup(html,'lxml') ##soup是用BeautiflSoup解析的結(jié)構(gòu)樹逢并,用的是lxml
title = soup.find(class_="core_title_txt")##然后獲取class=“core_title_text”的節(jié)點
#print('這個貼吧的標(biāo)題是:',title.get_text()) ##這個已經(jīng)注釋了之剧,解釋也沒用了
return title.get_text() ##返回的是上邊獲到標(biāo)題節(jié)點的內(nèi)容
##獲取帖子的總頁數(shù)
def pages(self,url): ##這個函數(shù)是獲取總頁數(shù)
html = self.getUrl(url) ##html是用getUrl獲取到的代碼
soup = etree.HTML(html) ##然后soup是用etree.HTML把上邊獲得的代碼解析郭卫,以便使用xpath
pages = soup.xpath('.//div[@id="thread_theme_5"]//li[@class="l_reply_num"]/span[last()]')##因為用正則有點麻煩我感覺,用bs4我也覺得有點煩背稼,就用了xpath贰军,xpath剛開始用,原諒我太菜
for page in pages: ##上邊的xpath是在此節(jié)點中不管那個位置的id=“thread_theme_5的div里不管在哪的class=“l(fā)_reply_num”的li的最后一個span
break; ##因為獲得的是列表蟹肘,所以要遍歷词疼,因為我只獲取一個值,所以我在這個循環(huán)里循環(huán)后直接結(jié)束
return page.text ##因為上邊返回的是一個那樣的帘腹,所以返回值帶上text返回文本
##獲取樓主和內(nèi)容
def content(self,url): ##獲取樓主的內(nèi)容贰盗,參數(shù)是url
html = self.getUrl(url) ##html是用getUrl獲取到的代碼
##我用的正則,有點麻煩阳欲,用在我這個帖子里好使舵盈,別的沒準(zhǔn)就報錯了陋率,推薦用xpath或者Bs4
zhengze = re.compile('<li.*?_author_name.*?_blank.*?(.*?)</a>.*?d_post_content.*?save_face_bg_hidden.*?d_post_content j_d_post_content.*?>(.*?)</div>',re.S)
contents = re.findall(zhengze,html) ##上邊是定義一個正則,這里就是使用在html篩選上邊條件的全部節(jié)點秽晚,返回列表
number = 1 ##計數(shù)器瓦糟,這是個記住器,以便記住第幾樓
for i in contents:
print('第%d個帖子\n樓主:%s\n內(nèi)容:%s\n'%(number,i[0],i[1]))
print()
number+=1
##獲取圖片
def img(self,url): ##獲取圖片的函數(shù)
html = self.getUrl(url) ##html也是用getUrl獲取的代碼
soup = BeautifulSoup(html,'lxml') ##soup是用BS4解析的代碼赴蝇,用的lxml
images = soup.select('img[class="BDE_Image"]')##然后用select查到符合‘class=“BDE_Image”’的img標(biāo)簽菩浙,返回列表
number = 0 ##這是個計數(shù)器,
imgs = [] ##這里創(chuàng)建一個空列表以便吧圖片地址存到這里句伶,你會問上邊不是有了嗎劲蜻,其實上邊是有列表,但是上邊的是節(jié)點的列表就是還設(shè)有別的屬性熄阻,咱們只要scr屬性的
for i in images: ##這是一個計一頁有多少圖片的方法斋竞,當(dāng)然這是最屌絲的方法
number+=1 ##讀取一個節(jié)點,number+1
if number > 0: ##計數(shù)下來秃殉,number>0的話
print('厲害坝初,厲害,這里有%s個圖片钾军,爬完就跑鳄袍,刺激'%number)##輸出這點話
else: ##反之就是<=0 就說這話
print('這里沒有圖片,快跑')
number = 1 ##這里number在=1吏恭,以便計數(shù)
for image in images: ##用image在images讀取拗小,也就是在上邊爬到的圖片節(jié)點中讀取
img = image.get('src') ##這里get(src)就是,img只獲得這個節(jié)點的src屬性樱哼,就是純url了
print('正在爬取哀九,第%d圖片:'%number,img)##輸出上邊獲取圖片的url
imgs.append(img) ##然后把上邊的純連接img追加到開始創(chuàng)建的那個空列表里,這不就會成為一個純連接的列表了
number+=1 ##number+1 以便計數(shù)
return imgs ##返回那個純連接的列表
##創(chuàng)建文件夾搅幅,和圖片
def make(self,name): ##創(chuàng)建文件夾的函數(shù)
dir = os.getcwd()+'\第'+str(name)+'文件夾' ##先定義文件的名字阅束,就是os.getcwd獲取當(dāng)前工作路徑,+文件夾的名
# 去除首位空格
dir = dir.strip()
# 去除尾部 \ 符號
dir = dir.rstrip('\\')
##判斷目錄是否存在
panduan = os.path.exists(dir) ##exists判斷目錄是否存在茄唐,是=true息裸,否=False
if panduan: ##如果有就已存在
print(dir,'已存在')
else: ##反之,也就是假沪编,沒有
os.makedirs(dir) ##就創(chuàng)建這個文件夾呼盆,當(dāng)然我這的路徑是絕對路徑
print(dir,'已創(chuàng)建成功')
return dir ##返回那個文件夾的路徑,以便下邊的切換路徑
##保存圖片
def saveimage(self,url): ##保存圖片了
images = self.img(url) ##images是用img獲取到的純連接的那個列表
num = 1 ##num=1計數(shù)器
for img in images: ##用循環(huán)讓img在那個返回的純連接的列表里讀取
fil = str(num) + '.jpg' ##然后定義圖片名字.jpg
html = requests.get(img).content ##因為直接一個地址是寫不到圖片里邊去的蚁廓,要寫入二進制访圃,所以要先獲取那個圖片的內(nèi)容,然后.content轉(zhuǎn)化成二進制
f = open(fil,'wb') ##然后打開fil的文件可寫可讀相嵌,沒有就是創(chuàng)建
f.write(html) ##然后寫入圖片的二進制
f.close() ##然后關(guān)閉腿时,隨手關(guān)閉是個好孩子
num+=1 ##當(dāng)然計數(shù)器要+1
print('第%s保存成功'%fil) ##提示圖片保存成功更有逼格
##操控克胳,一個貼吧的操控
def all(self,number): ##這個函數(shù)就是把所有的方法封裝到這里
##貼吧地址是self.url+帖子號
url = self.url+'/p/'+str(number) ##因為地址也是首頁+帖子號,這個也是第一頁
##獲取標(biāo)題
title = self.title(url) ##有title方法獲取標(biāo)題
print('這個帖子的標(biāo)題是%s'%title)
##獲取總頁數(shù)
page = int(self.pages(url)) ##用pages獲取帖子總頁數(shù)圈匆,并轉(zhuǎn)換成整數(shù)型漠另,以便下邊的+1
##根據(jù)總頁數(shù)獲取全部的頁數(shù),并獲取圖片
num = 1 ##num這里就是計數(shù)跃赚,頁數(shù)了
print('第1頁') ##這里是第一頁
##獲取內(nèi)容
self.content(url) ##第一頁是不加pn的所以要單獨分開來獲取笆搓,url是上邊弄得首頁+帖子號,這里是獲取內(nèi)容和樓主
self.img(url) ##這里是獲取圖片的詳細資料
dir = self.make(num) ##這里是創(chuàng)建文件夾纬傲,因為一頁保存一個文件夾满败,所以這是第一個
os.chdir(dir) ##上邊創(chuàng)建好文件夾后,轉(zhuǎn)換到文件夾下
self.saveimage(url) ##然后保存叹括,然后就跑
num+=1 ##第一頁保存了算墨,當(dāng)然是第二頁了,后邊的頁數(shù)也不一樣了汁雷,
for i in range(num,page+1): ##之前獲取到的總頁數(shù)在這里净嘀,因為要獲取全部,第一頁之前已經(jīng)獲取了侠讯,這里既是從第2頁開始到總頁數(shù)+1后停止挖藏,為什么+1?因為for取首不娶尾
url_2 = url + '?pn=' + str(i) ##這里是給每頁的url獲取厢漩,因為第二頁后每頁都是首頁+帖子號+膜眠?pn=頁數(shù)了
print('第%d頁'%i) ##計數(shù)第幾頁
time.sleep(1) ##爬蟲要禮貌,禮貌溜嗜,所以要sleep宵膨,1.。其實我打算想著0.1炸宵,但是為了世界和平所以要大點了辟躏,→_→
self.content(url_2) ##獲取第i頁這內(nèi)容
self.img(url_2) ##獲取第i頁圖片詳情
dir = self.make(i) ##然后創(chuàng)建第i個文件夾,根據(jù)i的數(shù)創(chuàng)建
os.chdir(dir) ##然后切換到新創(chuàng)建的第i個文件夾里
time.sleep(1) ##然后講一下禮貌
self.saveimage(url_2) ##然后保存第i頁的圖片
time.sleep(1) ##再講一下禮貌
img = spider()
img.all(int(input('輸入帖子號')))
(這段是一個內(nèi)心的小活動焙压,可以省略看下邊)
學(xué)校換老師開始前端實例了┓( ′-` )┏鸿脓,偷偷告訴你們我其實學(xué)的專業(yè)是ui設(shè)計抑钟,不會代碼的ui不是一個好美工( ̄ー ̄)涯曲,所以我決定好好學(xué)前端了,據(jù)說這樣可以避免以后工作上和程序員的矛盾在塔,嘛哈哈哈幻件。當(dāng)然爬蟲我也要抓住,好不容易有這樣的機會蛔溃。這里绰沥,這次是把貼吧篱蝇,旅游吧里的一個帖子爬圖片和內(nèi)容,足不出戶徽曲,就可以看美景零截,還出去什么旅游,還不如在宿舍乖乖敲代碼秃臣。emm對了我那個抓取樓主和內(nèi)容的時候用的正則涧衙,可能我這好使別的就不好使了,沒時間改xpath了(其實不也不知道能不能改)奥此,見諒弧哎。
好了到了這就要再見了,砸門下次再見稚虎。堅持撤嫩,加油,努力蠢终。