zoukankan      html  css  js  c++  java
  • python3爬取女神图片,破解盗链问题


    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?

  • 相关阅读:
    VS2015生成64位dll文件
    gdb简单调试~core文件
    Ubuntu ENet 的下载和编译
    Android LIstView初次创建getview方法执行多次问题
    android ipc通信机制之之三,进程通讯方式。
    Android Stduio统计项目的代码行数
    Android开发遇到的坑(1):Java中List的安全删除问题
    Android Studio修改项目的包名
    类似IOS的滑动返回上一级,SwipeBackLayout-android的滑动返回类库
    [转]理解RESTful架构
  • 原文地址:https://www.cnblogs.com/yaomaomao/p/8905977.html
Copyright © 2011-2022 走看看