[Artículos de bienestar] Python crawl girl map

Consejo: Este artículo es solo para aprendizaje y referencia, espero que cuides tu cuerpo (divertido manualmente) ~

Comienza una foto

Inserte la descripción de la imagen aquíPD: ¿Quién sabe que hay una herramienta de edición de video que es más fácil de usar sin una marca de agua, y espero recomendarla ~

Dididi ~~~
Hablando de Mzitu , presumiblemente el viejo conductor debería conocer el pozo , ya que solo estaba avergonzado de la existencia de él hace dos días, ¡estoy avergonzado! Los reptiles que lo rodean también son interminables, interminables y menguantes. La marea cae ... volviendo al tema, aquí principalmente quiero compartir con ustedes mi plan.

1. Versión de un solo hilo

El rastreo de Mzitu debe ser relativamente básico, ya que no hay muchos mecanismos contra la escalada involucrados. Según la situación actual, hay dos puntos principales:

  • Parámetro de referencia en los encabezados : la solución también es muy simple. Solo necesita agregar este parámetro al encabezado de la solicitud y no necesita cambiar dinámicamente. Se puede corregir como la dirección de la página de inicio.
  • Solicitar límite de velocidad : en el proceso de rastreo real, descubriremos que si la velocidad de rastreo es demasiado rápida, la IP a menudo se bloqueará, y aquí solo tenemos que limitar adecuadamente la velocidad o unirnos al grupo proxy.

Análisis de rastreadores específicos, una búsqueda aleatoria en Internet es un montón, proporcionaré directamente el código aquí:

# =============================================================================
# Mzitu图片爬取
# =============================================================================
import re
import os
import time
import queue
import requests
from tqdm import tqdm
from termcolor import *
from colorama import init

# 解决CMD无法显示颜色问题
init(autoreset=False)
    
class spider_Mzidu():
    def __init__(self):
        # 定义请求地址
        self.url_page = 'https://www.mzitu.com/page/%d/' # 搜索套图页面(用以获取套图ID)
        self.url_taotu = 'https://www.mzitu.com/%s'      # 套图页面(用以获取图片地址)
        
        # 定义请求头
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0',
                        'Accept': '*/*',
                        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                        'Accept-Encoding': 'gzip, deflate, br',
                        'X-Requested-With': 'XMLHttpRequest',
                        'Connection': 'keep-alive',
                        'Referer': 'https://www.mzitu.com',
                       }
        
        # 定义正则表达式
        self.p_id = '<span><a href="https://www.mzitu.com/(\d*?)" target="_blank">(.*?)</a></span>'
        self.p_imgurl = '"main-image">.*?<img src="(.*?)"'
        self.p_page = '…</span>.*?<span>(\d*?)</span>'
        
        # 存储变量
        self.queue_id = queue.Queue()
        
    def getPages(self): # 获取总页数
        res = requests.get(self.url_page%1,headers=self.headers)
        html = res.text
        N = re.findall('''class="page-numbers dots">[\s\S]*?>(\d*?)</a>[\s\S]*?"next page-numbers"''',html)[0]
        return int(N)
        
    def getID(self): # 获取套图ID
        page_range = input('请输入爬取页数(如1-10):')
        p_s = int(page_range.split('-')[0])
        p_e = int(page_range.split('-')[1])
        time.sleep(0.5)
        print(colored('开始获取套图ID'.center(50,'-'),'green'))
        bar = tqdm(range(p_s,p_e+1),ncols=60) # 进度条
        for p in bar:
            res = requests.get(self.url_page%p,headers=self.headers)
            html = res.text
            ids = re.findall(self.p_id,html)
            for i in ids:
                self.queue_id.put(i)
            bar.set_description('第%d页'%p)
    
    def downloadImg(self,imgurl): # 下载图片
        res = requests.get(imgurl,headers=self.headers)
        img = res.content
        return img

    def parseTaotu(self,taotuID): # 解析套图的"图片数量",以及"图片地址"
        res = requests.get(self.url_taotu%taotuID,headers=self.headers)
        html = res.text
        page = int(re.findall(self.p_page,html)[0])
        imgurl = re.findall(self.p_imgurl,html)[0]
        imgurl = imgurl[:-6]+'%s'+imgurl[-4:]
        return(imgurl,page)
    
    def downloadTaotu(self): # 下载套图 
        while not self.queue_id.empty():
            taotu = self.queue_id.get()
            taotuID = taotu[0]
            taotuName = taotu[1]
            try:
                imgurl,page = self.parseTaotu(taotuID)
                path = '[P%d]'%page+taotuName
                if not os.path.exists(path):
                    os.mkdir(path)
                bar = tqdm(range(1,page+1),ncols=50) # 进度条
                for i in bar:
                    url = imgurl%(str(i).zfill(2))
                    img = self.downloadImg(url)
                    with open('./%s/%d.jpg'%(path,i),'wb') as f:
                        f.write(img)
                print('套图("'+colored(taotuName,'red')+'")爬取完成')
            except:
                time.sleep(3)
                self.queue_id.put(taotu)
        
    def run(self): # 主程序
        os.system('cls')  # 清空控制台
        print('*'*35)
        print('*'+'欢迎使用Mzitu下载器'.center(26)+'*')
        print('*'*35)
        N = self.getPages()
        print(('Mzitu当前共有%s页!'%colored(N,'red')).center(30))
        print('\n')
        self.getID()
        print('\n'+colored('开始爬取套图'.center(50,'-'),'green'))
        self.downloadTaotu()
            
