1. 程式人生 > >python3爬取女神圖片,破解盜鏈問題

python3爬取女神圖片,破解盜鏈問題

什麽 agen lock 基本 avi rt thread agent 使用 icm


title: python3爬取女神圖片,破解盜鏈問題

date: 2018-04-22 08:26:00

tags: [python3,美女,圖片抓取,爬蟲, 盜鏈]

comments: true

前言

其實,抓取圖片和抓取小說內容沒有任何本質的區別,步驟都是一樣的。

但是圖片讀取的時候,會遇到一個盜鏈問題。這個問題是花的解決時間最長的。

環境

語言: python3

操作系統: mac 10.12.16

自定義工具包:soup_tool

其依賴工具如下:

from urllib import request
from urllib.parse import quote
from bs4 import BeautifulSoup
import os
import threading
import re
import ssl

version 0.1 單個網址鏈接抓取所有特定圖片

抓取分析

首先打開單個美女圖片集
https://www.nvshens.com/g/24816
技術分享圖片

可以看到我標註的

使用chrome的檢查功能,可以看到當前頁有3張我們想要的圖片

其中,可以以第二張圖片的格式作為模板

只要替換001直到002、003、……、044

再找下圖片總共有多少張,看我標註的count就可以了

這樣就可以不用分頁去抓取了。

至此,基本分析完畢,開始動手吧

動手實戰

因為之前爬取小說網站的積累,寫了一個工具類,主要就是用了request請求鏈接,BeautifulSoup解析網頁,ssl解決https問題

工具類代碼不一一貼出來了,最後會給個本項目github的地址

1.首先是初始化,建立class

class Capture:

引用自定義工具類

from soup_tool import Soup

from soup_tool import MyThread

然後定義初始化的一些參數

def __init__(self):
    self.index_page_url = ‘http://www.nvshens.com‘
    # 作品內容主頁
    self.one_page_url = ‘https://www.nvshens.com/g/:key/‘
    # root folder
    self.folder_path = ‘nvshens/‘
    # 每個線程的沈睡時間
    self.sleep_time = 2
    # 後綴
    self.file_hz = ‘.img‘

2.根據key來檢索分析圖集主頁

接著,我們得將本網頁的獲取做成動態的,將網址

https://www.nvshens.com/g/24816

中的24816作為搜索key

定義一個方法 readPageFromSearch

def readPageFromSearch(self, search_key):
    """
    根據輸入key讀取搜索頁面
    :param search_key:
    :return:
    """   

方法裏,第一個事,先建立個根目錄

     # 創建文件夾 /nvshens/search_key
    path = self.folder_path + search_key
    Soup.create_folder(path)   

然後打開美女圖集第一頁,使用soup解析

     # 打開搜索頁面第1頁
    page_url = self.one_page_url.replace(‘:key‘, search_key)
    print(page_url)
    soup_html = Soup.get_soup(page_url)
    

從soup中取到id是dinfo的div,然後找到裏面的span,獲取其中的文本,再處理掉“張照片”幾個字,得到最大圖片張數

    text_page = soup_html.find("div", {‘id‘: ‘dinfo‘}).find(‘span‘).get_text()
    print(‘text_page‘, text_page)
    last = text_page.replace(‘張照片‘, ‘‘)
    item_size = int(last)      

再接著,我們要找到模板,但是第一張照片也不能不管,所以先從第一張獲取,我們先看下規律

   # 第1張 
   https://img.onvshen.com:85/gallery/25366/24816/0.jpg
   # 第2張
   https://img.onvshen.com:85/gallery/25366/24816/001.jpg
   # 第3張
   ttps://img.onvshen.com:85/gallery/25366/24816/002.jpg

這樣,我們應該就知道怎麽辦了,取到第一張後,使用soup的find_next_sibling方法獲取下一個標簽節點

    # 第1張圖片
    image_one = soup_html.find("ul", {‘id‘: ‘hgallery‘}).find(‘img‘)
    image_one_url = image_one.get(‘src‘)
    print(‘image_one_url‘, image_one_url)

    # 第2張圖片鏈接作為模版
    image_two = image_one.find_next_sibling()
    image_two_url = image_two.get(‘src‘)
    print(‘image_two_url‘, image_two_url)

