├── .gitignore ├── README.md ├── get.cmd ├── get.fish ├── getComic-gui.py ├── getComic.py └── list.txt /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .* 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | getComic 2 | ======== 3 | 4 | ***本代码仅供学习交流使用,严禁用于非法用途,各种PR都欢迎*** 5 | 6 | 下载腾讯漫画的脚本。空参运行进入交互式模式,支持的参数可以加``-h``或``--help``参数查看。 7 | 8 | **GUI版本提供windows下打包好的版本** 9 | 10 | [点此下载](http://7xjpgb.com1.z0.glb.clouddn.com/getComic-gui.zip) (只提供64位版本,可以在win7/win10 64bit系统下运行) 11 | 12 | 使用[Pyinstaller](http://www.pyinstaller.org/)打包 13 | 14 | **依赖**: 15 | 16 | * python3 17 | * 第三方类库[requests](http://docs.python-requests.org/en/latest/user/install/#install) 18 | * 第三方类库[lxml](http://lxml.de/) 19 | * [python3-pyqt5](http://www.riverbankcomputing.co.uk/software/pyqt/download5) (GUI依赖,不用GUI可不装) 20 | 21 | ubuntu系列系统使用以下命令安装依赖: 22 | 23 | sudo apt-get update ; sudo apt-get install python3 python3-requests python3-lxml 24 | sudo apt-get install python3-pyqt5 #GUI依赖,不用GUI可不装 25 | 26 | URL格式: 漫画首页的URL,如``http://m.ac.qq.com/comic/index/id/518333``(移动版) 或 ``http://ac.qq.com/Comic/comicInfo/id/17114``, ``http://ac.qq.com/naruto``(PC版) 27 | 28 | **注意**: 火影忍者彩漫需要访问``m.ac.qq.com``搜索火影忍者,因为PC端页面火影忍者彩漫和黑白漫画是一个id一个url。 29 | 30 | **命令行帮助** 31 | 32 | ```bash 33 | usage: getComic.py [-h] [-u URL] [-p PATH] [-d] [-l LIST] 34 | 35 | *下载腾讯漫画,仅供学习交流,请勿用于非法用途* 36 | 空参运行进入交互式模式运行。 37 | 38 | optional arguments: 39 | -h, --help show this help message and exit 40 | -u URL, --url URL 要下载的漫画的首页,可以下载以下类型的url: 41 | http://ac.qq.com/Comic/comicInfo/id/511915 42 | http://m.ac.qq.com/Comic/comicInfo/id/505430 43 | http://pad.ac.qq.com/Comic/comicInfo/id/505430 44 | http://ac.qq.com/naruto 45 | -p PATH, --path PATH 漫画下载路径。 默认: /home/fengyu/tencent_comic 46 | -d, --dir 将所有图片下载到一个目录(适合腾讯漫画等软件连看使用) 47 | -l LIST, --list LIST 要下载的漫画章节列表,不指定则下载所有章节。格式范例: 48 | N - 下载具体某一章节,如-l 1, 下载第1章 49 | N,N... - 下载某几个不连续的章节,如 "-l 1,3,5", 下载1,3,5章 50 | N-N... - 下载某一段连续的章节,如 "-l 10-50", 下载[10,50]章 51 | 杂合型 - 结合上面所有的规则,如 "-l 1,3,5-7,11-111" 52 | ``` 53 | 54 | **GUI预览效果** 55 | 56 | 支持不连续的章节选择下载 57 | 58 | windows预览效果: 59 | 60 | ![](http://static.oschina.net/uploads/space/2014/0724/222236_2rb7_1395553.jpg) 61 | ![](http://static.oschina.net/uploads/space/2014/0724/222329_Pife_1395553.jpg) 62 | 63 | deepin/Linux 预览效果: 64 | 65 | ![](http://static.oschina.net/uploads/space/2014/0724/223412_4Hz4_1395553.jpg) 66 | 67 | **更新日志** 68 | * 2016-08-18更新: 增加超时,失败后返回错误,不卡死,增加两个批量下载脚本(windows&ubuntu) 69 | PS:本来是学校网络不好,打算要开学带点漫画过去,在ubuntu上爬了一半硬盘存满了。。。于是又牺牲了一下笔记本。 70 | list.txt是使用 71 | wget -r -l 2 -np -k http://ac.qq.com 72 | 把腾讯动漫网站爬下来,然后稍微处理一下弄得,没想到什么别的方法。 73 | * 2014-12-26更新: 新增小功能——单目录下载模式,适合导入腾讯漫画等看图工具连续观看 74 | * 2014-07-26更新: GUI小细节优化——下载完毕后重新聚焦listview。默认下载路径分隔符windows和linux统一风格 75 | * 2014-07-24更新: 完成GUI界面基本功能 76 | * 2014-07-11更新: 开坑,GUI走起!提交一个基本框架,使用python3-pyqt5的GUI框架。此次递交文件: https://github.com/abcfy2/getComic/commit/6110571122f923a398604ca7faff18615c961683 77 | * 2014-07-08更新: 增加-l|--list参数,指定需要下载的章节范围,相关issue: [#2](https://github.com/abcfy2/getComic/issues/2) 78 | * 2014-07-05更新: CF漫画地址 (http://ac.qq.com/cf) 无法跳转至对应的移动端URL,这一类地址将给出错误提示并退出 79 | * 2014-07-04更新: 加入命令行参数支持功能 80 | * 2014-07-03更新: 伪续传实现,判断目标文件路径存在就跳过下载(腾讯应该加入了防刷机制,无法通过head请求得到的content-length判断究竟是否需要重下,因为for循环+head请求过快,会被ban掉,造成异常退出) 81 | * 2014-07-03更新: 使用ipad的UA,这样访问非id的URL,会跳转为``http://m.ac.qq.com``这样带有id的移动版URL,可以搞定``http://ac.qq.com/naruto``或``http://ac.qq.com/onepiece``这一类非id结尾的URL。 82 | 83 | 下一步计划: 84 | 85 | * ~~实现火影等无id的页面下载~~(已解决) 86 | * ~~实现完整的命令行参数~~(已解决) 87 | * ~~一个图形界面(pyqt5实现)~~ 88 | -------------------------------------------------------------------------------- /get.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | for /f %%i in (list.txt) do ( 3 | echo %%i 4 | "C:\programs\Python 3.5\python.exe" getComic.py -p s:\tx\comic -u http://ac.qq.com/Comic/comicInfo/id/%%i 5 | echo return code : %ERRORLEVEL% 6 | if %ERRORLEVEL% NEQ 0 echo %%i >>error2.txt 7 | TIMEOUT /T 5 8 | ) -------------------------------------------------------------------------------- /get.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | for id in (cat list.txt);echo http://ac.qq.com/Comic/comicInfo/id/$id;if begin;getComic2.py -u http://ac.qq.com/Comic/comicInfo/id/$id;end;echo success;else;echo $id>>/tmp/error.txt;echo $id error;end;sleep 5;end 3 | -------------------------------------------------------------------------------- /getComic-gui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import re 5 | import sys 6 | import traceback 7 | 8 | from PyQt5.QtCore import * 9 | from PyQt5.QtWidgets import * 10 | 11 | import getComic 12 | 13 | 14 | class TencentComicDownloader(QWidget): 15 | def __init__(self, parent=None): 16 | super(TencentComicDownloader, self).__init__(parent) 17 | 18 | nameLabel = QLabel("漫画首页:") 19 | 20 | self.nameLine = QLineEdit() 21 | 22 | self.analysisButton = QPushButton("分析") 23 | self.analysisButton.clicked.connect(self.anaysisURL) 24 | self.nameLine.returnPressed.connect(self.analysisButton.click) 25 | 26 | pathLineLabel = QLabel("下载路径:") 27 | self.pathLine = QLineEdit() 28 | defaultPath = os.path.join(os.path.expanduser('~'), 'tencent_comic') 29 | self.pathLine.setText(defaultPath) 30 | 31 | self.browseButton = QPushButton("浏览") 32 | self.browseButton.clicked.connect(self.getPath) 33 | 34 | comicNameLabel = QLabel("漫画名: ") 35 | self.comicNameLabel = QLabel("暂无") 36 | self.one_folder_checkbox = QCheckBox("单目录") 37 | 38 | comicIntroLabel = QLabel("简介: ") 39 | self.comicIntro = QLabel("暂无") 40 | self.comicIntro.setWordWrap(True) 41 | 42 | chapterGroupBox = QGroupBox("章节列表: (按住CTRL点击可不连续选中,鼠标拖拽或按住SHIFT点击首尾可连续选中,CTRL+A全选)") 43 | 44 | self.chapterListView = QListWidget(chapterGroupBox) 45 | self.chapterListView.setSelectionMode(QAbstractItemView.ExtendedSelection) 46 | self.chapterListView.setEnabled(False) 47 | 48 | groupBoxLayout = QHBoxLayout(chapterGroupBox) 49 | groupBoxLayout.addWidget(self.chapterListView) 50 | 51 | self.downloadButton = QPushButton("下载选中") 52 | self.statusLabel = QLabel("输入要下载的漫画的首页,然后点分析") 53 | self.statusLabel.setWordWrap(True) 54 | 55 | self.downloadButton.setEnabled(False) 56 | self.downloadButton.clicked.connect(self.download) 57 | 58 | mainLayout = QGridLayout() 59 | mainLayout.addWidget(nameLabel, 0, 0) 60 | mainLayout.addWidget(self.nameLine, 0, 1) 61 | mainLayout.addWidget(self.analysisButton, 0, 2) 62 | mainLayout.addWidget(pathLineLabel, 1, 0) 63 | mainLayout.addWidget(self.pathLine, 1, 1) 64 | mainLayout.addWidget(self.browseButton, 1, 2) 65 | mainLayout.addWidget(comicNameLabel, 2, 0) 66 | mainLayout.addWidget(self.comicNameLabel, 2, 1, 1, 2) 67 | mainLayout.addWidget(self.one_folder_checkbox, 2, 2) 68 | mainLayout.addWidget(comicIntroLabel, 3, 0) 69 | mainLayout.addWidget(self.comicIntro, 3, 1, 1, 2) 70 | mainLayout.addWidget(chapterGroupBox, 4, 0, 1, 3) 71 | mainLayout.addWidget(self.downloadButton, 5, 2) 72 | mainLayout.addWidget(self.statusLabel, 5, 0, 1, 2) 73 | 74 | self.setLayout(mainLayout) 75 | self.setWindowTitle("腾讯漫画下载") 76 | self.setGeometry(400, 300, 800, 500) 77 | 78 | def setStatus(self, status): 79 | self.statusLabel.setText(status) 80 | 81 | def enableWidget(self, enable): 82 | widgets_list = [ 83 | self.downloadButton, 84 | self.nameLine, 85 | self.pathLine, 86 | self.chapterListView, 87 | self.analysisButton, 88 | self.browseButton, 89 | self.one_folder_checkbox 90 | ] 91 | for widget in widgets_list: 92 | widget.setEnabled(enable) 93 | 94 | if enable: 95 | self.downloadButton.setText('下载选中') 96 | self.chapterListView.setFocus() 97 | 98 | def getPath(self): 99 | path = str(QFileDialog.getExistingDirectory(self, "选择下载目录")) 100 | if path: 101 | self.pathLine.setText(path) 102 | 103 | def anaysisURL(self): 104 | url = self.nameLine.text() 105 | 106 | self.downloadButton.setEnabled(False) 107 | self.comicNameLabel.setText("暂无") 108 | self.comicIntro.setText("暂无") 109 | self.chapterListView.clear() 110 | self.chapterListView.setEnabled(False) 111 | 112 | try: 113 | if getComic.isLegelUrl(url): 114 | self.id = getComic.getId(url) 115 | self.comicName, self.comicIntrd, self.count, self.contentList = getComic.getContent(self.id) 116 | 117 | self.contentNameList = [] 118 | for item in self.contentList: 119 | self.contentNameList.append(item['name']) 120 | 121 | self.comicNameLabel.setText(self.comicName) 122 | self.comicIntro.setText(self.comicIntrd) 123 | self.chapterListView.setEnabled(True) 124 | self.downloadButton.setEnabled(True) 125 | self.chapterListView.setFocus() 126 | self.statusLabel.setText('选择要下载的章节后点击右侧按钮') 127 | 128 | for i in range(len(self.contentNameList)): 129 | self.chapterListView.addItem('第{0:0>4}话-{1}'.format(i + 1, self.contentNameList[i])) 130 | self.chapterListView.item(i).setSelected(True) 131 | 132 | self.downloadButton.setEnabled(True) 133 | 134 | else: 135 | self.statusLabel.setText('错误的URL格式!请输入正确的漫画首页地址!') 136 | except getComic.ErrorCode as e: 137 | if e.code == 2: 138 | self.statusLabel.setText('无法跳转为移动端URL,请进入http://m.ac.qq.com找到该漫画地址') 139 | except KeyError: 140 | self.statusLabel.setText('不存在的地址') 141 | except Exception as e: 142 | self.statusLabel.setText('{}'.format(e)) 143 | traceback.print_exc() 144 | 145 | def download(self): 146 | self.downloadButton.setText("下载中...") 147 | one_folder = self.one_folder_checkbox.isChecked() 148 | 149 | self.enableWidget(False) 150 | 151 | selectedChapterList = [item.row() for item in self.chapterListView.selectedIndexes()] 152 | 153 | path = self.pathLine.text() 154 | comicName = self.comicName 155 | forbiddenRE = re.compile(r'[\\/":*?<>|]') # windows下文件名非法字符\ / : * ? " < > | 156 | comicName = re.sub(forbiddenRE, '_', comicName) # 将windows下的非法字符一律替换为_ 157 | comicPath = os.path.join(path, comicName) 158 | 159 | if not os.path.isdir(comicPath): 160 | os.makedirs(comicPath) 161 | 162 | self.downloadThread = Downloader(selectedChapterList, comicPath, self.contentList, self.contentNameList, 163 | self.id, one_folder) 164 | self.downloadThread.output.connect(self.setStatus) 165 | self.downloadThread.finished.connect(lambda: self.enableWidget(True)) 166 | self.downloadThread.start() 167 | 168 | 169 | class Downloader(QThread): 170 | output = pyqtSignal(['QString']) 171 | finished = pyqtSignal() 172 | 173 | def __init__(self, selectedChapterList, comicPath, contentList, contentNameList, id, one_folder=False, parent=None): 174 | super(Downloader, self).__init__(parent) 175 | 176 | self.selectedChapterList = selectedChapterList 177 | self.comicPath = comicPath 178 | self.contentList = contentList 179 | self.contentNameList = contentNameList 180 | self.id = id 181 | self.one_folder = one_folder 182 | 183 | def run(self): 184 | try: 185 | for i in self.selectedChapterList: 186 | outputString = '正在下载第{0:0>4}话: {1}...'.format(i + 1, self.contentNameList[i]) 187 | print(outputString) 188 | self.output.emit(outputString) 189 | forbiddenRE = re.compile(r'[\\/":*?<>|]') # windows下文件名非法字符\ / : * ? " < > | 190 | self.contentNameList[i] = re.sub(forbiddenRE, '_', self.contentNameList[i]).strip() 191 | contentPath = os.path.join(self.comicPath, '第{0:0>4}话-{1}'.format(i + 1, self.contentNameList[i])) 192 | if not self.one_folder: 193 | if not os.path.isdir(contentPath): 194 | os.mkdir(contentPath) 195 | imgList = getComic.getImgList(self.contentList[i]['url']) 196 | getComic.downloadImg(imgList, contentPath, self.one_folder) 197 | 198 | self.output.emit('完毕!') 199 | 200 | except Exception as e: 201 | self.output.emit('{}\n' 202 | '遇到异常!请尝试重新点击下载按钮重试'.format(e)) 203 | raise 204 | 205 | finally: 206 | self.finished.emit() 207 | 208 | 209 | if __name__ == '__main__': 210 | app = QApplication(sys.argv) 211 | 212 | main = TencentComicDownloader() 213 | main.show() 214 | 215 | app.exec_() 216 | -------------------------------------------------------------------------------- /getComic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | '''***本代码仅供学习交流使用,严禁用于非法用途,各种PR都欢迎***''' 5 | 6 | import argparse 7 | import base64 8 | import json 9 | import os 10 | import re 11 | import threading 12 | from time import sleep 13 | 14 | import requests 15 | from lxml import html 16 | 17 | requestSession = requests.session() 18 | # Chrome on win10 19 | UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36' 20 | requestSession.headers.update({'User-Agent': UA}) 21 | 22 | 23 | class ErrorCode(Exception): 24 | '''自定义错误码: 25 | 1: URL不正确 26 | 2: URL无法跳转为移动端URL 27 | 3: 中断下载''' 28 | 29 | def __init__(self, code): 30 | self.code = code 31 | 32 | def __str__(self): 33 | return repr(self.code) 34 | 35 | 36 | def isLegelUrl(url): 37 | legal_url_list = [ 38 | re.compile(r'^https?://ac.qq.com/Comic/[Cc]omicInfo/id/\d+?'), 39 | re.compile(r'^https?://m.ac.qq.com/Comic/[Cc]omicInfo/id/\d+?'), 40 | re.compile(r'^https?://m.ac.qq.com/comic/index/id/\d+?'), 41 | re.compile(r'^https?://ac.qq.com/\w+/?$'), 42 | ] 43 | 44 | for legal_url in legal_url_list: 45 | if legal_url.match(url): 46 | return True 47 | return False 48 | 49 | 50 | def getId(url): 51 | if not isLegelUrl(url): 52 | print('请输入正确的url!具体支持的url请在命令行输入-h|--help参数查看帮助文档。') 53 | raise ErrorCode(1) 54 | 55 | numRE = re.compile(r'\d+$') 56 | 57 | id = numRE.findall(url) 58 | if not id: 59 | get_id_request = requestSession.get(url) 60 | url = get_id_request.url 61 | id = numRE.findall(url) 62 | if not isLegelUrl(url) or not id: 63 | print('无法自动跳转移动端URL,请进入http://m.ac.qq.com,找到' 64 | '该漫画地址。\n' 65 | '地址应该像这样: ' 66 | 'http://m.ac.qq.com/Comic/comicInfo/id/xxxxx (xxxxx为整数)') 67 | raise ErrorCode(2) 68 | 69 | return id[0] 70 | 71 | 72 | def getContent(id): 73 | comic_info_page = 'http://ac.qq.com/Comic/comicInfo/id/{}'.format(id) 74 | page = requestSession.get(comic_info_page).text 75 | tree = html.fromstring(page) 76 | comic_name_xpath = '//*[@id="special_bg"]/div[3]/div[1]/div[1]/div[2]/div[1]/div[1]/h2/strong/text()' 77 | comicName = tree.xpath(comic_name_xpath)[0].strip() 78 | comic_intro_xpath = '//*[@id="special_bg"]/div[3]/div[1]/div[1]/div[2]/div[1]/p[2]/text()' 79 | comicIntrd = tree.xpath(comic_intro_xpath)[0].strip() 80 | chapter_list_xpath = '//*[@id="chapter"]/div[2]/ol[1]/li/p/span/a' 81 | chapter_list = tree.xpath(chapter_list_xpath) 82 | count = len(chapter_list) 83 | sortedContentList = [] 84 | 85 | for chapter_element in chapter_list: 86 | sortedContentList.append( 87 | {'name': chapter_element.text.strip(), 'url': 'http://ac.qq.com' + chapter_element.get('href')}) 88 | 89 | return (comicName, comicIntrd, count, sortedContentList) 90 | 91 | 92 | def getImgList(chapter_url): 93 | retry_num = 0 94 | retry_max = 5 95 | while True: 96 | try: 97 | chapter_url = re.sub('ac.qq.com/ComicView', 'm.ac.qq.com/chapter', chapter_url, re.I) 98 | chapter_page = requestSession.get(chapter_url, timeout=5).text 99 | data = re.findall(r"data:\s*'(.+?)',", chapter_page)[0] 100 | nonce = re.findall(r'data-mpmvr="(.+?)"', chapter_page)[0] 101 | img_detail_json = __decode_data(data, nonce) 102 | imgList = [] 103 | for img_url in img_detail_json.get('picture'): 104 | imgList.append(re.sub(r'/\d+$', '/0', img_url['url'])) 105 | return imgList 106 | except (KeyboardInterrupt, SystemExit): 107 | print('\n\n中断下载!') 108 | raise ErrorCode(3) 109 | except: 110 | retry_num += 1 111 | if retry_num >= retry_max: 112 | raise 113 | print('下载失败,重试' + str(retry_num) + '次') 114 | sleep(2) 115 | 116 | return [] 117 | 118 | 119 | def downloadImg(imgUrlList, contentPath, one_folder=False): 120 | count = len(imgUrlList) 121 | print('该集漫画共计{}张图片'.format(count)) 122 | i = 1 123 | downloaded_num = 0 124 | 125 | def __download_callback(): 126 | nonlocal downloaded_num 127 | nonlocal count 128 | downloaded_num += 1 129 | print('\r{}/{}... '.format(downloaded_num, count), end='') 130 | 131 | download_threads = [] 132 | for imgUrl in imgUrlList: 133 | if not one_folder: 134 | imgPath = os.path.join(contentPath, '{0:0>3}.jpg'.format(i)) 135 | else: 136 | imgPath = contentPath + '{0:0>3}.jpg'.format(i) 137 | i += 1 138 | 139 | # 目标文件存在就跳过下载 140 | if os.path.isfile(imgPath): 141 | count -= 1 142 | continue 143 | download_thread = threading.Thread(target=__download_one_img, 144 | args=(imgUrl, imgPath, __download_callback)) 145 | download_threads.append(download_thread) 146 | download_thread.start() 147 | [t.join() for t in download_threads] 148 | print('完毕!\n') 149 | 150 | 151 | def __decode_data(data, nonce): 152 | t = list(data) 153 | n = re.findall(r'(\d+)([a-zA-Z]+)', nonce) 154 | n_len = len(n) 155 | index = n_len - 1 156 | while index >= 0: 157 | locate = int(n[index][0]) & 255 158 | del t[locate:locate + len(n[index][1])] 159 | index = index - 1 160 | 161 | base64_str = ''.join(t) 162 | json_str = base64.b64decode(base64_str).decode('utf-8') 163 | return json.loads(json_str) 164 | 165 | 166 | def __download_one_img(imgUrl, imgPath, callback): 167 | retry_num = 0 168 | retry_max = 2 169 | while True: 170 | try: 171 | downloadRequest = requestSession.get( 172 | imgUrl, stream=True, timeout=2) 173 | with open(imgPath, 'wb') as f: 174 | for chunk in downloadRequest.iter_content(chunk_size=1024): 175 | if chunk: # filter out keep-alive new chunks 176 | f.write(chunk) 177 | f.flush() 178 | callback() 179 | break 180 | except (KeyboardInterrupt, SystemExit): 181 | print('\n\n中断下载,删除未下载完的文件!') 182 | if os.path.isfile(imgPath): 183 | os.remove(imgPath) 184 | raise ErrorCode(3) 185 | except: 186 | retry_num += 1 187 | if retry_num >= retry_max: 188 | raise 189 | print('下载失败,重试' + str(retry_num) + '次') 190 | sleep(2) 191 | 192 | 193 | def parseLIST(lst): 194 | '''解析命令行中的-l|--list参数,返回解析后的章节列表''' 195 | legalListRE = re.compile(r'^\d+([,-]\d+)*$') 196 | if not legalListRE.match(lst): 197 | raise AttributeError(lst + ' 不匹配正则: ' + r'^\d+([,-]\d+)*$') 198 | 199 | # 先逗号分割字符串,分割后的字符串再用短横杠分割 200 | parsedLIST = [] 201 | sublist = lst.split(',') 202 | numRE = re.compile(r'^\d+$') 203 | 204 | for sub in sublist: 205 | if numRE.match(sub): 206 | if int(sub) > 0: # 自动忽略掉数字0 207 | parsedLIST.append(int(sub)) 208 | else: 209 | print('警告: 参数中包括不存在的章节0,自动忽略') 210 | else: 211 | splitnum = list(map(int, sub.split('-'))) 212 | maxnum = max(splitnum) 213 | minnum = min(splitnum) # min-max或max-min都支持 214 | if minnum == 0: 215 | minnum = 1 # 忽略数字0 216 | print('警告: 参数中包括不存在的章节0,自动忽略') 217 | parsedLIST.extend(range(minnum, maxnum + 1)) 218 | 219 | parsedLIST = sorted(set(parsedLIST)) # 按照从小到大的顺序排序并去重 220 | return parsedLIST 221 | 222 | 223 | def main(url, path, lst=None, one_folder=False): 224 | '''url: 要爬取的漫画首页。 path: 漫画下载路径。 lst: 要下载的章节列表(-l|--list后面的参数)''' 225 | try: 226 | if not os.path.isdir(path): 227 | os.makedirs(path) 228 | id = getId(url) 229 | comicName, comicIntrd, count, contentList = getContent(id) 230 | contentNameList = [] 231 | for item in contentList: 232 | contentNameList.append(item['name']) 233 | print('漫画名: {}'.format(comicName)) 234 | print('简介: {}'.format(comicIntrd)) 235 | print('章节数: {}'.format(count)) 236 | print('章节列表:') 237 | try: 238 | print('\n'.join(contentNameList)) 239 | except Exception: 240 | print('章节列表包含无法解析的特殊字符\n') 241 | 242 | # windows下文件名非法字符\ / : * ? " < > | 243 | forbiddenRE = re.compile(r'[\\/":*?<>|]') 244 | comicName = re.sub(forbiddenRE, '_', comicName) # 将windows下的非法字符一律替换为_ 245 | comicPath = os.path.join(path, comicName) 246 | if not os.path.isdir(comicPath): 247 | os.makedirs(comicPath) 248 | print() 249 | 250 | listpath = comicPath + '/list.txt' 251 | listfile = open(listpath, mode='w', errors='replace') 252 | listfile.write('漫画名: {}'.format(comicName) + '\n') 253 | listfile.write('简介: {}'.format(comicIntrd) + '\n') 254 | listfile.write('章节数: {}'.format(count) + '\n') 255 | listfile.write('章节列表:' + '\n') 256 | try: 257 | listfile.write('\n'.join(contentNameList)) 258 | except Exception: 259 | listfile.write('章节列表包含无法解析的特殊字符\n') 260 | 261 | listfile.close() 262 | 263 | if not lst: 264 | contentRange = range(1, len(contentList) + 1) 265 | else: 266 | contentRange = parseLIST(lst) 267 | 268 | for i in contentRange: 269 | if i > len(contentList): 270 | print('警告: 章节总数 {} ,' 271 | '参数中包含过大数值,' 272 | '自动忽略'.format(len(contentList))) 273 | break 274 | 275 | # 将windows下的非法字符一律替换为_ 276 | contentNameList[i - 1] = re.sub(forbiddenRE, 277 | '_', contentNameList[i - 1]).strip() 278 | contentPath = os.path.join( 279 | comicPath, '第{0:0>4}话-{1}'.format(i, contentNameList[i - 1])) 280 | 281 | try: 282 | print('正在下载第{0:0>4}话: {1}'.format(i, contentNameList[i - 1])) 283 | except Exception: 284 | print('正在下载第{0:0>4}话: {0}'.format(i)) 285 | 286 | if not one_folder: 287 | if not os.path.isdir(contentPath): 288 | os.mkdir(contentPath) 289 | 290 | imgList = getImgList(contentList[i - 1]['url']) 291 | downloadImg(imgList, contentPath, one_folder) 292 | 293 | except ErrorCode as e: 294 | exit(e.code) 295 | 296 | 297 | if __name__ == '__main__': 298 | defaultPath = os.path.join(os.path.expanduser('~'), 'tencent_comic') 299 | 300 | parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, 301 | description='*下载腾讯漫画,仅供学习交流,请勿用于非法用途*\n' 302 | '空参运行进入交互式模式运行。') 303 | parser.add_argument('-u', '--url', help='要下载的漫画的首页,可以下载以下类型的url: \n' 304 | 'http://ac.qq.com/Comic/comicInfo/id/511915\n' 305 | 'http://m.ac.qq.com/comic/index/id/505430\n' 306 | 'http://ac.qq.com/naruto') 307 | parser.add_argument('-p', '--path', help='漫画下载路径。 默认: {}'.format(defaultPath), 308 | default=defaultPath) 309 | parser.add_argument('-d', '--dir', action='store_true', 310 | help='将所有图片下载到一个目录(适合腾讯漫画等软件连看使用)') 311 | parser.add_argument('-l', '--list', help=("要下载的漫画章节列表,不指定则下载所有章节。格式范例: \n" 312 | "N - 下载具体某一章节,如-l 1, 下载第1章\n" 313 | 'N,N... - 下载某几个不连续的章节,如 "-l 1,3,5", 下载1,3,5章\n' 314 | 'N-N... - 下载某一段连续的章节,如 "-l 10-50", 下载[10,50]章\n' 315 | '杂合型 - 结合上面所有的规则,如 "-l 1,3,5-7,11-111"')) 316 | args = parser.parse_args() 317 | url = args.url 318 | path = args.path 319 | lst = args.list 320 | one_folder = args.dir 321 | 322 | if lst: 323 | legalListRE = re.compile(r'^\d+([,-]\d+)*$') 324 | if not legalListRE.match(lst): 325 | print('LIST参数不合法,请参考--help键入合法参数!') 326 | exit(1) 327 | 328 | if not url: 329 | url = input('请输入漫画首页地址: ') 330 | path = input('请输入漫画保存路径(默认: {}): '.format(defaultPath)) 331 | if not path: 332 | path = defaultPath 333 | 334 | main(url, path, lst, one_folder) 335 | -------------------------------------------------------------------------------- /list.txt: -------------------------------------------------------------------------------- 1 | 10008 2 | 1002 3 | 101 4 | 10113 5 | 1013 6 | 10192 7 | 1028 8 | 10334 9 | 10350 10 | 10460 11 | 10484 12 | 10541 13 | 1058 14 | 10595 15 | 10654 16 | 10709 17 | 10803 18 | 10836 19 | 1086 20 | 10967 21 | 10988 22 | 11000 23 | 11029 24 | 11268 25 | 11368 26 | 11513 27 | 1156 28 | 11635 29 | 11640 30 | 11675 31 | 1169 32 | 1184 33 | 12003 34 | 12033 35 | 1205 36 | 12139 37 | 1216 38 | 12168 39 | 1225 40 | 12326 41 | 12343 42 | 12352 43 | 12401 44 | 12566 45 | 12687 46 | 12750 47 | 12855 48 | 129 49 | 13016 50 | 13054 51 | 1307 52 | 1311 53 | 13132 54 | 13135 55 | 13142 56 | 13176 57 | 132 58 | 13211 59 | 13214 60 | 1322 61 | 13232 62 | 13240 63 | 13307 64 | 13605 65 | 1369 66 | 1370 67 | 13827 68 | 13847 69 | 138606 70 | 13919 71 | 13959 72 | 14008 73 | 14081 74 | 14328 75 | 14471 76 | 14486 77 | 14509 78 | 14535 79 | 14679 80 | 14717 81 | 14777 82 | 1478 83 | 14812 84 | 1490 85 | 1493 86 | 14956 87 | 15102 88 | 15125 89 | 1529 90 | 1531 91 | 1533 92 | 15502 93 | 15652 94 | 15664 95 | 15750 96 | 15807 97 | 15833 98 | 15836 99 | 15906 100 | 16043 101 | 1621 102 | 16214 103 | 16375 104 | 16377 105 | 16419 106 | 16448 107 | 16604 108 | 16629 109 | 1676 110 | 16766 111 | 16949 112 | 17017 113 | 17031 114 | 17034 115 | 17037 116 | 17080 117 | 17097 118 | 17114 119 | 17122 120 | 17428 121 | 1743 122 | 17477 123 | 1792 124 | 1808 125 | 1820 126 | 1904 127 | 194129 128 | 2026 129 | 2037 130 | 2125 131 | 2136 132 | 214 133 | 2167 134 | 2168 135 | 2171 136 | 2184 137 | 2228 138 | 2309 139 | 2310 140 | 2324 141 | 2403 142 | 2432 143 | 2481 144 | 249669 145 | 2506 146 | 2656 147 | 2673 148 | 2689 149 | 273 150 | 275832 151 | 2769 152 | 28 153 | 283 154 | 2869 155 | 2871 156 | 2920 157 | 293 158 | 2995 159 | 2998 160 | 3028 161 | 3154 162 | 3155 163 | 316 164 | 3177 165 | 318317 166 | 3197 167 | 3210 168 | 3275 169 | 331384 170 | 3351 171 | 3389 172 | 350971 173 | 3541 174 | 35457 175 | 35495 176 | 3553 177 | 357508 178 | 3612 179 | 3637 180 | 3703 181 | 373851 182 | 3839 183 | 3850 184 | 3928 185 | 3947 186 | 3953 187 | 40 188 | 4068 189 | 409778 190 | 4188 191 | 425 192 | 4286 193 | 4327 194 | 4455 195 | 45 196 | 452253 197 | 4560 198 | 4576 199 | 458824 200 | 458830 201 | 458837 202 | 458844 203 | 458850 204 | 458924 205 | 459053 206 | 459069 207 | 459076 208 | 459131 209 | 459141 210 | 459144 211 | 459154 212 | 459255 213 | 459294 214 | 459300 215 | 459320 216 | 459356 217 | 459387 218 | 459407 219 | 459523 220 | 459525 221 | 459586 222 | 459607 223 | 459708 224 | 459722 225 | 459733 226 | 459734 227 | 459743 228 | 459757 229 | 459796 230 | 459926 231 | 459948 232 | 459955 233 | 459990 234 | 46 235 | 460001 236 | 460018 237 | 460066 238 | 460073 239 | 460085 240 | 460086 241 | 460101 242 | 460114 243 | 460157 244 | 460211 245 | 460231 246 | 460233 247 | 462033 248 | 4629 249 | 463735 250 | 463764 251 | 463778 252 | 463858 253 | 464033 254 | 464061 255 | 464174 256 | 464240 257 | 464324 258 | 467344 259 | 4684 260 | 4698 261 | 476523 262 | 4785 263 | 4797 264 | 4798 265 | 480176 266 | 480475 267 | 480487 268 | 480578 269 | 480604 270 | 480659 271 | 480670 272 | 480680 273 | 480732 274 | 480753 275 | 480784 276 | 480810 277 | 480959 278 | 481014 279 | 481018 280 | 481052 281 | 481058 282 | 481103 283 | 481738 284 | 481753 285 | 483414 286 | 484269 287 | 484828 288 | 485140 289 | 485284 290 | 485374 291 | 485402 292 | 485527 293 | 485538 294 | 485668 295 | 485830 296 | 486028 297 | 486084 298 | 486186 299 | 488086 300 | 4881 301 | 488139 302 | 488174 303 | 488692 304 | 488768 305 | 489670 306 | 49 307 | 490952 308 | 490962 309 | 490964 310 | 490978 311 | 491203 312 | 491299 313 | 491566 314 | 491585 315 | 4916 316 | 491608 317 | 491612 318 | 491828 319 | 492256 320 | 492459 321 | 492516 322 | 492617 323 | 492698 324 | 492788 325 | 492797 326 | 492894 327 | 493108 328 | 493121 329 | 493132 330 | 493148 331 | 493211 332 | 493257 333 | 493434 334 | 493492 335 | 493523 336 | 493530 337 | 493542 338 | 493658 339 | 493674 340 | 493785 341 | 493930 342 | 493982 343 | 494007 344 | 494012 345 | 494013 346 | 494189 347 | 494393 348 | 494418 349 | 494540 350 | 494713 351 | 494751 352 | 494757 353 | 494844 354 | 494852 355 | 494859 356 | 494941 357 | 494954 358 | 494976 359 | 494998 360 | 4950 361 | 495003 362 | 495029 363 | 495145 364 | 495173 365 | 495821 366 | 495942 367 | 496 368 | 500412 369 | 500467 370 | 500560 371 | 500642 372 | 500647 373 | 500657 374 | 500658 375 | 500696 376 | 500725 377 | 500733 378 | 500735 379 | 500778 380 | 500798 381 | 500836 382 | 500879 383 | 500934 384 | 500959 385 | 500972 386 | 500973 387 | 501043 388 | 501071 389 | 501105 390 | 501175 391 | 501269 392 | 501277 393 | 501283 394 | 501292 395 | 501317 396 | 501321 397 | 501326 398 | 501356 399 | 501359 400 | 501453 401 | 501465 402 | 501480 403 | 501591 404 | 501661 405 | 501665 406 | 501738 407 | 501748 408 | 501913 409 | 502085 410 | 502171 411 | 502325 412 | 503650 413 | 504224 414 | 5044 415 | 505250 416 | 505260 417 | 505267 418 | 505281 419 | 505305 420 | 505322 421 | 505331 422 | 505403 423 | 505430 424 | 505431 425 | 505432 426 | 505433 427 | 505435 428 | 505436 429 | 505437 430 | 505439 431 | 505440 432 | 505441 433 | 505579 434 | 505730 435 | 505822 436 | 505903 437 | 505980 438 | 506033 439 | 506037 440 | 506135 441 | 506170 442 | 506223 443 | 506248 444 | 506367 445 | 506392 446 | 506438 447 | 506582 448 | 506584 449 | 506629 450 | 506630 451 | 5067 452 | 506703 453 | 506783 454 | 506845 455 | 506863 456 | 506913 457 | 506924 458 | 507186 459 | 507413 460 | 507440 461 | 507599 462 | 507641 463 | 507679 464 | 507710 465 | 507831 466 | 507960 467 | 508127 468 | 508167 469 | 508207 470 | 508224 471 | 508290 472 | 508294 473 | 508379 474 | 508403 475 | 508477 476 | 508555 477 | 508557 478 | 508573 479 | 508649 480 | 508766 481 | 508831 482 | 508898 483 | 508912 484 | 508944 485 | 508969 486 | 509097 487 | 509104 488 | 509200 489 | 509212 490 | 509220 491 | 509223 492 | 509235 493 | 509250 494 | 509305 495 | 509366 496 | 509489 497 | 509513 498 | 509582 499 | 509796 500 | 509835 501 | 509858 502 | 509895 503 | 509910 504 | 510045 505 | 510055 506 | 510068 507 | 510099 508 | 510286 509 | 510331 510 | 510337 511 | 510342 512 | 510353 513 | 510459 514 | 510482 515 | 510533 516 | 510582 517 | 510600 518 | 510624 519 | 510651 520 | 510761 521 | 510897 522 | 510930 523 | 510934 524 | 510943 525 | 511 526 | 511230 527 | 511240 528 | 511296 529 | 511602 530 | 511612 531 | 511655 532 | 511723 533 | 511752 534 | 511768 535 | 511769 536 | 511772 537 | 511815 538 | 511915 539 | 511938 540 | 511972 541 | 511981 542 | 511983 543 | 512038 544 | 512063 545 | 512069 546 | 512071 547 | 512117 548 | 512191 549 | 512215 550 | 512223 551 | 512235 552 | 512270 553 | 512374 554 | 512375 555 | 512446 556 | 512458 557 | 512541 558 | 512646 559 | 512650 560 | 512742 561 | 512750 562 | 512782 563 | 512864 564 | 512923 565 | 512929 566 | 513034 567 | 513045 568 | 513055 569 | 513072 570 | 513164 571 | 513182 572 | 513226 573 | 517485 574 | 517772 575 | 517789 576 | 517812 577 | 517817 578 | 517818 579 | 517830 580 | 517831 581 | 517832 582 | 517860 583 | 517979 584 | 517992 585 | 518028 586 | 518030 587 | 518100 588 | 518125 589 | 518220 590 | 518227 591 | 518305 592 | 518333 593 | 518335 594 | 518367 595 | 518374 596 | 518480 597 | 518580 598 | 51862 599 | 518720 600 | 518787 601 | 518797 602 | 518913 603 | 518953 604 | 519002 605 | 519006 606 | 519131 607 | 519143 608 | 519152 609 | 519274 610 | 519289 611 | 519341 612 | 519344 613 | 519451 614 | 519453 615 | 519486 616 | 519531 617 | 519544 618 | 519588 619 | 519593 620 | 519617 621 | 519637 622 | 519640 623 | 519641 624 | 519657 625 | 519687 626 | 519711 627 | 519818 628 | 519855 629 | 519857 630 | 519874 631 | 519878 632 | 519882 633 | 519899 634 | 519983 635 | 520023 636 | 520068 637 | 520087 638 | 520270 639 | 520392 640 | 5205 641 | 520552 642 | 520561 643 | 520633 644 | 520649 645 | 520720 646 | 520815 647 | 520829 648 | 520852 649 | 520853 650 | 520862 651 | 520899 652 | 520918 653 | 520922 654 | 520981 655 | 520995 656 | 521056 657 | 521069 658 | 521071 659 | 521131 660 | 521212 661 | 521232 662 | 521241 663 | 521254 664 | 521445 665 | 521464 666 | 521494 667 | 521501 668 | 521550 669 | 521554 670 | 521567 671 | 521600 672 | 521643 673 | 521644 674 | 521659 675 | 521669 676 | 521699 677 | 521717 678 | 521825 679 | 521882 680 | 521895 681 | 521900 682 | 521974 683 | 522009 684 | 522034 685 | 522101 686 | 522109 687 | 522110 688 | 522134 689 | 522238 690 | 522270 691 | 522309 692 | 522324 693 | 522330 694 | 522334 695 | 522337 696 | 522388 697 | 522412 698 | 522450 699 | 522472 700 | 522493 701 | 522516 702 | 522706 703 | 522715 704 | 522717 705 | 522796 706 | 522852 707 | 522894 708 | 522898 709 | 522900 710 | 522923 711 | 522924 712 | 522930 713 | 522934 714 | 522945 715 | 523000 716 | 523039 717 | 523120 718 | 523194 719 | 523195 720 | 523219 721 | 523270 722 | 523296 723 | 523365 724 | 523432 725 | 523473 726 | 523511 727 | 523516 728 | 523556 729 | 523565 730 | 523589 731 | 523664 732 | 523670 733 | 523678 734 | 523703 735 | 523874 736 | 523883 737 | 524019 738 | 524058 739 | 524059 740 | 524081 741 | 524126 742 | 524190 743 | 524195 744 | 524197 745 | 524201 746 | 524260 747 | 524262 748 | 524274 749 | 524276 750 | 524277 751 | 524330 752 | 524333 753 | 524356 754 | 524372 755 | 524397 756 | 524398 757 | 524486 758 | 524503 759 | 524567 760 | 524572 761 | 524598 762 | 524626 763 | 524742 764 | 524750 765 | 524777 766 | 524839 767 | 524859 768 | 524898 769 | 524917 770 | 524934 771 | 524951 772 | 524978 773 | 524981 774 | 525099 775 | 525113 776 | 525176 777 | 525197 778 | 525198 779 | 525223 780 | 525230 781 | 525238 782 | 525301 783 | 525311 784 | 525347 785 | 525358 786 | 525368 787 | 525382 788 | 525393 789 | 525406 790 | 525469 791 | 525487 792 | 525535 793 | 525550 794 | 525791 795 | 525796 796 | 525824 797 | 525912 798 | 525918 799 | 525943 800 | 525966 801 | 525971 802 | 526037 803 | 526060 804 | 526081 805 | 526117 806 | 526122 807 | 526230 808 | 526233 809 | 526256 810 | 526265 811 | 526270 812 | 526287 813 | 526293 814 | 526307 815 | 526318 816 | 526319 817 | 526320 818 | 526342 819 | 526465 820 | 526501 821 | 526553 822 | 526554 823 | 526585 824 | 526587 825 | 526599 826 | 526625 827 | 526629 828 | 526656 829 | 526697 830 | 526730 831 | 526755 832 | 526771 833 | 526780 834 | 526802 835 | 526811 836 | 526891 837 | 526948 838 | 526949 839 | 526996 840 | 527057 841 | 527078 842 | 527104 843 | 527173 844 | 527178 845 | 527202 846 | 527211 847 | 527276 848 | 527277 849 | 527311 850 | 527331 851 | 527494 852 | 527579 853 | 527580 854 | 527842 855 | 527843 856 | 527938 857 | 528287 858 | 528458 859 | 528584 860 | 528618 861 | 528695 862 | 528722 863 | 528744 864 | 528757 865 | 528762 866 | 528911 867 | 528943 868 | 528962 869 | 528976 870 | 528983 871 | 529028 872 | 529271 873 | 529317 874 | 529457 875 | 529460 876 | 5295 877 | 529504 878 | 529543 879 | 529554 880 | 529566 881 | 529617 882 | 529638 883 | 529683 884 | 529684 885 | 529693 886 | 5297 887 | 529810 888 | 529880 889 | 529907 890 | 529946 891 | 530129 892 | 530131 893 | 530132 894 | 530203 895 | 530257 896 | 530390 897 | 530406 898 | 530449 899 | 530456 900 | 530563 901 | 530568 902 | 530591 903 | 530763 904 | 530772 905 | 530780 906 | 530817 907 | 530836 908 | 530846 909 | 530851 910 | 530858 911 | 530859 912 | 530869 913 | 530875 914 | 530876 915 | 530890 916 | 530897 917 | 530928 918 | 530950 919 | 530952 920 | 530955 921 | 530960 922 | 530969 923 | 530983 924 | 530985 925 | 530986 926 | 530987 927 | 530988 928 | 530989 929 | 531027 930 | 531031 931 | 531036 932 | 531040 933 | 531049 934 | 531050 935 | 531051 936 | 531052 937 | 531053 938 | 531067 939 | 531068 940 | 531070 941 | 531071 942 | 531074 943 | 531077 944 | 531080 945 | 531081 946 | 531088 947 | 531091 948 | 531098 949 | 531101 950 | 531113 951 | 531155 952 | 531188 953 | 531193 954 | 531220 955 | 531236 956 | 531241 957 | 531242 958 | 531245 959 | 531257 960 | 531275 961 | 531278 962 | 531303 963 | 531308 964 | 531327 965 | 531328 966 | 531329 967 | 531330 968 | 531334 969 | 531349 970 | 531375 971 | 531390 972 | 531475 973 | 531490 974 | 531500 975 | 531507 976 | 531509 977 | 531522 978 | 531527 979 | 531560 980 | 531583 981 | 531609 982 | 531615 983 | 531616 984 | 531617 985 | 531618 986 | 531619 987 | 531620 988 | 531621 989 | 531647 990 | 531714 991 | 531716 992 | 531723 993 | 531754 994 | 531773 995 | 531789 996 | 531790 997 | 531813 998 | 531821 999 | 531823 1000 | 531834 1001 | 531839 1002 | 531851 1003 | 531886 1004 | 531894 1005 | 531904 1006 | 531907 1007 | 531920 1008 | 531970 1009 | 532022 1010 | 532031 1011 | 532047 1012 | 532055 1013 | 532071 1014 | 532083 1015 | 532088 1016 | 532099 1017 | 532135 1018 | 532189 1019 | 532201 1020 | 532211 1021 | 532212 1022 | 532220 1023 | 532231 1024 | 532260 1025 | 532276 1026 | 532308 1027 | 532310 1028 | 532311 1029 | 532312 1030 | 532313 1031 | 532317 1032 | 532319 1033 | 532347 1034 | 532388 1035 | 532395 1036 | 532450 1037 | 532474 1038 | 532490 1039 | 532493 1040 | 532496 1041 | 532515 1042 | 532524 1043 | 532533 1044 | 532655 1045 | 532656 1046 | 532661 1047 | 532669 1048 | 532686 1049 | 532687 1050 | 532688 1051 | 532689 1052 | 532690 1053 | 532691 1054 | 532704 1055 | 532707 1056 | 532712 1057 | 532730 1058 | 532784 1059 | 532797 1060 | 532798 1061 | 532828 1062 | 532837 1063 | 532849 1064 | 532864 1065 | 532935 1066 | 532945 1067 | 532958 1068 | 532970 1069 | 532977 1070 | 532992 1071 | 533022 1072 | 533025 1073 | 533045 1074 | 533048 1075 | 533049 1076 | 533052 1077 | 533053 1078 | 533054 1079 | 533065 1080 | 533068 1081 | 533076 1082 | 533077 1083 | 533086 1084 | 533096 1085 | 533131 1086 | 533190 1087 | 533223 1088 | 533236 1089 | 533278 1090 | 533297 1091 | 533303 1092 | 533318 1093 | 533319 1094 | 533374 1095 | 533375 1096 | 533376 1097 | 533395 1098 | 533426 1099 | 533446 1100 | 533494 1101 | 533538 1102 | 533555 1103 | 533632 1104 | 533639 1105 | 533667 1106 | 533696 1107 | 533697 1108 | 533756 1109 | 533790 1110 | 533814 1111 | 533834 1112 | 533847 1113 | 533864 1114 | 533920 1115 | 533935 1116 | 533952 1117 | 533970 1118 | 533980 1119 | 533987 1120 | 534004 1121 | 534012 1122 | 534013 1123 | 534014 1124 | 534016 1125 | 534019 1126 | 534026 1127 | 534028 1128 | 534035 1129 | 534036 1130 | 534055 1131 | 534059 1132 | 534062 1133 | 534080 1134 | 534098 1135 | 534103 1136 | 534105 1137 | 534127 1138 | 534146 1139 | 534178 1140 | 534234 1141 | 534246 1142 | 534258 1143 | 534297 1144 | 534422 1145 | 534434 1146 | 534470 1147 | 534471 1148 | 534536 1149 | 534584 1150 | 534585 1151 | 534639 1152 | 534640 1153 | 534641 1154 | 534642 1155 | 534643 1156 | 534645 1157 | 534651 1158 | 534658 1159 | 534674 1160 | 534676 1161 | 534679 1162 | 534680 1163 | 534682 1164 | 534687 1165 | 534690 1166 | 534705 1167 | 534741 1168 | 534796 1169 | 534823 1170 | 534824 1171 | 534826 1172 | 534853 1173 | 534859 1174 | 534879 1175 | 534881 1176 | 534888 1177 | 534894 1178 | 534902 1179 | 534906 1180 | 534910 1181 | 534913 1182 | 534925 1183 | 534929 1184 | 534983 1185 | 534994 1186 | 534999 1187 | 535040 1188 | 535064 1189 | 535068 1190 | 535072 1191 | 535102 1192 | 535190 1193 | 535197 1194 | 535282 1195 | 535283 1196 | 535301 1197 | 535331 1198 | 535342 1199 | 535350 1200 | 535402 1201 | 535434 1202 | 535435 1203 | 535445 1204 | 535461 1205 | 535482 1206 | 535495 1207 | 535505 1208 | 535537 1209 | 535555 1210 | 535587 1211 | 535619 1212 | 535662 1213 | 535674 1214 | 535684 1215 | 535687 1216 | 535690 1217 | 535695 1218 | 535698 1219 | 535728 1220 | 535731 1221 | 535934 1222 | 535959 1223 | 535962 1224 | 535974 1225 | 536042 1226 | 536069 1227 | 536074 1228 | 536079 1229 | 536084 1230 | 536097 1231 | 536103 1232 | 536107 1233 | 536117 1234 | 536126 1235 | 536131 1236 | 536137 1237 | 536146 1238 | 536159 1239 | 536169 1240 | 536176 1241 | 536202 1242 | 536207 1243 | 536274 1244 | 536332 1245 | 536334 1246 | 536344 1247 | 536345 1248 | 536350 1249 | 5364 1250 | 536418 1251 | 536428 1252 | 536435 1253 | 536438 1254 | 536440 1255 | 536445 1256 | 536465 1257 | 536626 1258 | 536634 1259 | 536643 1260 | 536658 1261 | 536665 1262 | 536669 1263 | 536699 1264 | 536705 1265 | 536716 1266 | 536723 1267 | 536726 1268 | 536740 1269 | 536752 1270 | 536757 1271 | 536761 1272 | 536793 1273 | 536897 1274 | 536901 1275 | 536921 1276 | 536946 1277 | 537006 1278 | 537007 1279 | 537015 1280 | 537024 1281 | 537025 1282 | 537042 1283 | 537046 1284 | 537052 1285 | 537053 1286 | 537057 1287 | 537084 1288 | 537142 1289 | 537155 1290 | 537165 1291 | 537175 1292 | 537367 1293 | 537464 1294 | 537476 1295 | 537498 1296 | 537515 1297 | 537558 1298 | 537602 1299 | 537607 1300 | 537613 1301 | 537626 1302 | 537634 1303 | 537635 1304 | 537636 1305 | 537639 1306 | 537640 1307 | 537646 1308 | 537647 1309 | 537649 1310 | 537652 1311 | 537666 1312 | 537667 1313 | 537668 1314 | 537669 1315 | 537670 1316 | 537671 1317 | 537676 1318 | 537677 1319 | 537678 1320 | 537695 1321 | 537697 1322 | 537706 1323 | 537711 1324 | 537719 1325 | 537737 1326 | 537741 1327 | 537783 1328 | 537789 1329 | 537791 1330 | 537804 1331 | 537832 1332 | 537885 1333 | 537899 1334 | 537900 1335 | 537922 1336 | 537956 1337 | 537982 1338 | 538004 1339 | 538013 1340 | 538028 1341 | 538048 1342 | 538068 1343 | 538077 1344 | 538132 1345 | 538133 1346 | 538156 1347 | 538162 1348 | 538187 1349 | 538189 1350 | 538197 1351 | 538221 1352 | 538242 1353 | 538301 1354 | 538315 1355 | 538341 1356 | 538351 1357 | 538359 1358 | 538407 1359 | 538438 1360 | 538449 1361 | 538452 1362 | 538477 1363 | 538483 1364 | 538499 1365 | 538504 1366 | 538521 1367 | 538537 1368 | 538544 1369 | 538556 1370 | 538564 1371 | 538565 1372 | 538566 1373 | 538574 1374 | 538611 1375 | 538660 1376 | 538669 1377 | 538710 1378 | 538714 1379 | 538715 1380 | 538716 1381 | 538717 1382 | 538745 1383 | 538776 1384 | 538785 1385 | 538787 1386 | 538866 1387 | 538950 1388 | 538954 1389 | 538957 1390 | 538969 1391 | 538975 1392 | 539002 1393 | 539046 1394 | 539047 1395 | 539051 1396 | 539052 1397 | 539055 1398 | 539082 1399 | 539111 1400 | 539114 1401 | 539166 1402 | 539247 1403 | 539255 1404 | 539270 1405 | 539336 1406 | 539419 1407 | 539431 1408 | 539512 1409 | 539559 1410 | 539665 1411 | 539697 1412 | 539707 1413 | 540117 1414 | 540119 1415 | 540120 1416 | 540123 1417 | 540148 1418 | 540149 1419 | 540155 1420 | 540222 1421 | 540255 1422 | 540256 1423 | 540286 1424 | 540287 1425 | 540301 1426 | 540339 1427 | 540361 1428 | 540414 1429 | 540432 1430 | 540445 1431 | 540450 1432 | 540471 1433 | 540472 1434 | 540473 1435 | 540487 1436 | 540495 1437 | 540523 1438 | 540527 1439 | 540577 1440 | 540582 1441 | 540613 1442 | 540625 1443 | 540627 1444 | 540632 1445 | 540654 1446 | 540689 1447 | 540693 1448 | 540704 1449 | 540805 1450 | 540826 1451 | 540833 1452 | 540846 1453 | 540876 1454 | 540895 1455 | 540897 1456 | 540898 1457 | 540902 1458 | 540905 1459 | 540918 1460 | 540921 1461 | 540922 1462 | 540929 1463 | 540933 1464 | 540939 1465 | 540961 1466 | 540981 1467 | 541000 1468 | 541060 1469 | 541077 1470 | 541083 1471 | 541094 1472 | 541140 1473 | 541146 1474 | 541189 1475 | 541197 1476 | 541200 1477 | 541224 1478 | 541327 1479 | 541330 1480 | 541342 1481 | 541345 1482 | 541360 1483 | 541390 1484 | 541392 1485 | 541404 1486 | 541412 1487 | 541413 1488 | 541417 1489 | 541452 1490 | 541523 1491 | 541598 1492 | 541638 1493 | 541640 1494 | 541643 1495 | 541694 1496 | 541749 1497 | 541776 1498 | 541779 1499 | 541782 1500 | 541785 1501 | 541789 1502 | 541798 1503 | 541812 1504 | 541829 1505 | 541854 1506 | 541889 1507 | 541918 1508 | 541976 1509 | 541999 1510 | 542003 1511 | 542005 1512 | 542007 1513 | 542010 1514 | 542011 1515 | 542013 1516 | 542021 1517 | 542023 1518 | 542031 1519 | 542056 1520 | 542063 1521 | 542077 1522 | 542087 1523 | 542090 1524 | 542092 1525 | 542096 1526 | 542098 1527 | 542120 1528 | 542121 1529 | 542132 1530 | 542166 1531 | 542175 1532 | 5422 1533 | 542203 1534 | 542206 1535 | 542234 1536 | 542241 1537 | 542243 1538 | 542251 1539 | 542252 1540 | 542255 1541 | 542259 1542 | 542264 1543 | 542296 1544 | 542311 1545 | 542316 1546 | 542325 1547 | 542330 1548 | 542335 1549 | 542347 1550 | 542356 1551 | 542367 1552 | 542405 1553 | 542422 1554 | 542447 1555 | 542449 1556 | 542470 1557 | 542471 1558 | 542484 1559 | 542489 1560 | 542511 1561 | 542516 1562 | 542527 1563 | 542532 1564 | 542553 1565 | 542566 1566 | 542609 1567 | 542638 1568 | 542640 1569 | 542660 1570 | 542671 1571 | 542691 1572 | 542716 1573 | 542717 1574 | 542721 1575 | 542724 1576 | 542728 1577 | 542787 1578 | 542860 1579 | 542861 1580 | 542904 1581 | 542945 1582 | 542948 1583 | 542956 1584 | 542973 1585 | 542974 1586 | 542975 1587 | 542976 1588 | 542977 1589 | 542978 1590 | 542983 1591 | 542999 1592 | 543003 1593 | 543036 1594 | 543063 1595 | 543078 1596 | 543118 1597 | 543122 1598 | 543124 1599 | 543131 1600 | 543146 1601 | 543159 1602 | 543166 1603 | 543172 1604 | 543194 1605 | 543206 1606 | 543209 1607 | 543215 1608 | 543234 1609 | 543292 1610 | 543305 1611 | 543317 1612 | 543343 1613 | 543388 1614 | 543396 1615 | 543400 1616 | 543401 1617 | 543402 1618 | 543413 1619 | 543421 1620 | 543442 1621 | 543446 1622 | 543505 1623 | 543507 1624 | 543523 1625 | 543534 1626 | 543541 1627 | 543552 1628 | 543570 1629 | 543578 1630 | 543584 1631 | 543594 1632 | 543605 1633 | 543612 1634 | 543633 1635 | 543718 1636 | 543734 1637 | 543736 1638 | 543737 1639 | 543740 1640 | 543759 1641 | 543776 1642 | 543785 1643 | 543801 1644 | 543802 1645 | 543808 1646 | 543810 1647 | 543814 1648 | 543817 1649 | 543820 1650 | 543832 1651 | 543835 1652 | 543836 1653 | 543837 1654 | 543838 1655 | 543848 1656 | 543850 1657 | 543877 1658 | 543878 1659 | 543890 1660 | 543896 1661 | 543906 1662 | 543911 1663 | 543938 1664 | 543942 1665 | 543971 1666 | 543986 1667 | 544023 1668 | 544026 1669 | 544034 1670 | 544051 1671 | 544054 1672 | 544060 1673 | 544091 1674 | 544100 1675 | 544115 1676 | 544116 1677 | 544118 1678 | 544123 1679 | 544136 1680 | 544139 1681 | 544143 1682 | 544150 1683 | 544163 1684 | 544165 1685 | 544182 1686 | 544235 1687 | 544258 1688 | 544263 1689 | 544332 1690 | 544343 1691 | 544401 1692 | 544408 1693 | 544410 1694 | 544423 1695 | 544425 1696 | 544426 1697 | 544427 1698 | 544429 1699 | 544510 1700 | 544521 1701 | 544524 1702 | 544581 1703 | 544614 1704 | 544628 1705 | 544631 1706 | 544632 1707 | 544636 1708 | 544639 1709 | 544640 1710 | 544642 1711 | 544646 1712 | 544651 1713 | 544699 1714 | 544706 1715 | 544723 1716 | 544726 1717 | 544732 1718 | 544783 1719 | 544792 1720 | 544826 1721 | 544871 1722 | 544907 1723 | 544909 1724 | 544910 1725 | 544926 1726 | 544927 1727 | 544933 1728 | 544958 1729 | 544960 1730 | 545 1731 | 545012 1732 | 545038 1733 | 545045 1734 | 545058 1735 | 545088 1736 | 545091 1737 | 545099 1738 | 545157 1739 | 545165 1740 | 545169 1741 | 545176 1742 | 545177 1743 | 545193 1744 | 545197 1745 | 545203 1746 | 545247 1747 | 545289 1748 | 545290 1749 | 545303 1750 | 545304 1751 | 545315 1752 | 545388 1753 | 545401 1754 | 545411 1755 | 545415 1756 | 545424 1757 | 545427 1758 | 545430 1759 | 545449 1760 | 545451 1761 | 545465 1762 | 545468 1763 | 545469 1764 | 545475 1765 | 545487 1766 | 545496 1767 | 545507 1768 | 545512 1769 | 545529 1770 | 545543 1771 | 545571 1772 | 545575 1773 | 545595 1774 | 545616 1775 | 546207 1776 | 546245 1777 | 546286 1778 | 546296 1779 | 546374 1780 | 546422 1781 | 546435 1782 | 546448 1783 | 546455 1784 | 546474 1785 | 546496 1786 | 546507 1787 | 546511 1788 | 546514 1789 | 546515 1790 | 546524 1791 | 546528 1792 | 546531 1793 | 546539 1794 | 546542 1795 | 546555 1796 | 546557 1797 | 546567 1798 | 546577 1799 | 5499 1800 | 5503 1801 | 5517 1802 | 5549 1803 | 556 1804 | 5639 1805 | 582 1806 | 5900 1807 | 594 1808 | 5986 1809 | 6156 1810 | 6196 1811 | 6294 1812 | 6295 1813 | 6443 1814 | 6510 1815 | 6515 1816 | 6536 1817 | 669 1818 | 670 1819 | 6854 1820 | 688 1821 | 6898 1822 | 6921 1823 | 6939 1824 | 7025 1825 | 7040 1826 | 7142 1827 | 7292 1828 | 7402 1829 | 7744 1830 | 778 1831 | 7809 1832 | 7817 1833 | 7825 1834 | 8119 1835 | 8137 1836 | 8140 1837 | 82 1838 | 8317 1839 | 8357 1840 | 8358 1841 | 8359 1842 | 8395 1843 | 8407 1844 | 8417 1845 | 8455 1846 | 8672 1847 | 8763 1848 | 8768 1849 | 8777 1850 | 8846 1851 | 8911 1852 | 89580 1853 | 896 1854 | 8962 1855 | 8999 1856 | 9079 1857 | 908 1858 | 916 1859 | 920 1860 | 92844 1861 | 9382 1862 | 9387 1863 | 9495 1864 | 9503 1865 | 9585 1866 | 9637 1867 | 99 1868 | 9970 1869 | 9971 1870 | --------------------------------------------------------------------------------