spider = spider_Mzidu()
spider.run()

En segundo lugar, la versión multiproceso.

Es posible que algunos amigos tengan que preguntar: "¿Un solo hilo es tan lento? ¿Estás bromeando, no puedo contenerme?"
Invitado oficial, prueba la versión multiproceso:

# =============================================================================
# Mzitu图片爬取(多线程)
# =============================================================================
import re
import os
import time
import queue
import requests
import threading
from tqdm import tqdm
from termcolor import *
from colorama import init

# 解决CMD无法显示颜色问题
init(autoreset=False)

# 代理(XXX代理)
def Get_proxy():
    res = requests.get('xxxxxxxxxxxxxxxxxxx')
    html = res.text
    return html
    
class spider_Mzidu():
    def __init__(self):
        # 定义请求地址
        self.url_page = 'https://www.mzitu.com/page/%d/' # 搜索套图页面(用以获取套图ID)
        self.url_taotu = 'https://www.mzitu.com/%s'      # 套图页面(用以获取图片地址)
        
        # 定义请求头
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0',
                        'Accept': '*/*',
                        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                        'Accept-Encoding': 'gzip, deflate, br',
                        'X-Requested-With': 'XMLHttpRequest',
                        'Connection': 'keep-alive',
                        'Referer': 'https://www.mzitu.com',
                       }
        
        # 定义正则表达式
        self.p_id = '<span><a href="https://www.mzitu.com/(\d*?)" target="_blank">(.*?)</a></span>'
        self.p_imgurl = '"main-image">.*?<img src="(.*?)"'
        self.p_page = '…</span>.*?<span>(\d*?)</span>'
        
        # 存储变量
        self.queue_id = queue.Queue()
        
        #HTTP代理
        proxy = Get_proxy()
        self.proxies = {'http':'http://'+proxy,
                        'https':'https://'+proxy} 
        
    def getPages(self): # 获取总页数
        res = requests.get(self.url_page%1,headers=self.headers,proxies=self.proxies,timeout=10)
        html = res.text
        N = re.findall('''class="page-numbers dots">[\s\S]*?>(\d*?)</a>[\s\S]*?"next page-numbers"''',html)[0]
        return int(N)
        
    def getID(self): # 获取套图ID
        page_range = input('请输入爬取页数(如1-10):')
        p_s = int(page_range.split('-')[0])
        p_e = int(page_range.split('-')[1])
        time.sleep(0.5)
        print(colored('开始获取套图ID'.center(50,'-'),'green'))
        bar = tqdm(range(p_s,p_e+1),ncols=60) # 进度条
        for p in bar:
            res = requests.get(self.url_page%p,headers=self.headers,proxies=self.proxies,timeout=10)
            html = res.text
            ids = re.findall(self.p_id,html)
            for i in ids:
                self.queue_id.put(i)
            bar.set_description('第%d页'%p)
    
    def downloadImg(self,imgurl,proxies): # 下载图片
        res = requests.get(imgurl,headers=self.headers,proxies=proxies,timeout=10)
        img = res.content
        return img

    def parseTaotu(self,taotuID,proxies): # 解析套图的"图片数量",以及"图片地址"
        res = requests.get(self.url_taotu%taotuID,headers=self.headers,proxies=proxies,timeout=10)
        html = res.text
        page = int(re.findall(self.p_page,html)[0])
        imgurl = re.findall(self.p_imgurl,html)[0]
        imgurl = imgurl[:-6]+'%s'+imgurl[-4:]
        return(imgurl,page)
    
    def downloadTaotu(self): # 下载套图 
        proxy = Get_proxy()
        proxies = {'http':'http://'+proxy,
                   'https':'https://'+proxy} 
        while not self.queue_id.empty():
            taotu = self.queue_id.get()
            taotuID = taotu[0]
            taotuName = taotu[1]
            try:
                imgurl,page = self.parseTaotu(taotuID,proxies)
                path = '[P%d]'%page+taotuName
                if not os.path.exists(path):
                    os.mkdir(path)
                bar = tqdm(range(1,page+1),ncols=50) # 进度条
                for i in bar:
                    url = imgurl%(str(i).zfill(2))
                    img = self.downloadImg(url,proxies)
                    with open('./%s/%d.jpg'%(path,i),'wb') as f:
                        f.write(img)
                print('套图("'+colored(taotuName,'red')+'")爬取完成')
            except:
                time.sleep(3)
                proxy = Get_proxy()
                proxies = {'http':'http://'+proxy,
                           'https':'https://'+proxy} 
                self.queue_id.put(taotu)
                
    def changeProxy(self): # 更换代理
        proxy = Get_proxy()
        self.proxies = {'http':'http://'+proxy,
                        'https':'https://'+proxy} 
        
    def run(self): # 主程序
        os.system('cls')  # 清空控制台
        print('*'*35)
        print('*'+'欢迎使用Mzitu下载器'.center(26)+'*')
        print('*'*35)
        N = self.getPages()
        print(('Mzitu当前共有%s页!'%colored(N,'red')).center(30))
        print('\n')
        self.getID()
        print('\n'+colored('开始爬取套图'.center(50,'-'),'green'))
        # 多线程下载套图
        N_thread = 3
        thread_list = []
        for i in range(N_thread):
            thread_list.append(threading.Thread(target=self.downloadTaotu))
        for t in thread_list:
            t.start()
        for t in thread_list:
            t.join()
            
