Python:批量下載百度貼吧原圖(超詳細)


1. 背景

??百度貼吧上有許多美圖头滔,幾張或十幾張圖片手動下載還可以鲤氢,但幾十張狠持,上百張就比較麻煩恳啥,故希望編個程序批量下載百度貼吧的原圖。由于python爬蟲代碼簡單某残,故利用python來編程窘茁。

孫允珠吧

2. 準備

2.1 貼吧組成

??現(xiàn)在使用孫允珠吧舉例妈嘹。一個貼吧由一個個帖子組成背犯,帖子中包含圖片坏瘩。故理論上下載原圖的一般方法是:先打開貼吧主頁,再打開帖子漠魏,然后點擊圖片使其原圖顯示倔矾,最后下載圖片。

孫允珠吧主頁
孫允珠吧帖子
孫允珠吧帖子中圖片原圖顯示

2.2 分析網(wǎng)頁url

貼吧主頁:http://tieba.baidu.com/f?kw=%CB%EF%D4%CA%D6%E9&fr=ala0&loc=rec
貼吧帖子:http://tieba.baidu.com/p/6383722178
原圖顯示:http://tieba.baidu.com/photo/p?kw=%E5%AD%99%E5%85%81%E7%8F%A0&ie=utf-8&flux=1&tid=6383722178&pic_id=4254484e251f95ca67a500d0c6177f3e660952e7&pn=1&fp=2&see_lz=1
分析結(jié)果:
1. 貼吧主頁中 “kw=%CB%EF%D4%CA%D6%E9” 是gb2312格式的UrlEncode編碼柱锹,“kw=%E5%AD%99%E5%85%81%E7%8F%A0” 是utf-8格式的UrlEncode編碼哪自,它們解碼結(jié)果是:孫允珠。
解碼網(wǎng)站:站長工具UrlEncode編碼/解碼

UrlEncode解碼前
UrlEncode解碼后

2. 貼吧帖子中 “6383722178” 是帖子編號禁熏。
3. 原圖顯示中 “pic_id=4254484e251f95ca67a500d0c6177f3e660952e7” 是圖片編號提陶。
4. 由原圖顯示的url可知,打開1張原圖需要 “kw=%E5%AD%99%E5%85%81%E7%8F%A0” 匹层、“tid=6383722178” 和 “pic_id=4254484e251f95ca67a500d0c6177f3e660952e7”

2.3 分析關(guān)鍵信息

  1. 打開貼吧主頁。點擊右上角設(shè)置圖標->更多工具->開發(fā)者工具(谷歌瀏覽器)锌蓄,或網(wǎng)頁鼠標右鍵點擊->檢查即可看到源碼升筏。
谷歌瀏覽器打開源碼方式
  1. Ctrl+F查找帖子編號 “6383722178” ,找到關(guān)鍵代碼瘸爽,提取出正則表達式您访。若提取內(nèi)容不同,所需的正則表達式需要自己修改剪决,不懂可以參考Python3 正則表達式灵汪。
    注意:瀏覽器上看到的關(guān)鍵代碼和程序獲取的關(guān)鍵代碼是不同的。
瀏覽器上帖子關(guān)鍵代碼

程序獲取的關(guān)鍵代碼:

<li class=" j_thread_list clearfix" data-field='{&quot;id&quot;:6383722178,&quot;author_name&quot;:&quot;lovedovelyonly&quot;,&quot;author_nickname&quot;:null,&quot;author_portrait&quot;:&quot;tb.1.d0fa6477.jIFXO-fqudlDDQVl2lym9g&quot;,&quot;first_post_id&quot;:128733834249,&quot;reply_num&quot;:26,&quot;is_bakan&quot;:null,&quot;vid&quot;:&quot;&quot;,&quot;is_good&quot;:true,&quot;is_top&quot;:null,&quot;is_protal&quot;:null,&quot;is_membertop&quot;:null,&quot;is_multi_forum&quot;:null,&quot;frs_tpoint&quot;:null}'  data-tid='6383722178' data-thread-type="0" data-floor='6''>

程序所需的正則表達式:

r1 = r"data-tid='([0-9]+)' data-thread-type"  # 正則表達式
  1. 同樣打開貼吧首頁的1個帖子柑潦,Ctrl+F查找圖片編號 “4254484e251f95ca67a500d0c6177f3e660952e7”享言,獲取關(guān)鍵代碼,提取出正則表達式渗鬼。
