[記錄][python]python爬蟲,下載某圖片網站的所有圖集,

來源:互聯網
上載者:User

[記錄][python]python爬蟲,下載某圖片網站的所有圖集,

  

隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

 

  該隨筆是記錄我的第一個python程式,一個爬去指定圖片網站的所有圖集,現在還是一個非常簡陋的單線程程式。下一步是改寫成多線程,雖然python多線程被詆毀得一塌糊塗。同時加上異常處理。

  近來練習python程式,仿照別人的爬蟲寫一個自己的爬蟲來練練手。在編寫的過程中遇到各種問題,中文編碼、請求不到html等問題。撰寫該隨筆的目的是將所遇到的問題記錄下來,並提供相應的解決方案。當然這些解決方案是參照其他人提供的,東抄抄西抄抄,^_^。

   先大致描述下代碼過程中遇到的問題: 隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

  •  html中文解碼

  雖然beautifulsoup預設的編碼方式是utf-8,而且國內部分網站的編碼方式是utf-8。還是需要手工設定一下中文的編碼方式。

  在BeautifulSoup中手工設定編碼方式如下所示

encoding = "gb18030"soup = BeautifulSoup(html,from_encoding=encoding)  

  

  •  list的append和extend使用 隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

  查詢相關資料,list中的append是向list插入一個值,extend則是將一個list插入另一個list中;

  若要將list1併入list2中,則使用list2.extend(list1);

  若向list中插入值的話,使用list.append(vale)

 

  •  beautifulsoup返回的值,可以直接尋找合格節點

   beautifulsoup返回的值是一顆文法樹,結果與html dom結構差不多[這個地方有些保留,我目前不是太瞭解dom結構],通過find和find_all去尋找相應的標籤。前者返回一個標籤的對象,後者返回list,該list的值是多個對象。

 

  •  將urllib.urlretrieve()盡量偽裝成一個使用者。

  使用 urlretrieve之前,將發送的http請求做些簡單的偽裝,盡量偽裝成為一個使用者,避免網站不響應下載請求。若不設定的話,通過wireshark,可以查看到下載請求的user-agent的值與python有關,伺服器可能會將下載請求給忽略掉。同時還可以添加上referer,有些網站通過referer來判斷盜鏈。若不設定的話,下載的圖片全是防盜鏈提示圖片。 隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

        #偽裝一下下載的http請求,否則有些網站不響應下載請求。        #不設定的話,下載請求中的user-agent為python+版本號碼        urllib.URLopener.version = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0'        #下載圖片到指定目錄中,保留圖片在伺服器上的檔案名稱        urllib.urlretrieve(imgurl,downloadpath)

  

  廢話有些多,上代碼。為了避免宣傳圖片網站的嫌疑,不放該網站的連結。 代碼僅用於學習交流。

