利用redis数据库管理代理库爬取cosplay网站-cnblog

news2025/1/13 10:09:51

爬取cos猎人

数据库管理主要分为4个模块,代理获取模块,代理储存模块,代理测试模块,爬取模块

image-20240704075525606

cos猎人已经倒闭,所以放出爬虫源码

api.py 为爬虫评分提供接口支持

import requests
import concurrent.futures
import redis
import random
import flask  # 导入flask模块
from flask import request  # 获取url地址中查询参数
from flask import jsonify  # 可以把对象转换为字符串
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379
REDIS_DATABASE = 0
REDISOBJECT = 'proxysss'

"""时间间隔配置"""
GETTER_PROXY = 60*5
VERIFY_PROXY = 60*3

class RedisClient:
    def __init__(self, host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DATABASE):
        self.db = redis.Redis(host=host, port=port, db=db, decode_responses=True)

    def exists(self, proxy):
        """判断传入代理有没有存输到数据库
                有TRUE,没有False
                is比not优先级高"""
        return not self.db.zscore(REDISOBJECT, proxy) is None

    def add(self, proxy, score=10):
        """添加代理到数据库,设置初始分数为10分
        决定是否加入新代理"""
        if not self.exists(proxy):
            return self.db.zadd(REDISOBJECT, {proxy: score})

    def random(self):
        """随机选择一个代理
        尝试获取评分为100分的代理
        获取指定范围的代理
        如果数据库没有代理就提示数据库为空"""
        proxies = self.db.zrangebyscore(REDISOBJECT, 100, 100)
        if len(proxies):
            return random.choice(proxies)
        proxies = self.db.zrangebyscore(REDISOBJECT, 1, 99)
        if len(proxies):
            return random.choice(proxies)
        print("-----数据库为空----")

    def decrease(self, proxy):
        """传入代理如果检测不过关,降低代理分数"""
        self.db.zincrby(REDISOBJECT, -10, proxy)
        score = self.db.zscore(REDISOBJECT, proxy)  # 查询分数
        if score <= 0:
            self.db.zrem(REDISOBJECT, proxy)  # 删除代理

    def max(self, proxy):
        """检测代理可用,就将代理设置最大分数"""
        return self.db.zadd(REDISOBJECT, {proxy: 100})

    def count(self):
        """获取数据库中代理的数量"""
        return self.db.zcard(REDISOBJECT)

    def all(self):
        """获取所有代理,返回列表"""
        proxies = self.db.zrangebyscore(REDISOBJECT,1,100)
        if proxies:
            return proxies
        else:
            print('-----数据库无代理----')

    def count_for_num(self,number):
        """指定数量获取代理,返回一个列表
        """
        all_proxies = self.all()
        proxies = random.sample(all_proxies,k=number)#随机取数据,不重样
        return proxies

def get_proxy():
    return requests.get("http://127.0.0.1:5010/all").json()


def delete_proxy(proxy):
    requests.get("http://127.0.0.1:5010/delete/?proxy={}".format(proxy))









# getHtml()
# def verify_thread_pool():
#     """线程池检测代理
#     1.从数据库中取到所有代理
#     2.用线程池检测代理"""
#     proxies_list = client.all()  # 列表
#     with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
#         for proxy in proxies_list:
#             executor.submit(verify_proxy, proxy)



#
#
# TEST_URL = "https://www.baidu.com/"
# headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'}
#
#
#
#
# def verify_proxy(proxy):
#     """检测代理是否可用"""
#     proxies = {
#         "http": "http://" + proxy,
#         "https": "https://" + proxy
#     }
#     try:
#         response = requests.get(url=TEST_URL, headers=headers, proxies=proxies, timeout=2)
#         if response.status_code in [200, 206, 302]:
#             """#判断请求返回的状态码是否成功
#             请求成功设为100分,调用max
#             请求不成功,将代理降分,调用decrease"""
#             client.max(proxy)
#             print("***代理可用***", proxy)
#         else:
#             client.decrease(proxy)
#             print("--状态码不合法--", proxy)
#     except:
#         """请求超时,表示代理不可用"""
#         client.decrease(proxy)
#         print("===请求超时===")
#
#     # 检测速度太慢,引入多任务,多线程
# def verify_thread_pool():
#         """线程池检测代理
#         1.从数据库中取到所有代理
#         2.用线程池检测代理"""
#         proxies_list = client.all()  # 列表
#         with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
#             for proxy in proxies_list:
#                 executor.submit(verify_proxy, proxy)
#
# if __name__ == '__main__':
#     # proxy = [
#     #     '45.234.63.220:999',
#     #     '60.168.255.69:8060',
#     #     '65.108.27.185:3128',
#     #     '62.162.91.205:3129',
#     #     '37.34.236.15:80'
#     # ]
#     # for pro in proxy:
#     #     verify_proxy(pro)
#     verify_thread_pool()