瀏覽器上帖子關(guān)鍵代碼

程序獲取的關(guān)鍵代碼:

<img class="BDE_Image" pic_type="0" width="560" height="560" src="http://imgsrc.baidu.com/forum/w%3D580/sign=61a7dc9d0546f21fc9345e5bc6256b31/4254484e251f95ca67a500d0c6177f3e660952e7.jpg" size="555815" >

程序所需的正則表達式:

r2 = r'src="http://imgsrc.baidu.com/(.*?)\.jpg"'  # 正則表達式
  1. 打開原圖顯示url的源碼览露,找出可下載原圖的地址。
原圖顯示的源碼

可下載原圖的地址:

http://imgsrc.baidu.com/forum/pic/item/4254484e251f95ca67a500d0c6177f3e660952e7.jpg

三譬胎、處理流程

??從上面的下載地址可知差牛,下載原圖需要知道 “4254484e251f95ca67a500d0c6177f3e660952e7” 即圖片編號命锄。故批量下載圖片時,只需給定貼吧首頁的url偏化,由首頁url的源碼找出帖子編號脐恩,再由帖子編號讀取帖子源碼,從而獲取圖片編號侦讨。最后由圖片編號組成原圖下載地址驶冒,通過其下載圖片。

流程圖

四搭伤、源代碼

from urllib import request  # 下載圖片
import re  # 正則表達式
import os  # 創(chuàng)建文件夾
from tqdm import trange  # 進度條

# 讀取主頁源碼
url1 = "http://tieba.baidu.com/f?kw=%CB%EF%D4%CA%D6%E9&fr=ala0&loc=rec"  # 貼吧首頁的網(wǎng)址
html = request.urlopen(url1, timeout=5)  # 讀取網(wǎng)頁源碼
code = html.read().decode("UTF_8")
"""
file = open("1.html", "w", encoding='UTF-8')  # 保存源碼
file.write(str(code))
file.close
print(code)
"""

# 提取帖子編號
r1 = r"data-tid='([0-9]+)' data-thread-type"  # 正則表達式
c1 = re.compile(r1)  # 根據(jù)正則表達式創(chuàng)建模式對象
f1 = re.findall(c1, code)  # 匹配結(jié)果
# 提取帖子名稱
r2 = r'href="/p/[0-9]+" title="(.*?)"'  # 正則表達式
c2 = re.compile(r2)  # 根據(jù)正則表達式創(chuàng)建模式對象
title = re.findall(c2, code)  # 匹配結(jié)果
i = 0
# 創(chuàng)建Image文件夾
if not os.path.exists("Image"):
    os.mkdir("Image")

for tid in f1:
    i = i + 1
    # 讀取帖子源碼
    url3 = 'http://tieba.baidu.com/p/' + tid  # 帖子地址 'http://tieba.baidu.com/p/6383722178'
    html3 = request.urlopen(url3, timeout=5)  # 讀取網(wǎng)頁源碼
    code3 = html3.read().decode("UTF_8")
    # 提取圖片編號
    r3 = r'src="http://imgsrc.baidu.com/(.*?)\.jpg"'  # 正則表達式
    c3 = re.compile(r3)  # 根據(jù)正則表達式創(chuàng)建模式對象
    f3 = re.findall(c3, code3)  # 匹配結(jié)果
    # 以該帖子的名稱創(chuàng)建文件夾
    dir1 = "Image//" + title[i] + "(共" + str(len(f3)) + "張)//"
    if not os.path.exists(dir1):
        os.mkdir(dir1)  # 創(chuàng)建帖子文件夾
    with trange(len(f3)) as bar:  # 進度條
        for j in bar:
            # 下載圖片并保存
            s = f3[j].split("/")
            pic_id = s[len(s) - 1]
            # 圖片下載地址'http://imgsrc.baidu.com/forum/pic/item/4254484e251f95ca67a500d0c6177f3e660952e7.jpg'
            url4 = 'http://imgsrc.baidu.com/forum/pic/item/' + pic_id + '.jpg'
            f = open(dir1 + str(j) + ".jpg", 'wb')
            f.write((request.urlopen(url4, timeout=5)).read())
            f.close()
            # 打印進度信息
            bar.set_description(str(i) + ". " + title[i] + "(共" + str(len(f3)) + "張)")

