版本1.5
本次簡單添加了四路多線程(由於我電腦CPU是四核的),速度飆升。本想試試xPath,但發現反倒是多此一舉,故暫不使用
#-*- coding:utf-8 -*- import re,urllib,os,urllib2,chardet,requests,time from multiprocessing.dummy import Pool def urllink(link): #網頁HTML獲取以及編碼轉換 html_1 = urllib2.urlopen(link,timeout=120).read() encoding_dict = chardet.detect(html_1) web_encoding = encoding_dict['encoding'] if web_encoding == 'utf-8' or web_encoding == 'UTF-8': html = html_1 else : html = html_1.decode('gbk','ignore').encode('utf-8') return html def downloadpic(j): href = 'http://www.dazui88.com' + re.search('href="(.*?).html', j).group(1) # 每一套總網址 label = (re.findall('alt="(.*?)"', j, re.S))[0].strip() # 每一套名稱 path = unicode(r'D:\pachong\pans\%s' % (label), 'utf-8') # 每一套文件夾 print '開始下載,%s' % (label) if not os.path.exists(path): os.mkdir(path) p = 0 for k in range(1, 100): # 爬取其中每一張圖片 hrefnew = href if k is not 1: hrefnew = href + '_%d' % k hrefnew += '.html' try: # 如果此頁不存在,表示已經爬完了,開始爬下一組 html2 = urllink(hrefnew) except: print u'該套下載完畢\n' break; try: # 如果該頁中圖片丟失,則開始爬下一張 picurl = re.findall('img alt.*?src="(.*?)"', html2) except: print u'該處丟失一張' continue for n in picurl: # 由於可能存在多張,故需一一下載 p += 1 if not re.findall('http', n, re.S): # 部分圖片缺少前綴部分,故需判斷后添加 n = 'http://www.dazui88.com' + n print u'正在下載圖片,圖片地址:' + n retu = requests.get(n, stream=True) picpath = unicode(r'D:\pachong\pans\%s\%s' % (label, str(p)) + '.jpg', 'utf-8') file = open(picpath, 'wb') for chunk in retu.iter_content(chunk_size=1024 * 8): if chunk: file.write(chunk) file.flush() file.close() def spider(): for i in range(2,46): #爬取總共的主頁面數 link1="http://www.dazui88.com/tag/pans/list_86_%d.html"%i html=urllink(link1) plist=re.findall("<p>.*?</p>",html,re.S) pool = Pool(4) pool.map(downloadpic,plist) pool.close() pool.join() if __name__=="__main__": spider()
***************************** 分割線 *********************************
版本1.2
此次添加若干功能,如下:
1.首先,終於解決了中文文件夾亂碼的問題,現支持中文文件夾自動創建,我想吐槽一句,python的中文編碼處理真的是稀爛,各種迷
2.美化腳本的輸出,使其更加直觀美觀
3.解決了一個頁面多張圖片的下載問題
4.修復部分圖片地址缺少前綴導致無法下載的問題
***************************** 分割線 *********************************
版本1.0
今天上午開始學了學爬蟲技術。下午開始着手寫了第一個網站爬蟲腳本。
這次我要爬的是隨手找的一個主要是妹子圖片的網站,目標是把其中某個分類下的所有妹子套圖都爬下來
(舉例附網址:http://www.dazui88.com/tag/toutiao/list_130_1.html)
老司機們應該知道,一套圖一般都有幾十張,但這類網站一般一頁只會放出一張或者幾張,這樣一來我們瀏覽圖片時的觀感就會大大下降,
因此一次把圖片全都爬下來會方便的多。
實現時的技術要求與難點:
總的老說目前做的還比較粗糙,但完全夠用,主要是拿來練練手。
1.本想以每套圖片的名字作為文件夾,但是由於中文有亂碼,暫時未實現;
2.下載圖片使用的還是requests庫,貌似 beautifulsoup庫會更好一點,但暫未嘗試;
3.由於並沒有編寫多線程,以及緩沖池之類的,速度會比較慢,但還可以接受;
4.腳本存在一定問題,如果網站其中一張圖片丟失,該套圖片的剩下部分會被跳過,可解決,但暫未解決;
5.腳本還可以做成軟件的形式,但較耗時,有空再說;
6.由於此次爬取的網站其他版塊的url結構基本一致,所以花上幾秒鍾改一下,就能很快爬取其他的圖片,甚至整個站所有的圖片,但是速度有待改進。
代碼實現:
#-*- coding:utf-8 -*- import re,urllib,os,urllib2,chardet,requests def urllink(link): #網頁HTML獲取以及編碼轉換 html_1 = urllib2.urlopen(link,timeout=120).read() encoding_dict = chardet.detect(html_1) web_encoding = encoding_dict['encoding'] if web_encoding == 'utf-8' or web_encoding == 'UTF-8': html = html_1 else : html = html_1.decode('gbk','ignore').encode('utf-8') return html def spider(): m=0 for i in range(1,12): #爬取總共的主頁面數 link1="http://www.dazui88.com/tag/tgod/list_80_%d.html"%i html=urllink(link1) plist=re.findall("<p>.*?</p>",html,re.S) for j in plist: #開始爬其中每一套 m+=1 href = 'http://www.dazui88.com' + re.search('href="(.*?).html', j).group(1) #每一套總網址 label = (re.findall('alt="(.*?)"',j,re.S))[0].strip() #每一套名稱 path = unicode(r'D:\pachong\tgod\%s %s' %( str(m),label), 'utf-8') #每一套文件夾 print '開始下載第%d套,%s'%(m,label) if not os.path.exists(path): os.mkdir(path) p=0 for k in range(1,100): #爬取其中每一張圖片 hrefnew=href if k is not 1: hrefnew=href+'_%d'%k hrefnew+='.html' try: #如果此頁不存在,表示已經爬完了,開始爬下一組 html2=urllink(hrefnew) except: print u'該套下載完畢\n' break; try: #如果該頁中圖片丟失,則開始爬下一張 picurl=re.findall('img alt.*?src="(.*?)"',html2) except: print u'該處丟失一張' continue for n in picurl: #由於可能存在多張,故需一一下載 p+=1 print u'正在下載圖片,圖片地址:'+n retu=requests.get(n,stream=True) picpath=unicode(r'D:\pachong\tgod\%s %s\%s'%(str(m),label,str(p))+'.jpg','utf-8') file=open(picpath,'wb') for chunk in retu.iter_content(chunk_size=1024*8): if chunk: file.write(chunk) file.flush() file.close() if __name__=="__main__": spider()