python---Pixiv排行榜图片获取(2024.2.16)


1.提示:
使用需要安装各种import的包,都是很基础的包,直接安装即可。
自备梯子 。

2.严肃警告

  1. 本程序仅可用作个人爱好,商业用途严禁!
  2. 请自觉遵守君子协定robots.txt
  3. 不要给网址过大的压力,每天以及同一时段的访问量请控制在一定程度内!

3.思路:
天天有群友找我要涩图,库存根本不够哇,得想办法弄点。

pixiv的爬取有很多大佬做过了,不过我看了一些都是弄得类似于项目一样,确实都很厉害,但我的需求简单,写在一个文件里适合我这种懒蛋。

  1. 首先通过RankingCrawler类的get_multi_page_json方法,获取榜单的json数据,将id添加到collector中。
  2. 然后通过collector的collect方法,遍历每个id,用get_artworks_urls方法获取id页面内的所有图片的urls,将url添加到downloader中。
  3. 最后通过downloaderdownload方法,多线程调用同class内的download_image方法同时下载图片。

4.使用方法:
一般来说都是直接run就行,所有需要修改的参数都在RankingCrawler类的init中,看一眼就明白

5.代码如下:

import os
import re
import time
import requests
import concurrent.futures as futuresfrom datetime import datetime, timedelta
from typing import Set, Iterable, Callable, Dict, Optional, Tuple
from tqdm import tqdmclass Downloader():def __init__(self, capacity, headers, threads, standard_time):self.url_group: Set[str] = set()self.capacity = capacity   # 最大下载量(MB)self.store_path = f"{datetime.now().strftime('%Y_%m_%d')}/"  # 获取当日日期作为存储路径self.standard_time = standard_timeself.threads = threadsself.headers = headers.copy()# 添加urldef add(self, urls: Iterable[str]):for url in urls:self.url_group.add(url)# 下载单张图片def download_image(self, url: str) -> float:"""func: 1.根据url下载单张图片,返回图片大小(MB)return: 返回图片大小(MB)url example: "https://i.pximg.net/img-master/img/2024/02/10/03/09/52/115911580_p0_master1200.jpg""""# image_nameimage_name = url[url.rfind("/") + 1:]# image_idimage_id = re.search(r"/(\d+)_", url).group(1)# image_pathimage_path = self.store_path + image_name# 添加Refererself.headers.update({"Referer": f"https://www.pixiv.net/artworks/{image_id}"})# 确保存储路径存在os.makedirs(self.store_path, exist_ok=True)# 判断图片是否存在if os.path.exists(image_path):# print(f"File {image_name} already exists. Skipping download.")return 0# 下载图片, 尝试最多10次,因为是多线程下载,所以间隔时间可以稍微长一点点for i in range(10):try:response = requests.get(url, headers=self.headers, timeout=(4, self.standard_time))  # timeout(连接超时, 读取超时)if response.status_code == 200:if "content-length" not in response.headers:  # 确保content-length在response.headers中,否则抛出异常raise "content-length not in response.headers"image_size = int(response.headers["content-length"])with open(image_path, "wb") as f:f.write(response.content)return image_size / (1 << 20)except Exception as e:passreturn 0# 多线程下载多张图片def download(self):# 提前封装download_image函数的固定参数,因为map函数只能传入一个参数flow_size = .0print("===== downloader start =====")with futures.ThreadPoolExecutor(self.threads) as executor:# tqdm为进度条with tqdm(total=len(self.url_group), desc="downloading") as pbar:# 多线程并发,通过futures的map方法,将url_group中的每个url传入download_image函数,并通过迭代器的方式返回每个图片的大小for image_size in executor.map(self.download_image, self.url_group):flow_size += image_sizepbar.update()pbar.set_description(f"downloading / flow {flow_size:.2f}MB")if flow_size > self.capacity:executor.shutdown(wait=False, cancel_futures=True)breakprint("===== downloader complete =====")return flow_sizeclass Collector():def __init__(self, threads, user_id, headers, downloader):self.id_group: Set[str] = set()  # illust_idself.threads = threadsself.user_id = user_idself.headers = headers.copy()self.downloader = downloaderdef add(self, image_ids):self.id_group.add(image_ids)# 解析HTTP响应,提取并返回一个包含原始图像URLs的集合def select_page(self, response) -> Set[str]:"""url: https://www.pixiv.net/ajax/illust/xxxx/pages?lang=zhcollect all image urls from (page.json)Returns: Set[str]: urls"""group = set()for url in response.json()["body"]:group.add(url["urls"]["original"])return group# 对给定的URL执行HTTP GET请求,并使用指定的选择器函数处理响应数据def get_artworks_urls(self, args: Tuple[str, Callable, Optional[Dict]]) -> Optional[Iterable[str]]:# 拿到参数url, selector, additional_headers = args# 更新请求头headers = self.headersheaders.update(additional_headers)time.sleep(1)# 尝试抓取最多10次for i in range(10):try:response = requests.get(url, headers=headers, timeout=4)if response.status_code == 200:id_group = selector(response)return id_groupexcept Exception as e:print(e)time.sleep(1)# 并发地收集所有艺术作品的图像URLs,并将它们发送给下载器进行下载。def collect(self):"""collect all image ids in each artwork, and send to downloaderNOTE: an artwork may contain multiple images"""print("===== collector start =====")with futures.ThreadPoolExecutor(self.threads) as executor:with tqdm(total=len(self.id_group), desc="collecting urls") as pbar:# 生成每个illust_id对应的urlurls_list = [f"https://www.pixiv.net/ajax/illust/{illust_id}/pages?lang=zh" for illust_id in self.id_group]# 生成每个illust_id对应的请求头additional_headers = [{"Referer": f"https://www.pixiv.net/artworks/{illust_id}","x-user-id": self.user_id,}for illust_id in self.id_group]# 通过get_artworks_urls获取url下的所有图片urls,发送给downloader# futures.ThreadPoolExecutor(n_thread).map(func, iterable) 会将可迭代对象中的每个元素传入func中, 并将所有的func返回值组成一个迭代器返回for urls in executor.map(self.get_artworks_urls, zip(urls_list, [self.select_page] * len(urls_list), additional_headers)):if urls is not None:self.downloader.add(urls)pbar.update()print("===== collector complete =====")return self.id_groupclass RankingCrawler():def __init__(self):"""download artworks from ranking参数(*为可修改的):top_num: 排行榜前多少名*time_mode: 榜单时间(日, 周, 月...)*content: 内容(插画, 漫画, 动图...)*headers: 请求头*threads: 线程数*capacity: 最大流量容量(MB)*standard_time: 标准等待时间user_id: 自己的用户id*date: 当日日期-1天切记cookie和user_id要是同一个账号的"""self.top_num = 200self.time_mode = "weekly"self.content = "illust"self.headers = {"Cookie": "first_visit_datetime_pc=2022-08-02+15%3A36%3A28; p_ab_id=1; p_ab_id_2=7; p_ab_d_id=1023356603; yuid_b=QXQ4QA; privacy_policy_notification=0; a_type=1; b_type=0; d_type=1; login_ever=yes; __utmv=235335808.|2=login%20ever=yes=1^3=plan=normal=1^6=user_id=56850222=1^9=p_ab_id=1=1^10=p_ab_id_2=7=1^11=lang=zh=1; _im_vid=01HM1N03159737XTWCJAJ2BY5P; __utmz=235335808.1707968192.3.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); _gid=GA1.2.1257313260.1707968194; QSI_S_ZN_5hF4My7Ad6VNNAi=v:0:0; cf_clearance=sC.C_Nz8.49ropcKnVtVHwfrTz0lUg9aYEOSImWP_10-1707984781-1.0-AWnSRIR6YUxoAY8SgMleN0cv3AEKUf1k5ZpisVJ8snzbHvjFS5eX2oWL8Cd2oh0X4fq33MNgfAG7t8d80uS6gmQ=; _gcl_au=1.1.652233640.1707984789; _im_uid.3929=b.427a030d239f8f0f; _pbjs_userid_consent_data=3524755945110770; _im_vid=01HM1N03159737XTWCJAJ2BY5P; _pubcid=72d87e02-9d02-4eba-b647-77676ef3673c; __utma=235335808.1308491601.1659422191.1707968192.1707986109.4; __cf_bm=yav.mgbX7Rs1IN42BVskLJ0y56PpJ.1vuWOV.KN9160-1708063973-1.0-AVZMWvXlgMpvT1KiNIA0E0QeHN5d61NRsSZhDIrrqdV+zJXgRgtEXp1QfmcXtt1nCQ727jXsSJuN3AXfbNO49rvj6Lj7/mYJzBkiPMVZpREY; cto_bundle=LnH3rF8lMkJwbmI0WnQlMkZoTjlEVlBkalNGaVJLMWR4JTJGN1JGeFpJM0VQcDVMVVJNU0g1ZkxqOEdlS2VIMkFDbmZrYlNGa21xUlAxWHdJZm1ZY2g1VmE3emhYUnNWbyUyQjFreFp1M1VKMTQ2Tm9Bc051VHpCTU51SzhzNFVNbEZjJTJCa3dlZFBQSDlIZ1JmMlNwSWpoR0FIdFY2Z2ZlMHBBJTNEJTNE; cto_bidid=GceTm19EUWVHTDZEMjdZVEVad0g2Skh0bDdtMVpCJTJGNiUyRjlBQ3N0JTJCeVZaeUU0dWIzemIzRlVsWjZVWnlDcFh4VnJVQ0xNRERtRCUyQnRDRmU0UkQlMkZOdERHUWJsMmNNT0d1bUZJSnBlb3ZtREY1eUYxWG8lM0Q; cto_dna_bundle=wcDUY185WlVTMUslMkYzb3lGS2J1ekVhb2pXaVgyQnF5ZkFyelBXZUIyMEMlMkYlMkZOWnZGbkhVaFBjT1pRcmhvdEdzTlhOcTdKc0JJTmIxZXduS2tsUXUlMkZPVVBVM1N3JTNEJTNE; cc1=2024-02-16%2015%3A33%3A21; PHPSESSID=103427506_aygRqdHukP6BzGOBKfQDw2QadPmoxwvm; device_token=29dcd2275dd3ad33f978780a8732d797; privacy_policy_agreement=6; _ga_MZ1NL4PHH0=GS1.1.1708065204.3.1.1708065473.0.0.0; c_type=45; _ga_75BBYNYN9J=GS1.1.1708063957.12.1.1708065479.0.0.0; _ga=GA1.2.1308491601.1659422191; _gat_UA-1830249-3=1","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36"}self.threads = 12self.capacity = 2048self.standard_time = 10self.user_id = "103427506"self.date = (datetime.now()-timedelta(days=1)).strftime('%Y%m%d')self.downloader = Downloader(self.capacity, self.headers, self.threads, self.standard_time)self.collector = Collector(self.threads, self.user_id, self.headers, self.downloader)# 拿到榜单的json数据,将id添加到collector中def get_multi_page_json(self):for i in range(1, self.top_num // 50 + 1):url = f"https://www.pixiv.net/ranking.php?mode={self.time_mode}&content={self.content}&date={self.date}&p={i}&format=json"headers = self.headersheaders.update({"Referer": f"https://www.pixiv.net/ranking.php?mode={self.time_mode}&date={self.date}","x-requested-with": "XMLHttpRequest"})response = requests.get(url, headers=headers, timeout=(4, self.standard_time))if response.status_code == 200:art_works = response.json()["contents"]for i in art_works:self.collector.add(str(i["illust_id"]))time.sleep(1)def run(self):self.get_multi_page_json()self.collector.collect()self.downloader.download()if __name__ == "__main__":RankingCrawler().run()