print("貼吧首頁下載完成只怎。")
程序運行結(jié)果

五、遇到的問題

問題1:點擊程序運行怜俐,但程序一直卡住身堡,既不報錯,又沒有結(jié)果拍鲤。
原因:經(jīng)調(diào)試發(fā)現(xiàn)程序一直卡住code = html.read()贴谎,所以程序應(yīng)加上超時處理和異常處理。如此程序會正常報錯季稳。
報錯程序:

from urllib import request

html = urllib.request.urlopen(url)
code = html.read()
code = code.decode("UTF_8")

改正后程序

from urllib import request, error

try:
    html = request.urlopen(url, timeout=3)
    code = html.read()
    code = code.decode("UTF_8")
except error.URLError as e:
    print(e.reason)

問題2:點擊程序運行擅这,發(fā)出超時錯誤。
原因:這可能是網(wǎng)絡(luò)連接不佳或者網(wǎng)站發(fā)現(xiàn)是爬蟲程序而禁止訪問景鼠,推薦博客python urllib.request的5個基本程序仲翎,使用異常處理,User_Agent和IP代理運行測試一下是否可以讀取url的源碼铛漓。

問題3:百度貼吧首頁下載完成溯香,想換頁怎么辦?

孫允珠吧首頁
孫允珠吧第2頁
孫允珠吧第10頁

解決方法:由上圖可知浓恶,其它頁的網(wǎng)址可以直接從首頁推出玫坛。即第n頁的url
="http://tieba.baidu.com/f?kw=%E5%AD%99%E5%85%81%E7%8F%A0&ie=utf-8&pn="+(n-1)*50

問題4:在百度貼吧首頁查找帖子編號 “6383722178”和圖片編號 “4254484e251f95ca67a500d0c6177f3e660952e7”也能找到,為何還要打開具體帖子讀取圖片編號包晰?
解答:百度貼吧首頁獲取的圖片編號只是帖子中圖片編號的一部分而已湿镀,它并不完全。

問題5:在具體帖子的源碼中已經(jīng)可以找到所有圖片編號以及地址伐憾,為何不用這個地址勉痴,而要使用原圖顯示圖片的地址?
解答:直接使用帖子中的圖片地址也是可以下載圖片的塞耕,但它只是按比例縮小的縮略圖蚀腿,不是原圖。

六、參考資料

1莉钙、Python學(xué)習(xí)筆記(二)urllib.urlopen()超時問題 : 504Gateway Time-out
2廓脆、【Python】urllib庫——下載網(wǎng)頁、爬蟲匯總

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磁玉,一起剝皮案震驚了整個濱河市停忿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚊伞,老刑警劉巖席赂,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異时迫,居然都是意外死亡颅停,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門掠拳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來癞揉,“玉大人,你說我怎么就攤上這事溺欧『笆欤” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵姐刁,是天一觀的道長芥牌。 經(jīng)常有香客問我,道長聂使,這世上最難降的妖魔是什么壁拉? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮柏靶,結(jié)果婚禮上扇商,老公的妹妹穿的比我還像新娘。我一直安慰自己宿礁,他們只是感情好,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布蔬芥。 她就那樣靜靜地躺著梆靖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪笔诵。 梳的紋絲不亂的頭發(fā)上返吻,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音乎婿,去河邊找鬼测僵。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的捍靠。 我是一名探鬼主播沐旨,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼榨婆!你這毒婦竟也來了磁携?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤良风,失蹤者是張志新(化名)和其女友劉穎谊迄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烟央,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡统诺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疑俭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粮呢。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖怠硼,靈堂內(nèi)的尸體忽然破棺而出鬼贱,到底是詐尸還是另有隱情,我是刑警寧澤香璃,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布这难,位于F島的核電站,受9級特大地震影響葡秒,放射性物質(zhì)發(fā)生泄漏姻乓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一眯牧、第九天 我趴在偏房一處隱蔽的房頂上張望蹋岩。 院中可真熱鬧,春花似錦学少、人聲如沸剪个。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扣囊。三九已至,卻和暖如春绒疗,著一層夾襖步出監(jiān)牢的瞬間侵歇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工吓蘑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惕虑,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像溃蔫,于是被迫代替她去往敵國和親健提。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349