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

爬取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.mfbz.cn/a/777547.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

dependencyManagement的作用、nacos的学习

使用SpringCloudAlibaba注意各组件的版本适配 SpringCloudAlibaba已经包含了适配的各组件&#xff08;nacos、MQ等&#xff09;的版本号&#xff0c;也是一个版本仲裁者&#xff0c;但是可能已经有了父项目Spring-Boot-Starter-Parent这个版本仲裁者&#xff0c;又不能加多个父…

Mongodb oplog的作用及如何评估和更改保留时间

作者介绍&#xff1a;老苏&#xff0c;10余年DBA工作运维经验&#xff0c;擅长Oracle、MySQL、PG数据库运维&#xff08;如安装迁移&#xff0c;性能优化、故障应急处理等&#xff09; 公众号&#xff1a;老苏畅谈运维 欢迎关注本人公众号&#xff0c;更多精彩与您分享。oplog …

硅纪元视角 | 国内首款鸿蒙人形机器人“夸父”开启应用新篇章

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

景区气象站:守护旅行安全的智能向导

在繁忙的现代社会&#xff0c;人们越来越渴望逃离城市的喧嚣&#xff0c;寻找一处宁静的自然之地放松身心。景区&#xff0c;作为大自然与人类文明交织的瑰宝&#xff0c;吸引了无数游客前来探访。然而&#xff0c;多变的天气往往给游客的旅行带来不确定性。 景区气象站&#x…

Java跳出循环的四种方式

1、continue,break,return continue&#xff1a;跳出当前层循环的当前语句&#xff0c;执行当前层循环的下一条语句。   continue标签 break&#xff1a;跳出当前层循环。 break标签&#xff1a;多层循环时&#xff0c;跳到具体某层循环。 return&#xff1a;结束所有循环…

微观特征轮廓尺寸测量:光学3D轮廓仪、共焦显微镜与台阶仪的应用

随着科技进步&#xff0c;显微测量仪器以满足日益增长的微观尺寸测量需求而不断发展进步。多种高精度测量仪器被用于微观尺寸的测量&#xff0c;其中包括光学3D表面轮廓仪&#xff08;白光干涉仪&#xff09;、共聚焦显微镜和台阶仪。有效评估材料表面的微观结构和形貌&#xf…

如何选择一家适合自己的商城源码?

商城源码的选择取决于多个因素&#xff0c;包括商城的功能需求、稳定性、易用性、可定制性以及价格等。启山智软作为在市场上被广泛认可且表现优异的商城源码提供商&#xff0c;具有以下的特点和优势&#xff1a; 特点①&#xff1a;国内知名的B2B2C开源商城源码系统&#xff…

AI助手崛起:开发者的新伙伴还是未来替代者?

你好&#xff0c;我是三桥君。 自从 ChatGPT 问市以来&#xff0c;AI 将取代开发者的声音不绝于耳&#xff0c;至今还是互联网异常火热的问题。 在软件开发领域&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;正在改变开发者的工作方式。无论是代码生成、错误检测还是…

笔记15:while语句编程练习

练习一&#xff1a; 编写程序&#xff0c;求 2^24^26^2...n^2? -直到累加和大于或等于 10000 为止&#xff0c;输出累加和 -输出累加式中的项数&#xff0c;以及最大的数 n #include<stdio.h> int main() {int sum 0;int i 1;int n 0;while(sum < 10000)//将sum…

Leetcode - 周赛404

目录 一&#xff0c;3200. 三角形的最大高度 二&#xff0c;3201. 找出有效子序列的最大长度 I 三&#xff0c;3202. 找出有效子序列的最大长度 II 四&#xff0c;3203. 合并两棵树后的最小直径 一&#xff0c;3200. 三角形的最大高度 本题直接模拟&#xff0c;分别计算一下…

极简通俗VAE

一、VAE 背景&#xff1a;VAE什么变分自编码器&#xff0c;听起来起名都头大&#xff0c;用大白话告诉你。 把一个复杂图片压缩成两个参数&#xff0c;用这个参数采样再复原。 这个简单的东西是两个参数&#xff0c;均值和方差&#xff0c;用&#xff08;0&#xff0c;1&…

C语言_练习题

求最小公倍数 思路&#xff1a;假设两个数&#xff0c;5和7&#xff0c;那么最小至少也要7吧&#xff0c;所以先假定最小公倍数是两个数之间较大的&#xff0c;然后看7能不能同时整除5和7&#xff0c;不能就加1继续除 int GetLCM(int _num1, int _num2) {int max _num1>_n…

web学习笔记(八十)

目录 1.小程序实现微信一键登录 2. 小程序的授权流程 3.小程序配置vant库 4.小程序配置分包 5.小程序配置独立分包 6.小程序分包预下载 1.小程序实现微信一键登录 要先实现小程序一键登录首先我们需要给按钮设置一个绑定事件&#xff0c;然后在绑定事件内部通过wx.login…

phpexcel导入导出

前言&#xff1a; 如果你到处的excel软件打开有问题&#xff0c;下面有介绍解决办法 导入 1. composer init 初始化 2. 下载phpspreadsheet 这里需要注意php版本&#xff0c;需要大于7.2 composer require phpoffice/phpspreadsheet3. 编写代码 <?php require vendo…

Vue3+.NET6前后端分离式管理后台实战(二十七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(二十七)

017-GeoGebra基础篇-微积分函数求解圆弧面积问题

基础篇慢慢的走进尾声&#xff0c;今天给大家带来一个小项目&#xff0c;是关于高中数学微积分部分的展示&#xff0c;这个项目主要包含了函数的介绍、函数与图形绘制的区别、区域函数图像的绘制、积分函数的应用、动态文本的调用、嵌套滑动条的应用等等&#xff0c;以及其他常…

代理模式的实现

1. 引言 1.1 背景 代理模式&#xff08;Proxy Pattern&#xff09;是一种常用的设计模式&#xff0c;它允许通过一个代理对象来控制对另一个对象的访问。在面向对象编程的框架中&#xff0c;代理模式被广泛应用&#xff0c;尤其在Spring框架的AOP&#xff08;面向切面编程&am…

Python的招聘数据分析与可视化管理系统-计算机毕业设计源码55218

摘要 随着互联网的迅速发展&#xff0c;招聘数据在规模和复杂性上呈现爆炸式增长&#xff0c;对数据的深入分析和有效可视化成为招聘决策和招聘管理的重要手段。本论文旨在构建一个基于Python的招聘数据分析与可视化管理系统。 该平台以主流招聘平台为数据源&#xff0c;利用Py…

arm架构安装chrome

在ARM架构设备上安装谷歌软件或应用通常涉及到几个步骤&#xff0c;这取决于你要安装的具体谷歌产品&#xff0c;比如谷歌浏览器、Google Play服务或者是其他谷歌开发的软件。下面我会给出一些常见的指导步骤&#xff0c;以安装谷歌浏览器为例&#xff1a; 在Linux ARM64上安装…

平价蓝牙耳机推荐有哪些?四大超值平价蓝牙耳机品牌盘点

市面上的蓝牙耳机品牌繁多&#xff0c;价格差异巨大&#xff0c;对于预算有限但又不想牺牲音质和使用体验的消费者来说&#xff0c;寻找到既平价又性能出色的蓝牙耳机无疑是一项挑战&#xff0c;那么在平价蓝牙耳机推荐有哪些&#xff1f;面对这个疑问&#xff0c;作为真无线蓝…