然後,根據第二章的url,首先用"/"分割,取最右一組數,得到“24816/001.jpg”,在用"."分割,獲取後綴,知道是jpg還是png

    # https://img.onvshen.com:85/gallery/25366/24816/001.jpg 
    # 24816/001.jpg
    img_hz = image_two_url.split("/")[-1]
    # jpg
    file_hz = img_hz.split(‘.‘)[1]
    # https://img.onvshen.com:85/gallery/25366
    img_mod_url = image_two_url.replace(img_hz, ‘‘)
    

3.多線程讀取圖片鏈接

定義readPageByThread 方法
將前面的

  • 最大圖片數 item_size
  • 文件存放目錄 path
  • 模板url img_mod_url
  • 文件後綴 file_hz

全部作為參數傳進來

# 多線程讀取,每個圖片下載都是一個線程
def readPageByThread(self, item_size, path, img_mod_url, file_hz):
    """
    :param item_size: 最大圖片數
    :param path: 文件存放目錄
    :param img_mod_url: 模板url 
    :param file_hz: 文件後綴 
    :return:
    """
    

循環 item_size,使用zfill方法左側補零

    # 循環打開圖片鏈接
    for item in range(1, item_size):
        # 左側補零 1->001,2->002,……,114->114
        page = str(item + 1).zfill(3)
        new_page_url = img_mod_url + page + ‘.‘ + file_hz
        new_path = path + ‘/‘ + page + ‘.‘ + file_hz
        print(new_path, ‘---‘, new_page_url)  
        

使用自定義的多線程方法,將本次線程收集起來,參數傳進 readPagetoTxt 方法中

        t = MyThread(self.readPagetoTxt, (new_page_url, new_path, self.sleep_time), self.readPagetoTxt.__name__)
        threads.append(t)
        

開啟線程,並join阻塞

    for t in threads:
        t.start()
    for t in threads:
        t.join()

    print(‘all end‘, ctime())

4.讀取圖片內容並寫入

這是本次圖片抓取的重點了,在晚上搜索了很多內容,找到以下方法

urllib.request.urlretrieve

親測,對於破解盜鏈沒有任何作用

那麽,真正的破盜鏈怎麽搞呢?搜到了一個哥們的文章

go語言 grequests+goquery 簡單爬蟲,使用多協程並發爬取

其中有一段代碼是這樣的

  Headers:map[string]string{  
                            "Referer":"http://www.zngirls.com",  
                            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"}})  
                            

這heads不只設置了User-Agent,還有Referer,艾?這是啥?我試試

將Referer設置為咱們的index_page_url(http://www.nvshens.com),果然可以了。為什麽呢?

原來Referer表示一個來源,代表是從哪個網站請求web服務器的,我們將Referer設置為http://www.nvshens.com,代表的其實是從它自身網站請求訪問的。

具體請參考這個哥們的文章什麽是HTTP Referer?

當然,這也主要是這個網站的開發人員只用了Referer來作為防盜鏈的判斷,如果不是Referer而是換成別的,那就又要重新破解了。

好了,寫我們的代碼吧,為head添加個Referer的屬性,這Soup_tool類中

_HEAD2 = {
    # Referer 抓取哪個網站的圖片,添加此頭部,可以破解盜鏈
    "Referer": "",
    ‘Accept-language‘: ‘zh-CN,zh;q=0.9‘
    ,
    ‘User-Agent‘: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36‘
}

@staticmethod
def open_url(query_url, referer=‘‘):
    Soup._HEAD2[‘Referer‘] = referer
    req = request.Request(quote(query_url, safe=‘/:?=‘), headers=Soup._HEAD2)
    webpage = request.urlopen(req)
    html = webpage.read()
    return html
    
@staticmethod
def write_img(query_url, file_name, referer):
    content = Soup.open_url(query_url, referer)
    with open(file_name, ‘wb‘) as f:
        f.write(content)

回到我們的Capture類:

    # 使用Request添加頭部的方法,讀取圖片鏈接再寫入,最重要的是加上Referer
    Soup.write_img(page_url, path, referer=self.index_page_url) 

後記

還有v0.2、v0.3版本

這是v0.2的分析截圖

https://www.nvshens.com/gallery/

https://www.nvshens.com/gallery/dudou/
技術分享圖片

技術分享圖片

分析思路是一樣的,就不再細說了,自己看源碼

看下下載後呈現的效果
技術分享圖片

技術分享圖片

最後放出代碼鏈接

github

https://github.com/kiok1210/nvshens_img

參考文獻:

go語言 grequests+goquery 簡單爬蟲,使用多協程並發爬取

什麽是HTTP Referer?

python3爬取女神圖片,破解盜鏈問題