Python 爬取圖蟲網圖片

關于&說明

這是我的第一個正式的爬蟲

個人感覺圖蟲網的圖片還是不錯的,關鍵是小姐姐的圖片多https://tuchong.com/tags/%E7%BE%8E%E5%A5%B3/

此爬蟲只作為學習交流,如有侵犯請告知作者,刪除!、

網站的爬取還是非常簡單的沒有模擬登陸,驗證碼,加密什么的個人感覺很簡單

準備

開發環境&工具:Python3 ,Pycharm

需要用到的模塊 re,requests,os,json,urllib.parse,traceback

分析

進入官網我們選擇發現-->標簽然后會看到很多的類型

標簽.jpg

我們先隨意選擇一個,這里我就選擇美女這個標簽吧!(小姐姐)

進去之后我們會發現有很多的圖片集

美女.jpg

如何獲取圖片

第一種圖片獲取

然后我們點擊一個圖片集,查看并且打開F12調試工具選擇Network選項進行抓包,注意F12調試工具不要關閉后續有用!

然后我在抓包數據中并沒有找到準確的圖片地址,但是可以從一下數據鏈接中找到圖片的img_id(PS:img_id就是圖片的標識例如https://photo.tuchong.com/1535376標識(這里是圖片集的)/l/18389913(這里就是圖片的標識了).jpg)我們在這里就不用這個了如果想用自行嘗試,附上此數據鏈接地址 https://tuchong.com/rest/posts/15653079(后面的數字是本圖片集的標識后續會講到)

image

現在我們再去源碼中找一下,應為網站js限制所以無法右擊查看源碼,請看下面講解

PS:
如果你是谷歌內核的瀏覽器需要打開一個新標簽且輸入view-source:(這里填寫鏈接就可以查看了)
如果你是IE的話直接F12就可以了
打開源碼之后我們按快捷鍵Ctrl+F鍵打開快速搜索,在此時同樣打開我們在此前圖片頁面打開的F12調試工具,且找到屬于圖片集內圖片的鏈接

image

如圖,然后復制圖片鏈接,再次切換到源碼查頁在剛剛打開的Ctrl+F的搜索框中填入圖片地址

搜搜.png

然后我們就找到所搜的圖片集了,然后我們就可以在Pycharm寫這一部分的代碼:

def Download(url):  # 下載網頁
    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)
        #使用requests模塊進行訪問第一個參數是鏈接,第二個是協議頭,第三個是超時時間!

    except (Exception, AttributeError) as a:
        print(a)

這里我們首先定義一個HTTP訪問下載然后我們先寫一段正則

<img id="image\d+" class="multi-photo-image" src="([a-zA-z]+://[^\s]*)" alt="">

在后續我測試的時候,在匹配圖片的時候我發現圖蟲網有兩種圖片顯示方式所以我寫的這個代碼是兩個不同的正則,當然如果你使用我們上面所找找到的img_id進行拼接的話就不用有下面的步驟了代碼:

def Picturenoe(title,url,page,type):#用正則匹配圖片鏈接
#第一個參數是后續獲取到的圖片記得名稱,用做創建文件夾的名字,
#第二個參數是我們傳入圖片集的地址例如https://tuchong.com/2602198/15653079
#第三個參數是后為了直觀輸出的現在正在爬取第幾頁
#第四個參數就是判斷我們究竟該用那種方式進行匹配
    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)#這里的這個函數是后續寫的圖片下載保存
#第二種才是上文的

第二種圖片獲取

那么我們在上文中提到了圖片的兩種顯示方式,那么下面我們就講解第二種的獲取
同上我還是查看源碼并且我們需要打開F12調試工具并且點擊左上角第一個圖標



點擊之后我們再次點擊頁面中的圖片我們會跳轉到圖片的代碼處


示范.gif


我們復制圖片鏈接接下來與第一種圖片獲取的查找一樣打開搜索框搜索到圖片搜之后復制改寫為正則語句
'<img src="([a-zA-z]+://[^\s]*)" alt="\d+.[a-z]+" />

如果有不會正則的推薦正則表達式30分鐘入門教程
我們講到這里圖片的獲取就講完了,那么兩種圖片的獲取有什么不同呢?
1、先看瀏覽器顯示的效果
1.1圖片集

樣式.jpg

1.2文字加圖片
樣式二.jpg

這是可以看到的區別那么他們主要的區別就是鏈接
圖片集:https://tuchong.com/2602198/15653079/
文字圖片混合排版:https://tuchong.com/1535376/t/15563899/
在鏈接中可以很清晰的看到在后者多了一個/t/那么在我們后續的代碼中就可以這么判斷二者:

def DownloadIf(url,title,page):
    if url.find("/t/") != -1:#如果沒有找到就會返回-1
        Picturenoe(title,url,page,2)#這里的函數是調用我們上面的正則匹配的內個方法
    else:
        Picturenoe(title,url,page,1)

至此我們的圖片鏈接獲取就結束了,開始我們下面的圖片集鏈接的獲取!

圖片集鏈接的獲取

1、分析&抓包

1.1我在頁面并沒有找到底部有頁數那么我們就可以向下啦當我們拉倒底部的時候,我們會看到有一個加載更多,由此我們就知道他是動態獲取的所以我們就可以打開F12再次選擇Network開始抓包


點擊完加載更多之后我們會發現第一個數據包是帶有json的所以我們查看他的數據
頁數.jpg

在查看后我們會發現postlist這個節點有我們先要的數據鏈接
節點.png

然后我們分析數據鏈接https://tuchong.com/rest/tags/%E7%BE%8E%E5%A5%B3/posts?page=5&count=20&order=weekly
第一個參數其實是編碼了的%E7%BE%8E%E5%A5%B3
它解碼之后就是美女也就是我們最開始選擇的標簽
第二個是page從單詞可疑看出他是頁的意思,也就是現在你要獲取第幾頁
第三就是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">風光</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)#匹配之后返回一個標簽的列表

在這個大概就完成了應為是圖文教程所以沒辦法講的很詳細
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):  # 下載網頁
    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("圖蟲網爬蟲",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張/現%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文件創建時不允許出現的字符
    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套/現%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("偷偷創建了:picture 文件夾")
    label = Thelabel()#獲取動態標簽
    print("標簽:",label,"更多標簽請前往https://tuchong.com/explore/查詢")
    name = urllib.parse.quote(input("請輸入標簽名字:"))
    number = int(input("請輸入要爬取的頁數:"))
    initial(name,number)

演示一.jpg

演示二.jpg

演示四.jpg

演示五.jpg

演示六.jpg

搞笑

完2017年11月10日寫

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,269評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,229評論 4 61
  • SCN System Change Number. A database ordering primitive. ...
    只有香如故閱讀 2,707評論 0 1
  • 陳小米 我是小小,不知道幾歲了,你去問問我媽媽吧。因為我還很小,我還沒有學會數數。我有一座小小的花園,那是爸爸在我...
    小米rt8閱讀 346評論 4 2
  • 看見有趣的東西總想分享給你,身邊大大小小的事情都想告訴你,此起彼伏的情緒都想你知道。 為什么呢? 為什么總是想跟你...
    賤賤小姐閱讀 110評論 0 0