喜欢的话不妨点个赞吧?有人互动的感觉才能支撑我继续发文章呀~

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

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

相关文章

Springboot --- 使用国内的 AI 大模型 对话

实在是不知道标题写什么了 可以在评论区给个建议哈哈哈哈 先用这个作为标题吧 尝试使用 国内给出的 AI 大模型做出一个 可以和 AI 对话的 网站出来 使用 智普AI 只能 在控制台中输出 对应的信息 不如就做一个 maven 的 项目调用对应的API https://open.bigmodel.cn/dev/api#g…

Python 字符串格式化输出

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 前言 字符串格式化是编程中一个常见的需求&#xff0c;它可以们将不同类型的数据&#xff08;如数字、文本、日…

JVM-JVM中对象的生命周期

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 对象的创建 常量池检查:检查new指令是否能在常量池…

openEuler 22.03 LTS 上源码安装 PostgreSQL 15

安装PostgreSQL 15 1 安装必要的依赖 #yum install -y readline-devel zlib-devel gcc2、下载源码 # wget https://ftp.postgresql.org/pub/source/v15.6/postgresql-15.6.tar.gz # tar -xzvf postgresql-15.6.tar.gz3 配置 # cd postgresql-15.6/ # ./configure4 编译安装…

Matlab|基于支持向量机的电力短期负荷预测【三种方法】

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序主要是对电力短期负荷进行预测&#xff0c;采用三种方法&#xff0c;分别是最小二乘支持向量机&#xff08;LSSVM&#xff09;、标准粒子群算法支持向量机和改进粒子群算法支持向量机三种方法对负荷进行…

