# !/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/11/16 10:02 AM
# @Author : cxa
# @File : cosmic.py
# @Software: PyCharm
# encoding: utf-8
import os
import aiohttp
import hashlib
import base64
from cryptography.fernet import Fernet
import aiofiles
import multiprocessing
import async_timeout
from lxml import html
import asyncio
from aiologger import Logger
import asyncpool
workers = multiprocessing.cpu_count() * 2 + 1
# 开始索引数
start_num = 227002
# 结束索引数
# end_num = 227006
end_num = 250606
key = "X0JxSkg4NFVBQVBPODlUM0VzT1liNnloeWtLcndkSldRT2xURzQ4MEM5RT0="
page_num_xpath = "//p[@class='selectpage']/select[@id='page_number']/option[last()]/@file"
page_id_xpath = "//img[@id='thumbnail']/@src" def aes_cbc_decrypt(message):
decrypted_text = Fernet(base64.b64decode(key).decode("utf8")).decrypt(bytes("{}".format(message), encoding="utf8"))
return decrypted_text.decode("utf8") # 漫画题目
cosmic_name = "//head//title/text()"
# 漫画id
cosmic_id = "//img[@id='curPic']/@src"
main_url = aes_cbc_decrypt(
"gAAAAABbNdhqCnxkaJwZ2VL7HUXne_IOic-NsHtE30W-J68oecVmgm0dzO_lLXgTlI7a5_NbUWlkGm7FqLwY81XIBddNWbac4rCgBA9NFAECsNISkhTvdRl4uDSaS6bHY8sbcJJwO13Z")
cosmic_url_gen = (main_url.format(i) for i in range(start_num, end_num + 1))
full_url = aes_cbc_decrypt(
"gAAAAABbNdk5FLeX55hOiDAXxgCwwYmGrokYvU3Nd1AOYuOE7OdIEcBdAmSG_Q3kOltealBKMOgUBKDuPUJtzFFPwqoxL-FUip"
"VNQU-JmBW_K5qxgzTQ3IOla_F61Rscy0fJOaN-mEXKPqrakctyDRN7OVm1LARTMhylQELLuBnJgIT4WXilchg=") # 漫画的总id,序号的id和格式使用(jpg) sema = asyncio.Semaphore(5)
sem_img = asyncio.Semaphore(50) async def logging():
logger = Logger.with_default_handlers(name='cosmic_download')
return logger async def get_buff(url, c_name, session, log):
with async_timeout.timeout(60):
async with session.get(url) as r:
buff = await r.read()
if not len(buff):
url = url.replace(".jpg", ".png")
async with session.get(url) as r2:
buff = await r2.read()
await log.info(f"NOW_URL:, {url}")
await get_img(url, buff, c_name, log) async def run_img(url, c_name, session, log):
async with sem_img:
await get_buff(url, c_name, session, log) async def get_img(url, buff, c_name, log):
# 题目那层目录
filepath = os.path.join(os.getcwd(), "comics_images", c_name)
# 如果标题太长就转md5,然后单独启动一个text写入内容为标题
md5name = hashlib.md5(c_name.encode("utf-8")).hexdigest()
filepath2 = os.path.join(os.getcwd(), "comics_images", md5name) id = url.split('/')[-1]
image_id = os.path.join(filepath, id)
image_id2 = os.path.join(filepath2, md5name) # 题目层目录是否存在
if not os.path.exists(filepath) and not os.path.exists(filepath2):
try:
os.makedirs(filepath)
except:
os.makedirs(filepath2)
image_id = image_id2
fs = await aiofiles.open(os.path.join(filepath2, "title.txt"), 'w')
await fs.write(c_name) # 文件是否存在
if not os.path.exists(image_id) and not os.path.exists(image_id2):
await log.info(f"SAVE_PATH:{image_id}")
async with aiofiles.open(image_id, 'wb') as f:
await f.write(buff) async def fetch(url, session, log, retry_index=0):
try:
with async_timeout.timeout(30):
async with session.get(url, verify_ssl=False) as req:
res_status = req.status
if res_status == 200:
text = await req.text()
root = html.fromstring(text)
name = root.xpath(cosmic_name)[0]
jpg_id = root.xpath(page_id_xpath)[0].split('/')[-2]
max_page = root.xpath(page_num_xpath)[0].split('.')[0]
full_url_gen = (full_url.format(jpg_id, i, "jpg") for i in range(1, int(max_page) + 1))
tasks = [asyncio.ensure_future(run_img(img_url, name, session, log)) for img_url in full_url_gen]
await asyncio.gather(*tasks)
except Exception as e:
text = None
if not text:
await log.error(f'Retry times: {retry_index + 1}')
retry_index += 1
return await fetch(url, session, log, retry_index) async def bound_fetch(url, session, log):
async with sema:
await fetch(url, session, log) async def run(data):
log = await logging()
result_queue = asyncio.Queue()
await log.info("Start Spider")
async with asyncpool.AsyncPool(loop, num_workers=10, name="cosmic",
logger=log, worker_co=bound_fetch) as pool:
async with aiohttp.connector.TCPConnector(limit=100, force_close=True, enable_cleanup_closed=True) as tc:
async with aiohttp.ClientSession(connector=tc) as session:
for url in data:
await pool.push(url, session, log)
await result_queue.put(None) if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run(cosmic_url_gen))
loop.close()

