Python小爬蟲——貼吧圖片的爬取
在對Python有了一定的基礎學習后,進行貼吧圖片抓取小程序的編寫。
目標:
首先肯定要實現圖片抓取這個基本功能
然后實現對用戶所給的鏈接進行抓取
最后要有一定的交互,程序不能太傻吧
一、頁面獲取
要讓python可以進行對網頁的訪問,那肯定要用到urllib之類的包。So先來個 import urllib
urllib中有 urllib.urlopen(str) 方法用于打開網頁并返回一個對象,調用這個對象的read()方法后能直接獲得網頁的源代碼,內容與瀏覽器右鍵查看源碼的內容一樣。
1 #coding:utf-8
2 importurllib3
4 page = urllib.urlopen('http://tieba.baidu.com/p/1753935195')#打開網頁
5 htmlcode = page.read()#讀取頁面源碼
6 print htmlcode#在控制臺輸出
運行結果與查看源碼其實差不多
運行結果就不放上來了
也可以寫到文本文檔中:
1 #coding:utf-8
2 importurllib3
4 page = urllib.urlopen('http://tieba.baidu.com/p/1753935195')5 htmlcode =page.read()6 #print htmlcode
7
8 pageFile = open('pageCode.txt','w')#以寫的方式打開pageCode.txt
9 pageFile.write(htmlcode)#寫入
10 pageFile.close()#開了記得關
運行一遍,txt就出現在了getJpg.py
的目錄下
好了別鬧,我們把它封裝成方法:
1 defget_html(url):2 page =urllib.urlopen(url)3 html =page.read()4 return html
然后我們的頁面獲取代碼就K.O.了
二、圖片(目標)的提取
做完上面步驟,你打開txt一看,我去!這都是什么跟什么啊,根本找不到圖片在哪好伐?
客官別急啊,我這就去給你叫我們的小。。。圖片!圖片!
首先我們要一個正則表達式 (什么你不會?請看菜鳥入門教程-->
然后我們看源代碼,Yeah 我們找到了其中一張圖片是這樣的
寫出圖片的正則表達式: reg = r'src="(.+?\.jpg)" width'
解釋下吧——匹配以src="開頭然后接一個或多個任意字符(非貪婪),以.jpg" width結尾的字符串。比如圖中紅框內src后 雙引號里的鏈接就是一個匹配的字符串。
接著我們要做的就是從get_html方法返回的辣么長一串字符串中 拿到 滿足正則表達式的 字符串。
用到python中的re庫中的 re.findall(str) 它返回一個滿足匹配的字符串組成的列表
1 #coding:utf-8
2 importurllib3 importre4
5 defget_html(url):6 page =urllib.urlopen(url)7 html =page.read()8 returnhtml9
10 reg = r'src="(.+?\.jpg)" width'#正則表達式
11 reg_img = re.compile(reg)#編譯一下,運行更快
12 imglist = reg_img.findall(get_html('http://tieba.baidu.com/p/1753935195'))#進行匹配
13 for img inimglist:14 print img
打印出這么多圖片鏈接
光把鏈接拿出來沒用啊,我們的目標是下載下來~
urllib庫中有一個 urllib.urlretrieve(鏈接,名字) 方法,它的作用是以第二個參數為名字下載鏈接中的內容,我們來試用一下
在上面代碼循環中加上 urllib.urlretrieve(img, 'tieba.jpg')
臥槽!!!怎么只下了一張
至少它下載了不是?啪啪啪啪啪(掌聲)
檢查下問題出在哪。。。。
沒錯我們只給了一個tieba.jpg的名字,后來的把前面的覆蓋了。
調整下代碼:
1 #coding:utf-8
2 importurllib3 importre4
5 defget_html(url):6 page =urllib.urlopen(url)7 html =page.read()8 returnhtml9
10 reg = r'src="(.+?\.jpg)" width'
11 reg_img =re.compile(reg)12 imglist = reg_img.findall(get_html('http://tieba.baidu.com/p/1753935195'))13 x =014 for img inimglist:15 urllib.urlretrieve(img, '%s.jpg' %x)16 x += 1
啪啪啪啪啪
第一步完成~
三、指定鏈接抓取
我想要抓另一個帖子,總不能打開源代碼,然后把那段地址改了在運行吧。
只是一個小程序,那也不行欸,加一個讓用戶指定地址的交互。
先把提取圖片的那段代碼打包下:
1 defget_image(html_code):2 reg = r'src="(.+?\.jpg)" width'
3 reg_img =re.compile(reg)4 img_list =reg_img.findall(html_code)5 x =06 for img inimg_list:7 urllib.urlretrieve(img, '%s.jpg' %x)8 x += 1
最后來個請輸入:
1 print u'請輸入url:',2 url =raw_input()3 ifurl:4 pass
5 else:6 url = 'http://tieba.baidu.com/p/1753935195'
7 html_code =get_html(url)8 get_image(html_code)
運行一下,試試另一個帖子:
完美~~
四、交互的添加
雖然寫的是一個簡單的小程序,但有強迫癥的我還是給他加上了交互(不然多難受啊:雙擊,屏幕一閃,下載完了。。。)
最后的代碼
1 #coding:utf-8
2 importurllib3 importre4
5 defget_html(url):6 page =urllib.urlopen(url)7 html_code =page.read()8 returnhtml_code9
10 defget_image(html_code):11 reg = r'src="(.+?\.jpg)" width'
12 reg_img =re.compile(reg)13 img_list =reg_img.findall(html_code)14 x =015 for img inimg_list:16 urllib.urlretrieve(img, '%s.jpg' %x)17 x += 1
18
19 print u'-------網頁圖片抓取-------'
20 print u'請輸入url:',21 url =raw_input()22 ifurl:23 pass
24 else:25 print u'---沒有地址輸入正在使用默認地址---'
26 url = 'http://tieba.baidu.com/p/1753935195'
27 print u'----------正在獲取網頁---------'
28 html_code =get_html(url)29 print u'----------正在下載圖片---------'
30 get_image(html_code)31 print u'-----------下載成功-----------'
32 raw_input('Press Enter to exit')
相對來說比較舒服的交互體驗,大功告成~