Nginx反向代理多虚拟主机节点服务器

IP规划: servera,serverd作为web服务器 serverb作为nginx负载均衡服务器 serverc域名映射服务器 servera(192.168.233.132)配置: # 安装Nginx yum install nginx -y# 进入Nginx配置文件目录 cd /etc/nginx/conf.d/# 编辑配置文件&#xf…

讲解用Python处理Excel表格

我们今天来一起探索一下用Python怎么操作Excel文件。与word文件的操作库python-docx类似&#xff0c;Python也有专门的库为Excel文件的操作提供支持&#xff0c;这些库包括xlrd、xlwt、xlutils、openpyxl、xlsxwriter几种&#xff0c;其中我最喜欢用的是openpyxl&#xff0c;这…

【天幕系列 02】开源力量:揭示开源软件如何成为技术演进与社会发展的引擎

文章目录 导言01 开源软件如何推动技术创新1.1 开放的创新模式1.2 快速迭代和反馈循环1.3 共享知识和资源1.4 生态系统的建设和扩展1.5 开放标准和互操作性 02 开源软件的商业模式2.1 支持和服务模式2.2 基于订阅的模式2.3 专有附加组件模式2.4 开源软件作为平台模式2.5 双重许…

【计算机网络】物理层|传输介质|物理层设备|宽带接入技术