项目地址:https://github.com/muzico425/cosmic_download

cosmic_download-AsyncPool待修正的更多相关文章

  1. [修正] Firemonkey 中英文混排折行问题(移动平台)

    问题:FMX 在移动平台的文字显示并非由该平台的原生 API 来显示,而是由 FMX.TextLayout.GPU 来处理,也许是官方没留意到中文字符的问题,造成在中英文混排折行时,有些问题. 适用: ...

  2. [修正] Firemonkey Android 显示 Emoji (颜文字)

    问题:在 Android 平台下,显示 Emoji 文字,无法显示彩色(皆为黑色),例如 Edit 控件,即使将 Edit.ControlType = Platform 设为平台原生控件,还是没用(真 ...

  3. 2016 正确 sublime安装PHPcs PHPcodesniffer代码规范提示插件,修正网上部分不详细描述

    对你有助请点赞,请顶,不好请踩------送人玫瑰,手留余香!-------------------14:37 2016/3/212016 正确 sublime安装PHPcs PHPcodesniff ...

  4. Mint Linux 安装 DotnetCore 遭遇无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系

    evlon@evlon-ThinkPad-T530 ~ $ apt install dotnet-dev-1.0.0-preview2-003121 正在读取软件包列表... 完成 正在分析软件包的依 ...

  5. 修正IE6不支持position:fixed的bug(转)

    众所周知IE6不支持position:fixed,这个bug与IE6的双倍margin和不支持PNG透明等bug一样臭名昭著.前些天我做自己的博客模板的时候,遇到了这个问题.当时就简单的无视了IE6— ...

  6. [修正] 移动平台曲线不平滑的问题(如:TRectangle, TPath...等)

    问题:从 XE4 以来,Firemonkey 曲线绘图在移动平台不平滑的问题一直令人诟病,提交到官方的 QC 也是族繁不及备载,官方似乎有意的避开这个问题,迟迟没有修正. 适用版本:XE4 ~ Ber ...

  7. [修正] Firemonkey TSelection 控件等比缩放时,左下角拉动问题

    说明:TSelection 控件,当在属性 Proportional = True 为等比缩放时,拉动左下角,右上角会跟着移动. 适用:Berlin 10.1.1 (或之前版本) Firemonkey ...

  8. [修正] Berlin Firemonkey Windows 控件左方显示虚线问题

    说明:在 Wndows 显示时,有时控件左方会显示一条虚线 适用:Berlin Firemonkey 修正方法: 请将源码 FMX.Platform.Win.pas 复制到自己的工程目录里,再进行修改 ...

  9. 查看数据库表的数据量和SIZE大小的脚本修正

    在使用桦仔的分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)的脚本时,遇到下面一些错误 这个是因为这些表的Schema是Maint,而不是默认的dbo,造成下面这段SQ ...

随机推荐

  1. 设计模式_代理模式_在SqlSessionTemplate(Spring)中的应用

    1.SqlSessionTemplate的构造函数,根据传入的SqlSessionFactory和ExecutorType创建一个Spring管理的SqlSession,并生成SqlSession的动 ...

  2. 运维监控-Zabbix Server 使用QQ SMTP发送邮件报警及定制报警内容

    运维监控-Zabbix Server 使用QQ SMTP发送邮件报警及定制报警内容 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客采用腾讯邮箱,想必大家都对QQ很了解,所以 ...

  3. linq总结系列(一)---基础部分

    一.linq的基本概念 LINQ是C#和VB中的统一查询语法,使用对象来保存和检索来自不同来源(如数据库.xml.对象集合)的数据. 主要功能:消除了编程语言和数据库之间的不匹配,以及为不同类型的数据 ...

  4. Mysql:索引实战

    MySQL主要提供2种方式的索引:B-Tree索引,Hash索引 B树索引具有范围查找和前缀查找的能力,对于有N节点的B树,检索一条记录的复杂度为O(LogN).相当于二分查找. 哈希索引只能做等于查 ...

  5. https笔记【转】

    图解HTTPS 我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取.所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议. HTTPS简介 HTTPS其实是有两部分组成:HT ...

  6. 【1】BIO,NIO,AIO与Reactor,Proactor

    讲解IO思路: BIO(一个连接一个线程) -->大并发问题-->NIO(操作系统层面:IO多路复用) -->NIO两个问题:1.谁去监听就绪(Boss),2.谁来处理已就绪(Wor ...

  7. GIL 全局解释器

    全局解释器锁 GIL 相当于给python解释器加了一把互斥锁 每一个进程都有一把互斥锁,所有线程必须先拿到解释器,才能执行代码, 同一进程下,所有线程并发 在 Cpython 解释器下,多个进程可以 ...

  8. int、bool和str

    int bit_length 返回以二进制表示的最短长度 print(int.bit_length(10)) 结果 4 Process finished with exit code 0 int() ...

  9. webpack 内存溢出 Allocation failed - JavaScript heap out of memory

    项目中,当组件文件过多,webpack-dev-server 编译时,容易内存溢出, 在 \node_modules\.bin\webpack-dev-server.cmd 加以下红色配置,暂可解决 ...

  10. QIM量化

    基于量化思想的水印嵌入模型的主要目的是为了实现盲检测.其主要思想是根据水印信息的不同将原始载体数据量化到不同的量化区间,而检测时根据所属的量化区间来识别水印信息.常见的两种量化方式是QIM和SCS方法 ...