getter.py从数据库抽取一个代理

import requests
def get_one_proxy():
    return requests.get("http://127.0.0.1:5000/all")
print(get_one_proxy().text)

sever.py搭建本地服务器供调用

import flask  # 导入flask模块
from api import RedisClient
from flask import request  # 获取url地址中查询参数
from flask import jsonify  # 可以把对象转换为字符串

app = flask.Flask(__name__)

client = RedisClient()
@app.route('/')
# 将下面的函数挂载到路由
def index():
    """视图函数:http://demo.spiderpy.cn/get/
    视图函数返回的数据,只能返回字符串类型的数据"""
    return '<h2>欢迎来到代理池</h2>'


@app.route('/get')
def get_proxy():
    """随机获取一个代理,调用数据库random模块"""
    one_proxy = client.random()
    return one_proxy


@app.route('/getcount')
def get_any_proxy():
    """获取指定数量一个代理,调用数据库的 count_for_num()
    拿到查询参数的值
    又可能用户没有传递查询参数,num返回为空"""
    num = request.args.get('num', '')
    if not num:
        """没有获取到查询参数"""
        num = 1
    else:
        num = int(num)

    any_proxy = client.count_for_num(num)
    return jsonify(any_proxy)


@app.route('/getnum')
def get_count_proxy():
    """获取所有代理数量,调用数据库count方法"""
    count_proxy = client.count()
    return f"代理可用的数量为:{count_proxy}个"


@app.route('/getall')
def get_all_proxy():
    """获取所有代理,调用数据库的all()"""
    all_proxy = client.all()
    return jsonify(all_proxy)


if __name__ == '__main__':
    """运行实例化的app对象"""
    app.run()

test_self.py和tests.py对已经储存的代理质量进行检测

记不清哪个效果更好

import time

import requests
from api import RedisClient
clients = RedisClient()
def get_proxy():
    return requests.get("http://127.0.0.1:5000/getall")

a = get_proxy()
a = a.json()
# print(a)
# for b in a:
#     print(b)
# print(type(a))

def getHtml():
    # retry_count = 1
    for proxy in a:
        # print(proxy)
        try:
            html = requests.get('http://www.example.com', proxies={"http": "http://{}".format(proxy)},timeout=4)
            # print(html.text)
            if html.status_code in [200, 206, 302]:
                print(proxy,":可以使用")
                clients.add(proxy)
            # 使用代理访问
        except Exception:
            print("代理不可用", proxy)
            clients.decrease(proxy)
    # 删除代理池中代理
    # delete_proxy(proxy)
while True:
    getHtml()
    time.sleep(60*2)

进程池爬取cos猎人.py 主爬虫代码

from typing import List, Any
from concurrent.futures import ThreadPoolExecutor
import requests
import os
from lxml import etree
import re
if not os.path.exists('./img'):
    os.makedirs("img")
def get_one_proxy():
    return requests.get("http://127.0.0.1:5000/get")
proxies = get_one_proxy().text
# proxies = ''

def down_img(img_url):
    for urls in img_url:
        response = requests.get(url=urls, headers=headers)
        name = urls.split("/")[-1]
        with open("./img/"+f'{name}', 'wb') as f:
            f.write(response.content)

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.58",
    "referer": "https://www.coshunter.pro/simo"
}

a = 252

