Python爬取淘宝图片
爬取淘女郎模特圖片與相關(guān)信息
(一)解析淘女郎首頁網(wǎng)站地址果然,仔細(xì)觀察發(fā)現(xiàn),里面加載的內(nèi)容跟當(dāng)前頁面的人名及其他信息完全吻合。便可以肯定這就是我們要的數(shù)據(jù)。所以,查看request url獲取相關(guān)url。https://mm.taobao.com/alive/list.do?scene=all&page=1
而后面的page=1 則就表示,第一頁。只要我們把數(shù)值改變便可以加載到對應(yīng)的頁碼。
個人覺得這個還算簡單。所以直接上代碼了:
import urllib.request import re from user_agent.base import generate_user_agentclass Spider:# 定義需要爬取的頁數(shù)def __init__(self, page):self.page = int(page)# 獲取要爬取的圖片的頁數(shù)def get_pags(self, page):for i in range(1, page+1):url = "https://mm.taobao.com/alive/list.do?scene=all&page=%d"%iyield url# 定義常用的 URL 打開函數(shù)def open_url(self, url):user_agent = generate_user_agent()header = {"User-Agent":user_agent}req = urllib.request.Request(url, headers=header)response = urllib.request.urlopen(req).read() # 文件未進(jìn)行decode解碼,此時為response二進(jìn)制文件return response# 定義獲取圖片名稱的函數(shù)def get_name(self, url):response = self.open_url(url).decode('gbk').encode('utf-8').decode('utf-8')name_list = re.compile('darenNick":"(.*?)"').findall(response)return name_list# 定義獲取圖片鏈接地址并返回圖片內(nèi)容def get_picture(self, url):response = self.open_url(url).decode('gbk').encode('utf-8').decode('utf-8')link_list = re.compile('avatarUrl":"(.*?)"').findall(response)for link in link_list:if re.compile('http:').match(link):img = self.open_url(link)else:link_ = 'http:'+ linkimg = self.open_url(link_)yield img # 這里一個二進(jìn)制生成器,方便圖片保存# 保存圖片def save_picture(self, url):name = self.get_name(url)img = self.get_picture(url)list_zip = list(zip(name, img))for each in list_zip:with open('./首頁/%s.jpg'%each[0], 'wb') as f:f.write(each[1])def main(self):links = self.get_pags(self.page)for link in links:print(link)self.get_name(link)self.get_picture(link)self.save_picture(link)print("It's done!!")if __name__ == "__main__":spider = Spider(67)spider.main()都是一些常見的爬蟲知識,而我重點(diǎn)要講的不是這個,而是這中間的這個decode編碼問題(純屬個人的看法):這里面獲取那些信息的時候那是出現(xiàn)那些編碼錯誤,好像是由于,中文與utf-8的老毛病導(dǎo)致的。我試過在decode()參數(shù)中設(shè)置忽略ignore,與replace,然而并沒有什么用。試來試去發(fā)現(xiàn)這種辦法最靠譜了。不報錯。如果有遇到相同錯誤的可以參考一下。
結(jié)果部分截圖:
1,進(jìn)入找模特
2,細(xì)心找
進(jìn)入一個網(wǎng)頁地址第一件事肯定是,審查元素。發(fā)現(xiàn)也不能在網(wǎng)頁源碼中找到信息。想想我們上面說的,那就是耐細(xì)的去網(wǎng)頁數(shù)據(jù)包中找。先看有沒有動態(tài)加載的XHR,一般都是在這個下面可以找到。沒錯。這個就是這么找到的。
右邊的數(shù)據(jù)仔細(xì)一看,發(fā)現(xiàn)它是一個像字典一樣的東西,里面包含了很多鍵值對,再網(wǎng)頁翻發(fā)現(xiàn)最里面那一層包含了30對鍵值對,分別包含一些用戶名,userID ,等。這個時候再看這個網(wǎng)頁,發(fā)現(xiàn),剛好有30張照片。初步確定就是這個。
隨后,找到request url 的請求網(wǎng)絡(luò)地址,然后用瀏覽器打開。發(fā)現(xiàn)里面包含了30張照片的基本信息。于是我們就知道,這就是我們要的 真實(shí)的 URL。
3,信息獲取
我們可以看到,每張圖片下方都有對應(yīng)模特的相關(guān)信息:名字,城市,身高,體重,被贊次數(shù)。
當(dāng)我們點(diǎn)進(jìn)去看,里面還有很多東西,相冊里面有很多寫真。模特卡里面還有跟多個人簡介,三圍等
這里呢,我們初步確定先只爬取模特的相關(guān)信息:名字,城市,身高,體重,被贊次數(shù),并且每個模特單獨(dú)使用一個文件夾。
4,分析代碼可行度
我們需要編寫一個函數(shù)從來獲取圖片
一個用來獲取名字,另一個用來獲取其他的相關(guān)信息。
這個應(yīng)該容易。因?yàn)樘崛⌒畔?#xff0c;只需要用到很簡單的正則表達(dá)式即可。
在準(zhǔn)備好這一切之后。發(fā)現(xiàn),整個頁面只有30張圖片,是不是少了點(diǎn)。那么我們怎么翻頁呢?首先肯定是去往源代碼里找翻頁的鏈接可不可以用。結(jié)果顯示,是不可以的。那么我么怎么去做?下面來看:
在header里面可以看到,下面有個一個表單。而這個表單就是我們這個網(wǎng)頁提交的數(shù)據(jù)。里面有一項(xiàng)currentpage,當(dāng)你切換頁碼的時候,發(fā)現(xiàn)這個值跟隨頁碼也在變化。好了。肯定就是這樣了。
所有我們可以通過表單提交數(shù)據(jù)來達(dá)到切換到下一頁的目的。然后結(jié)合我們前面的,大致的思路應(yīng)該出來了,即:
①編寫幾個獲取相應(yīng)信息的函數(shù)
②然后編寫保存這個些信息的函數(shù)
③接著通過切換下一頁來達(dá)到保存更多的信息
5,給出代碼參考
# -*- coding : utf-8 -*- ''' Desc: 抓取淘寶中淘女郎模特的信息:名字,圖片,身高,體重以文件夾形式保存信息保存為文本通過觀察network 中變化,得出信息網(wǎng)址:https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8經(jīng)過分析發(fā)現(xiàn),無法通過此網(wǎng)站源碼中鏈接實(shí)現(xiàn)翻頁,于是想到通過提交表單數(shù)據(jù)實(shí)現(xiàn)翻頁。request url 不變?nèi)缓缶褪侨绾芜M(jìn)入 各位模特的詳情頁 的問題了。通過觀察發(fā)現(xiàn):https://mm.taobao.com/self/aiShow.htm?&userId=268367415 可以進(jìn)入對應(yīng)模特的個人界面。https://mm.taobao.com/self/model_info.htm?user_id=268367415 可以進(jìn)入對應(yīng)model的模特卡,里面有跟多相關(guān)信息。而 userId 正好我們可以從前面那個鏈接獲取到。通過改變ID便可實(shí)現(xiàn)對詳情頁面信息的爬取 ''' import urllib.request import urllib.parse import re from user_agent.base import generate_user_agent import os.path, os from datetime import datetime import threading # 設(shè)立標(biāo)志位flag 用于判斷文件是否已經(jīng)存在,用來避免重復(fù)操作 global flag class Spider:def __init__(self):pass# 定義常用的 URL 打開函數(shù)def open_url(self, url, data):data = urllib.parse.urlencode(data).encode("utf-8")user_agent = generate_user_agent()header = {"User-Agent":user_agent}req = urllib.request.Request(url, data=data, headers=header)response = urllib.request.urlopen(req).read() # 文件未進(jìn)行decode解碼,此時為response二進(jìn)制文件return response# 獲取model的realnamedef get_realname(self, url, data):response = self.open_url(url, data).decode('gbk').encode('utf-8').decode('utf-8')name = re.compile('realName":"(.*?)"').findall(response)return name# 獲取model頭像地址,并返回圖片的二進(jìn)制信息def get_head(self, url,data):response = self.open_url(url,data).decode('gbk').encode('utf-8').decode('utf-8')link_list = re.compile('avatarUrl":"(.*?)"').findall(response)imgs = []for link in link_list:link_ = 'http:'+ linkimg = urllib.request.urlopen(link_).read()imgs.append(img)return imgs # 直接返回二進(jìn)制文件,方便圖片保存# 保存一張圖片def save_img(self, img, folder, picname, i):print("正在保存 %s 的照片..." %picname)with open(folder+'/'+picname+'.jpg', 'wb') as f:f.write(img)print("完成!")# 獲取model的 城市,身高,體重,被贊次數(shù)def get_desc(self,url, data):response = self.open_url(url,data).decode('gbk').encode('utf-8').decode('utf-8')city = re.compile('city":"(.*?)"').findall(response)height = re.compile('height":"(.*?)"').findall(response)weight = re.compile('weight":"(.*?)"').findall(response)favor = re.compile('totalFavorNum":(.*?),').findall(response)# 建立人物信息對應(yīng)關(guān)系desc = list(zip(city, height, weight, favor))return desc# 保存一個人物信息def save_desc(self, folder, filename, desc, i):print("正在保存 %s 的個人信息" %filename)line = "model:\t\t %s \n\n所在城市:\t\t %s \n\n身高(cm):\t\t %s \n\n體重(kg):\t\t %s \n\n這貨被贊過: %d 次" % (filename, desc[i][0], (desc[i][1]), (desc[i][2]), int(desc[i][3]))with open(folder + '/' + filename + '.txt', 'w') as f:f.write(line)print("完成!")# 建立每個模特的文件夾def make_dir(self, folder):#判斷model文件夾下是否存在folderif os.path.exists(folder):print("文件夾已存在!")flag = 1return flagelse:os.mkdir(folder)print("已創(chuàng)建文件夾 %s " % folder)flag = 0return flagdef main(self):url = "https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8"print(datetime.now().strftime( '%Y-%m-%d %H:%M:%S' ))pages = int(input("程序開始...\n請輸入要爬取的頁數(shù)(1-1450):\n" ))if pages<1:print("太小啦,請輸入1-1450之間的整數(shù)...")if pages>1450:print("太大啦,請輸入1-1450之間的整數(shù)...")i = 0# 選擇一個文件夾os.chdir("model")# 實(shí)現(xiàn)翻頁操作for page in range(1,pages+1):data = {'currentPage': page, 'pageSize':100}# 重置i 因?yàn)槊恳豁撝挥?0份數(shù)據(jù)i =0# 獲取人物基本信息real_name = self.get_realname(url, data)imgs = self.get_head(url, data)desc = self.get_desc(url, data)# 圍繞名字這個關(guān)鍵字來理清思路for name in real_name:flag = self.make_dir(name)if flag == 0:print("正在進(jìn)行第 %d 頁的第 %d 次操作,操作對象是: %s " % (page, i + 1, name))# 保存model頭像的二進(jìn)制文件self.save_img(imgs[i], name, name, i)self.save_desc(name, name, desc, i)else:passi += 1print("It's done!!\n", datetime.now().strftime( '%Y-%m-%d %H:%M:%S' ))if __name__ == "__main__":spider = Spider()spider.main()6,代碼分析
1,上邊代碼的注釋都非常清楚,import user_agent 是用來隨機(jī)生成可用的user-agent模擬瀏覽器訪問,防止被BAN。
我對部分代碼進(jìn)行了處理,比如利用標(biāo)志位防止文件夾重復(fù)操作,只不過代碼太過冗長,因?yàn)槲覜]有花時間去優(yōu)化下它,都是想到什么寫什么,所以僅供參考。
2,這個代碼的功能及其少,不過如果要爬取跟跟多信息也很簡單。如:
https://mm.taobao.com/self/aiShow.htm?&userId=268367415 可以進(jìn)入對應(yīng)模特的個人界面。
https://mm.taobao.com/self/model_info.htm?user_id=268367415 可以進(jìn)入對應(yīng)model的模特卡,
上面這連個鏈接可以讓我們獲得跟更多的信息。而我們可以通過改變 userID的值來獲得不同model的不同信息。這些userID我們都可以在上面的代碼中獲得,只需要多添加一行代碼用正則提取相關(guān)userID操作即可。這個沒啥大問題。
3,代碼在執(zhí)行過程中,可以回比較慢,因?yàn)檫@只是一個單線程,而且還受網(wǎng)路影響,不過單線程才是主要的。所以建議開多個線程來執(zhí)行這個操作。這樣會快很多。由于程序改動會比較麻煩。我就沒弄了。。我太懶了。沒辦法。。。。還有一個就是多線程不太會。。[/尷尬]
結(jié)果部分截圖:
好吧,就這么多了..
總結(jié)
以上是生活随笔為你收集整理的Python爬取淘宝图片的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消息转换器原理解析
- 下一篇: Python-使用海龟绘图制作动态时钟