目录 一、思维导图 二、传输介质 1.传输介质——导引型 2.传输介质——非导引型​编辑 三、物理层设备 1.物理层设备&#xff1a;中继器&集线器 2.宽带接入技术&#xff08;有线&#xff09; ​编辑 四、趁热打铁☞习题训练 五、物理层总思维导图 推荐 前些天发现…

【C++】友元、内部类和匿名对象

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 1. 友元 1.1 友元函数 1.2 友元类 2. 内部类 2.1 成员内部类 2.2 局部内部类 3. 匿名对象 3.1 基本概念 3.1 隐式转换 1…

Node.js开发-MongoDB

MongoDB 1) Mongoose2) 插入文档3) 字段类型4) 字段值验证5) CRUD1) 增加2) 删除3) 更新4) 查询 6) 条件控制1) 运算符2) 逻辑运算3) 正则匹配 7) 个性化读取1) 字段筛选2) 数据排序3) 数据截取 1) Mongoose 介绍 Mongoose 是一个对象文档模型库&#xff0c;官网 http://www.…

在已有代码基础上创建Git仓库

在已有代码基础上创建Git仓库 背景方法处理问题 背景 先进行了代码编写&#xff0c;后续想放入仓库方便大家一起合作开发&#xff0c;此时需要在已有代码的基础上建立仓库。 方法 首先在Gitee或者GitHub上创建仓库&#xff0c;这里以Gitee为例。创建完后&#xff0c;我们可以…

各类有关于花卉的深度学习数据集

花卉的识别和分类在深度学习过程中是最常见的使用的案例&#xff0c;因此各类有关花卉分类、识别、计数的图像数据集是大家都常用的数据集。最近收集到各类有关花卉的各类数据集分享给大家&#xff01;&#xff01; 1、16种花常见的图像数据集 数据说明&#xff1a;我们看到我…

Blazor SSR/WASM IDS/OIDC 单点登录授权实例1-建立和配置IDS身份验证服务

目录: OpenID 与 OAuth2 基础知识Blazor wasm Google 登录Blazor wasm Gitee 码云登录Blazor SSR/WASM IDS/OIDC 单点登录授权实例1-建立和配置IDS身份验证服务Blazor SSR/WASM IDS/OIDC 单点登录授权实例2-登录信息组件wasmBlazor SSR/WASM IDS/OIDC 单点登录授权实例3-服务端…

1070A A. Find a Number bfs同时处理数和数位和 ,依次处理每一位数

Problem - 1070A - Codeforces A - Find a Number CodeForces - 1070A -记忆化广搜-同余定理_codeforces 1070a find a number(bfs)-CSDN博客 这个大佬的博客代码写的非常好看。 ———— &#xff08;其实第二个样例32位的数long long存不下&#xff0c;就知道这道题不是寻…

【实战】一、Jest 前端自动化测试框架基础入门(二) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(二)

文章目录 一、Jest 前端自动化测试框架基础入门5.Jest 中的匹配器toBe 匹配器toEqual匹配器toBeNull匹配器toBeUndefined匹配器和toBeDefined匹配器toBeTruthy匹配器toBeFalsy匹配器数字相关的匹配器字符串相关的匹配器数组相关的匹配器异常情况的匹配器 6.Jest 命令行工具的使…

DSA 经典数据结构与算法 学习心得和知识总结(三) |有向无环图及其应用

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《算法导论》第三版 就是这本被封神的杰作&#xff0c;就是它&#x1f926; 2、参考书籍&#xff1a;《数据结构》严奶奶版 3、参考书…

DataX源码分析-插件机制

系列文章目录 一、DataX详解和架构介绍 二、DataX源码分析 JobContainer 三、DataX源码分析 TaskGroupContainer 四、DataX源码分析 TaskExecutor 五、DataX源码分析 reader 六、DataX源码分析 writer 七、DataX源码分析 Channel 八、DataX源码分析-插件机制 文章目录 系列文章…

基于GPT一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

Prompt Tuning:深度解读一种新的微调范式

阅读该博客&#xff0c;您将系统地掌握如下知识点&#xff1a; 什么是预训练语言模型&#xff1f; 什么是prompt&#xff1f;为什么要引入prompt&#xff1f;相比传统fine-tuning有什么优势&#xff1f; 自20年底开始&#xff0c;prompt的发展历程&#xff0c;哪些经典的代表…