#354
while a < 355:
    url = f"https://www.coshunter.pro/shop/buy/page/{a}"
    res = requests.get(url, headers=headers, proxies={"http": "http://{}".format(proxies)})
    res.encoding = "utf-8"
    html = re.findall(r'<a class="link-block" href="(.*?)"></a>',res.text)
    urls = html[:-1]
    # print(urls)
    for i in urls:
        res = requests.get(i, headers=headers, proxies={"http": "http://{}".format(proxies)})
        img_url = re.findall(r'<figure class="wp-block-image.*src="(.*?)"',res.text)
        print(img_url)

        with ThreadPoolExecutor(10) as t:
            t.submit(down_img,img_url)
        print(a)
    a += 1



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1895821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙应用实践:利用扣子API开发起床文案生成器

前言 扣子是一个新一代 AI 应用开发平台&#xff0c;无需编程基础即可快速搭建基于大模型的 Bot&#xff0c;并发布到各个渠道。平台优势包括无限拓展的能力集&#xff08;内置和自定义插件&#xff09;、丰富的数据源&#xff08;支持多种数据格式和上传方式&#xff09;、持…

lodash中flush的使用(debounce、throttle)

在项目的配置中&#xff0c;看到了一个请求&#xff0c;类似是这样的 import { throttle } from lodash-es// 请求函数 async function someFetch(){const {data} await xxx.post()return data }// 节流函数 async function throttleFn(someFetch,1000)// 执行拿到数据函数 a…

掌握电路交换与分组交换:计算机网络的核心技术

计算机网络是现代信息社会的基石&#xff0c;而交换技术是实现网络通信的核心。本文将详细介绍两种典型的交换方式&#xff1a;电路交换和分组交换&#xff0c;帮助基础小白快速掌握这两种技术的基本概念和区别。 什么是电路交换&#xff1f; 电路交换&#xff08;Circuit Swi…

斯坦福提出首个开源视觉语言动作大模型OpenVLA

OpenVLA&#xff1a;开源视觉语言动作大模型 摘要模型结构训练数据训练设施实验总结和局限性 项目主页 代码链接 论文链接 模型链接 摘要 现有的VLA(Vision-Language-Action )模型具有这些局限性&#xff1a; 1)大多封闭且开放&#xff1b; 2)未能探索高效地为新任务微调VLA的方…

香橙派AIpro做目标检测

使用香橙派AIpro做目标检测 文章目录 使用香橙派AIpro做目标检测香橙派AIpro开发板介绍香橙派AIpro应用体验快速体验香橙派的AI功能YOLOV5s目标检测使用场景描述图像目标检测视频目标检测摄像头目标检测YOLOv5s 目标检测的运行结果分析香橙派 AIpro 在运行过程中的表现 香橙派A…

【Vue报错】v-bind动态绑定src无效

今天遇到v-bind动态绑定video的src&#xff0c;出现无效的问题 但是翻看以前的项目都是没问题的 之前的项目 现在的项目 发现并不能呈现视频效果 进行了改进&#xff0c;成功展示

Java数据结构9-排序

1. 排序的概念及引用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

【ROS2】Ubuntu 24.04 源码编译安装 Jazzy Jalisco

目录 系统要求 系统设置 设置区域启用所需的存储库安装开发工具 构建 ROS 2 获取 ROS 2 代码使用 rosdep 安装依赖项安装额外的 RMW 实现&#xff08;可选&#xff09;在工作区构建代码 设置环境 尝试一些例子 下一步 备用编译器 Clang保持最新状态 故障排除 卸载 系统要求 当前…

mac如何安装nvm

​ vue项目开发&#xff0c;热更新&#xff0c;webpack&#xff0c;前辈造的轮子&#xff1a;各类的工具&#xff0c;库&#xff0c;像axios,qs,cookie等轮子在npm上可以拿来直接用&#xff0c;需要node作为环境支撑。 开发时同时有好几个项目&#xff0c;每个项目的需求不同…

自然语言处理领域介绍及其发展历史

