關(guān)于&說明
這是我的第一個正式的爬蟲
個人感覺圖蟲網(wǎng)的圖片還是不錯的漏益,關(guān)鍵是小姐姐的圖片多https://tuchong.com/tags/%E7%BE%8E%E5%A5%B3/
此爬蟲只作為學(xué)習(xí)交流,如有侵犯請告知作者绰疤,刪除!癣猾、
網(wǎng)站的爬取還是非常簡單的沒有模擬登陸余爆,驗證碼,加密什么的個人感覺很簡單
準備
開發(fā)環(huán)境&工具:Python3 龙屉,Pycharm
需要用到的模塊 re,requests作岖,os,json五芝,urllib.parse痘儡,traceback
分析
進入官網(wǎng)我們選擇發(fā)現(xiàn)-->標簽然后會看到很多的類型
我們先隨意選擇一個,這里我就選擇美女這個標簽吧枢步!(小姐姐)
進去之后我們會發(fā)現(xiàn)有很多的圖片集
如何獲取圖片
第一種圖片獲取
然后我們點擊一個圖片集沉删,查看并且打開F12調(diào)試工具選擇Network選項進行抓包,注意F12調(diào)試工具不要關(guān)閉后續(xù)有用!
然后我在抓包數(shù)據(jù)中并沒有找到準確的圖片地址醉途,但是可以從一下數(shù)據(jù)鏈接中找到圖片的img_id(PS:img_id就是圖片的標識例如https://photo.tuchong.com/1535376標識(這里是圖片集的)/l/18389913(這里就是圖片的標識了).jpg)我們在這里就不用這個了如果想用自行嘗試矾瑰,附上此數(shù)據(jù)鏈接地址 https://tuchong.com/rest/posts/15653079(后面的數(shù)字是本圖片集的標識后續(xù)會講到)
現(xiàn)在我們再去源碼中找一下,應(yīng)為網(wǎng)站js限制所以無法右擊查看源碼隘擎,請看下面講解
PS:
如果你是谷歌內(nèi)核的瀏覽器需要打開一個新標簽且輸入view-source:(這里填寫鏈接就可以查看了)
如果你是IE的話直接F12就可以了
打開源碼之后我們按快捷鍵Ctrl+F鍵打開快速搜索殴穴,在此時同樣打開我們在此前圖片頁面打開的F12調(diào)試工具,且找到屬于圖片集內(nèi)圖片的鏈接
如圖货葬,然后復(fù)制圖片鏈接采幌,再次切換到源碼查頁在剛剛打開的Ctrl+F的搜索框中填入圖片地址
然后我們就找到所搜的圖片集了,然后我們就可以在Pycharm寫這一部分的代碼:
def Download(url): # 下載網(wǎng)頁
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}#這里主要是進行簡單的協(xié)議頭偽裝
try:
return requests.get(url, headers=head,timeout=60)
#使用requests模塊進行訪問第一個參數(shù)是鏈接震桶,第二個是協(xié)議頭休傍,第三個是超時時間!
except (Exception, AttributeError) as a:
print(a)
這里我們首先定義一個HTTP訪問下載然后我們先寫一段正則
<img id="image\d+" class="multi-photo-image" src="([a-zA-z]+://[^\s]*)" alt="">
在后續(xù)我測試的時候蹲姐,在匹配圖片的時候我發(fā)現(xiàn)圖蟲網(wǎng)有兩種圖片顯示方式所以我寫的這個代碼是兩個不同的正則磨取,當然如果你使用我們上面所找找到的img_id進行拼接的話就不用有下面的步驟了代碼:
def Picturenoe(title,url,page,type):#用正則匹配圖片鏈接
#第一個參數(shù)是后續(xù)獲取到的圖片記得名稱人柿,用做創(chuàng)建文件夾的名字,
#第二個參數(shù)是我們傳入圖片集的地址例如https://tuchong.com/2602198/15653079
#第三個參數(shù)是后為了直觀輸出的現(xiàn)在正在爬取第幾頁
#第四個參數(shù)就是判斷我們究竟該用那種方式進行匹配
if type == 1:
html = Download(url).text
path = list(set(re.findall('<img id="image\d+" class="multi-photo-image" src="([a-zA-z]+://[^\s]*)" alt="">',html)))
#我們第一種圖片的正則匹配就是上面的type == 1的
elif type == 2:
html = Download(url).text
path = list(set(re.findall('<img src="([a-zA-z]+://[^\s]*)" alt="\d+.[a-z]+" />', html)))
Save(path,title,page)#這里的這個函數(shù)是后續(xù)寫的圖片下載保存
#第二種才是上文的
第二種圖片獲取
那么我們在上文中提到了圖片的兩種顯示方式寝衫,那么下面我們就講解第二種的獲取
同上我還是查看源碼并且我們需要打開F12調(diào)試工具并且點擊左上角第一個圖標
點擊之后我們再次點擊頁面中的圖片我們會跳轉(zhuǎn)到圖片的代碼處
我們復(fù)制圖片鏈接接下來與第一種圖片獲取的查找一樣打開搜索框搜索到圖片搜之后復(fù)制改寫為正則語句
'<img src="([a-zA-z]+://[^\s]*)" alt="\d+.[a-z]+" />
如果有不會正則的推薦正則表達式30分鐘入門教程
我們講到這里圖片的獲取就講完了顷扩,那么兩種圖片的獲取有什么不同呢?
1慰毅、先看瀏覽器顯示的效果
1.1圖片集
1.2文字加圖片
這是可以看到的區(qū)別那么他們主要的區(qū)別就是鏈接
圖片集:https://tuchong.com/2602198/15653079/
文字圖片混合排版:https://tuchong.com/1535376/t/15563899/
在鏈接中可以很清晰的看到在后者多了一個/t/那么在我們后續(xù)的代碼中就可以這么判斷二者:
def DownloadIf(url,title,page):
if url.find("/t/") != -1:#如果沒有找到就會返回-1
Picturenoe(title,url,page,2)#這里的函數(shù)是調(diào)用我們上面的正則匹配的內(nèi)個方法
else:
Picturenoe(title,url,page,1)
至此我們的圖片鏈接獲取就結(jié)束了汹胃,開始我們下面的圖片集鏈接的獲茸偶ⅰ宰掉!
圖片集鏈接的獲取
1轨奄、分析&抓包
1.1我在頁面并沒有找到底部有頁數(shù)那么我們就可以向下啦當我們拉倒底部的時候挪拟,我們會看到有一個加載更多击你,由此我們就知道他是動態(tài)獲取的所以我們就可以打開F12再次選擇Network開始抓包
點擊完加載更多之后我們會發(fā)現(xiàn)第一個數(shù)據(jù)包是帶有json的所以我們查看他的數(shù)據(jù)
在查看后我們會發(fā)現(xiàn)postlist這個節(jié)點有我們先要的數(shù)據(jù)鏈接
然后我們分析數(shù)據(jù)鏈接https://tuchong.com/rest/tags/%E7%BE%8E%E5%A5%B3/posts?page=5&count=20&order=weekly
第一個參數(shù)其實是編碼了的%E7%BE%8E%E5%A5%B3
它解碼之后就是美女也就是我們最開始選擇的標簽
第二個是page從單詞可疑看出他是頁的意思,也就是現(xiàn)在你要獲取第幾頁
第三就是count每頁需要獲取多少個石景,一般為默認
def Picturegroup(name,num):#獲取第X頁的列表
url = "https://tuchong.com/rest/tags/%(name)s/posts?page=%(num)s&count=20&order=weekly" % {'name':name,"num":str(num)}
html = Download(url)
if html:
return json.loads(html.text)#用json模塊解析并且返回一個解析好的json模塊
圖片集獲取完
標簽的獲取
標簽的獲取其實很簡單直接訪問https://tuchong.com/explore/
在源碼中找到標簽的代碼
<span class="tag-title">風(fēng)光</span>
用正則改寫
<span class="tag-title">([\u4e00-\u9fa5]+)</span>
代碼:
def Thelabel():#獲取開始的標簽菜單
url = "https://tuchong.com/explore/"
html = Download(url).text
return re.findall('<span class="tag-title">([\u4e00-\u9fa5]+)</span>',html)#匹配之后返回一個標簽的列表
在這個大概就完成了應(yīng)為是圖文教程所以沒辦法講的很詳細
PS:這也是我第一次寫文章可能有點啰嗦
附上代碼:
# -*- coding:utf-8 -*-
'''
By:xiaojing
Time:2017-11-1
Blog:www.ceo404.com
'''
import requests
import re
import urllib.parse
import json
import traceback
import os
def Download(url): # 下載網(wǎng)頁
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}
try:
return requests.get(url, headers=head,timeout=60)
except (Exception, AttributeError) as a:
print(a)
def Thelabel():#獲取開始的標簽菜單
url = "https://tuchong.com/explore/"
html = Download(url).text
return re.findall('<span class="tag-title">([\u4e00-\u9fa5]+)</span>',html)
def Picturegroup(name,num):#獲取第X頁的列表
url = "https://tuchong.com/rest/tags/%(name)s/posts?page=%(num)s&count=20&order=weekly" % {'name':name,"num":str(num)}
print(url)
html = Download(url)
if html:
return json.loads(html.text)
def Save(url_list,title,page):#下載保存
title_naem = os.path.join("picture",title)#要將圖片保存到那個文件夾
if not os.path.exists(title_naem):
try:
os.makedirs(title_naem)
num = 0
countfile = 0
countdir = 0
for url in url_list:
num += 1
path_name_split = url.split("/")
suffix = ".%s"%path_name_split[-1].split(".")[-1]
path_name = os.path.join("picture",os.path.join(title,"%s(%d)%s"%(title,num,suffix)))
#print(path_name)
#path_name = os.path.join("圖蟲網(wǎng)爬蟲",path_name)
if not os.path.exists(path_name.encode()):
response = Download(url)
if requests:
with open(path_name,"wb") as f:
f.write(response.content)
f.close()
countfile += 1
print("正在下載:%s 標題:%s 共%d張/現(xiàn)%d張"%(page,title,num,len(url_list)),"當前進度文件夾進度{0:.2f}%".format(countfile * 100 / len(url_list)))
print("%s下載完畢!" % title)
except:#輸出錯誤的類型以及詳細
print(traceback.print_exc())
def Picturenoe(title,url,page,type):#用正則匹配圖片鏈接
if type == 1:
html = Download(url).text
path = list(set(re.findall('<img id="image\d+" class="multi-photo-image" src="([a-zA-z]+://[^\s]*)" alt="">',html)))
elif type == 2:
html = Download(url).text
path = list(set(re.findall('<img src="([a-zA-z]+://[^\s]*)" alt="\d+.[a-z]+" />', html)))
Save(path,title,page)
#print("開始下載:%s共:%d個" % (title, len(path)))
def DownloadIf(url,title,page):
if url.find("/t/") != -1:
Picturenoe(title,url,page,2)
else:
Picturenoe(title,url,page,1)
def strip(path):#刪除Windows文件創(chuàng)建時不允許出現(xiàn)的字符
return re.sub(r'[? .\\*|"<>,:/]',"",str(path))
def initial(name,num):#總程序
for i in range(1,num+1):
print(i)
img_info = Picturegroup(name,i)
number = 0
print("開始下載第%d頁共:%d套" % (i,len(img_info['postList'])))
for img_info_temp in img_info['postList']:
img_info_url = img_info_temp['url']
img_info_post_id = img_info_temp['post_id']
img_info_title = strip(img_info_temp['title']).strip()
if img_info_title =="":
img_info_title = img_info_post_id
number += 1
DownloadIf(img_info_url,img_info_title,"下載第%d頁共:共%d套/現(xiàn)%d套" % (i,len(img_info['postList']),number))
print("全部下載完畢共:%d頁,%d套怠堪!"%(number,len(img_info['postList'])))
if __name__ == '__main__':
if not os.path.exists("picture"):
os.makedirs("picture")
print("偷偷創(chuàng)建了:picture 文件夾")
label = Thelabel()#獲取動態(tài)標簽
print("標簽:",label,"更多標簽請前往https://tuchong.com/explore/查詢")
name = urllib.parse.quote(input("請輸入標簽名字:"))
number = int(input("請輸入要爬取的頁數(shù):"))
initial(name,number)