import urllib2import ioimport randomimport urllibfrom bs4 import BeautifulSoupimport reimport osimport sysreload(sys)sys.setdefaultencoding('utf8')def getHtml(url): #儘可能讓爬蟲顯示為一個正常使用者。若不設定,則發送的請求中,user-agent顯示為Python+版本 user_agent = [ 'Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30', 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)', 'Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.9.168 Version/11.50', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)' ] #設定網頁編碼格式,解碼擷取到的中文字元 encoding = "gb18030" #構造http要求標頭,設定user-agent header = {"User-Agent":random.choice(user_agent)} #構造發送請求 request = urllib2.Request(url,headers=header) #發送請求,擷取伺服器響應回來的html頁面 html = urllib2.urlopen(request).read() #使用beautifulSoup處理的html頁面,類似dom soup = BeautifulSoup(html,from_encoding=encoding) return soup# 擷取整個網站所有圖集的頁碼def getPageNum(url): soup = getHtml(url) # 直接在網站首頁擷取所有圖集的總頁碼 nums=soup.find_all('a',class_='page-numbers') # 除掉“下一頁”的連結,並擷取到最後一頁 totlePage = int(nums[-2].text) return totlePage#擷取指定頁面集名稱和連結def getPicNameandLink(url): soup = getHtml(url) meun = [] #類似html dom對象,直接尋找id為“pins”的ul標籤,返回的結果是一個dom對象 targetul = soup.find("ul",id="pins") if targetul: #擷取該ul下所有的超連結,傳回值的類型是list,find_all中第二個參數表示某個指定標籤的屬性 pic_list = targetul.find_all("a",target="_blank") if pic_list: # 遍曆所有指定的標籤a for pic in pic_list: #擷取圖集的連結 link = pic["href"] picturename = "" #找到標籤a中,“class”為“lazy”的img標籤。 #find中,第二個參數表示某個指定標籤的屬性。 #在python中class是保留字,所有標籤的class屬性的名稱為“class_” img = pic.find("img",class_='lazy') if img: # 保證中文字元能夠正常轉碼。 picturename = unicode(str(img["alt"])) else: continue #插入圖集名稱和對應的url meun.append([picturename,link]) return meun return None#function擷取所有的圖集名稱def getallAltls(url): totalpage = getPageNum(url) #擷取首頁中所有的圖集名稱。首頁的url和其他頁面不同,沒有page meun = getPicNameandLink(url) #迴圈遍曆所有的圖集頁面,擷取圖集名稱和連結 for pos in range(2,totalpage): currenturl = url + "/page/" + str(pos) #getPicNameandLink()返回的值是一個list。 #當一個list插入到另一個list中時,使用extend。 #若是插入一個值時,可以用append meun.extend(getPicNameandLink(currenturl)) return meun # 擷取從首頁到指定頁面所有的圖集名稱和連結def getparAltls(url,page): meun = getPicNameandLink(url) for pos in range(2,page): currenturl = url + "/page/" + str(pos) meun.extend(getPicNameandLink(currenturl)) return meun#擷取單個相簿內圖片頁碼def getSinglePicNum(url): soup = getHtml(url) #pagenavi還是一個對象(Tag),可以通過find_all找出指定標籤出來 pagenavi = soup.find("div",class_="pagenavi") pagelink = pagenavi.find_all("a") num = int(pagelink[-2].text) return num#下載單個相簿中的所有圖片def getSinglePic(url,path): totalPageNum = getSinglePicNum(url) #從第一頁開始,下載單個圖集中所有的圖片 #range()第二個參數是範圍值的上限,迴圈時不包括該值 #需要加1以保證讀取到所有頁面。 for i in range(1,totalPageNum + 1): currenturl = url + "/" + str(i) downloadpic(currenturl,path) #下載單個頁面中的圖片 def downloadpic(url,path): soup = getHtml(url) #找出指定圖片所在父容器div pageimg = soup.find("div",class_="main-image") if pageimg: #找出該div容器中的img,該容器中只有一個img img = pageimg.find("img") #擷取圖片的url imgurl = img["src"] #擷取圖片的檔案名稱 restring = r'[A-Za-z0-9]+\.jpg' reimgname = re.findall(restring,imgurl) #將圖片儲存在指定目錄下 path = str(path) if path.strip() == "": downloadpath = reimgname[0] else: downloadpath = path + "/" + reimgname[0] #偽裝一下下載的http請求,否則有些網站不響應下載請求。 #不設定的話,下載請求中的user-agent為python+版本號碼 urllib.URLopener.version = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0' #下載圖片到指定目錄中,保留圖片在伺服器上的檔案名稱 urllib.urlretrieve(imgurl,downloadpath) def downimgofsite(url,path = ""): path = str(path) #擷取所有圖集的名稱和連結 meun_list = getallAltls(url) directorypath = "" for meun in meun_list: directoryname = meun[0] if path.strip() != "": directorypath = path + "/" + directoryname else: directorypath = os.getcwd + "/" + directoryname if not os.path.exists(directorypath): os.makedirs(directorypath) getSinglePic(meun[1], directorypath) if __name__ == "__main__": # page = 8 url = "XXXXX" menu = getallAltls(url) #menu = getparAltls(url, page) f = open("tsts.txt","a") for i in menu: f.write(str(unicode(i[0]))+"\t"+str(i[1])+"\n") f.close() View Code

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.