自然语言处理领域介绍及其发展历史 1 NLP2 主要任务3 主要的方法1 基于规则的方法&#xff08;1950-1980&#xff09;2 基于统计的方法&#xff08;传统的机器学习的方法&#xff09;3 Connectionist approach&#xff08;Neural networks&#xff09; 1 NLP 自动的理解人类语…

C++(第四天----拷贝函数、类的组合、类的继承)

一、拷贝构造函数&#xff08;复制构造函数&#xff09; 1、概念 拷贝构造函数&#xff0c;它只有一个参数&#xff0c;参数类型是本类的引用。如果类的设计者不写拷贝构造函数&#xff0c;编译器就会自动生成拷贝构造函数。大多数情况下&#xff0c;其作用是实现从源对象到目…

mmdetection3增加12种注意力机制

在mmdetection/mmdet/models/layers/目录下增加attention_layers.py import torch.nn as nn from mmdet.registry import MODELS #自定义注意力机制算法 from .attention.CBAM import CBAMBlock as _CBAMBlock from .attention.BAM import BAMBlock as _BAMBlock from .attent…

语音声控灯:置入NRK3301离线语音识别ic 掌控的灯具新风尚

一、语音声控灯芯片开发背景 我们不难发现&#xff0c;传统的灯具控制方式已难以满足现代人对便捷性和智能化的追求。传统的开关控制方式需要人们手动操作&#xff0c;不仅繁琐且不便&#xff0c;特别是在夜晚或光线昏暗的环境下&#xff0c;更容易造成不便甚至安全隐患。而语音…

Spring学习03-[Spring容器核心技术IOC学习进阶]

IOC学习进阶 Order使用Order改变注入顺序实现Ordered接口&#xff0c;重写getOrder方法来改变自动注入顺序 DependsOn使用 Lazy全局设置-设置所有bean启动时候懒加载 Scopebean是单例的&#xff0c;会不会有线程安全问题 Order 可以改变自动注入的顺序 比如有个animal的接口&a…

海外仓一件代发功能自动化:海外仓WMS系统配置方法

根据数据显示&#xff0c;2014-2019年短短几年之间&#xff0c;跨境电商销售总额增长了160%以上。这为跨境电商商家和海外仓&#xff0c;国际物流等服务端企业都提供了巨大的发展机遇。 然而&#xff0c;作为海外仓&#xff0c;要想服务好跨境电商&#xff0c;仓库作业的每一个…

JAVA进阶学习10

文章目录 一、创建不可变集合二、Stream流2.1 Stream流的获取2.1 Stream流的中间方法2.2 Stream流的终结方法 一、创建不可变集合 意义&#xff1a;如果一个集合中的数据在复制或使用过程中不能修改&#xff0c;或者被其他对象调用时不能改变内部数据&#xff0c;即增加数据的安…

【C++ 】解决 C++ 语言报错:Null Pointer Dereferenc

文章目录 引言 在 C 编程中&#xff0c;空指针解引用&#xff08;Null Pointer Dereference&#xff09;是一种常见且危险的错误。当程序试图通过空指针访问内存时&#xff0c;会导致程序崩溃或产生不可预期的行为。本文将详细探讨空指针解引用的成因、检测方法及其预防和解决…

Unity之VS脚本自动添加头部注释Package包开发

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之VS脚本自动添加头部注释Package包开发 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&…

【靶机实战】Apache Log4j2命令执行漏洞复现

# 在线靶场 可以通过访问极核官方靶场开启靶机实验&#xff1a;极核靶场 -> 漏洞复现靶场 -> Log4j2-RCE 原文&#xff1a;【靶机实战】Apache Log4j2命令执行漏洞复现 - 极核GetShell (get-shell.com) # 简介 Apache Log4j2 是一个广泛使用的 Java 日志记录库&#…

秋招突击——设计模式补充——简单工厂模式和策略模式

文章目录 引言正文简单工厂模式策略模式策略模式和工厂模式的结合策略模式解析 总结 引言 一个一个来吧&#xff0c;面试腾讯的时候&#xff0c;问了我单例模式相关的东西&#xff0c;自己这方面的东西&#xff0c;还没有看过。这里需要需要补充一下。但是设计模式有很多&…