spider = spider_Mzidu()
spider.run()

Debe descubrirse con cuidado, de hecho, casi no hay diferencia en la estructura entre la versión de subprocesos múltiples y la versión de subprocesos únicos ( aquí también se proporciona una idea de código, lo que lo hace más conveniente si queremos cambiar el código original a subprocesos múltiples más adelante). Rápido ), principalmente estos dos puntos:

  • Cuando llame a la función downloadTaotu (), use el módulo de subprocesos para habilitar varias llamadas multiproceso.
  • Módulo proxy HTTP agregado . Aquí puede considerar si desea mantenerlo a su discreción, pero de acuerdo con mi prueba, si usa subprocesos múltiples, se recomienda que aún se una al proxy, de lo contrario, la IP podría bloquearse.

Escribe al final

Si está interesado en la barra de progreso en el código o en el color del texto de salida , para hacer que la salida de su código sea más coqueta, puede consultar aquí. ( Salida de color frío de Python e impresión de barra de progreso )

Si hay deficiencias en el texto, ¡espero que critiquen y corrijan!
Finalmente, gracias por su paciencia para leer ~

5 artículos originales publicados · Me gusta 39 · Visitas 30,000+

Supongo que te gusta

Origin blog.csdn.net/kimol_justdo/article/details/105515579
Recomendado
Clasificación