第一步, 爬取并入库 MySQL, 这一步占了最多的时间, 为了避免被 Anti-Spider 机制影响, 所以限速也较低.
因为 URL 格式里面似乎包含了 ID 信息, 所以也一并采集了.
第一段 ID 似乎是小说 ID, 第二段 ID 似乎是章节 ID, 章节 ID 和小说 ID 并非连续, 但是同样的小说 ID 下, 章节 ID 必然递增存在, 所以储存时候就这么干.(正文内容省略)
第二步就是得到 CSV 文件 (大约 100GB), 然后从 CSV 文件入库, 为什么不用 pipeline 入库的原因是数据库是临时用的, 按需付费省着用.
- CREATE DATABASE `books`
- use books;
- DROP TABLE `scrapy`;
- CREATE TABLE `scrapy` (
- `id` INT NOT NULL AUTO_INCREMENT,
- `id_primary` INT NOT NULL,
- `id_subset` INT NOT NULL,
- `title` VARCHAR(200) NOT NULL DEFAULT '',
- `chapter_name` VARCHAR(200) NOT NULL DEFAULT '',
- `chapter_content` MEDIUMTEXT,
- `created_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
- PRIMARY KEY (`id`),
- INDEX `id_subset` (`id_subset`),
- INDEX `id_primary` (`id_primary`)
- )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- LOAD DATA LOCAL INFILE '/mnt/ScrapyBooks.csv' IGNORE INTO TABLE scrapy CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' IGNORE 1 LINES (`chapter_content`,`chapter_name`,`id_primary`,`id_subset`,`title`);
- SHOW WARNINGS;
如果采集到的 CSV 100G 的话, 入库大概需要 170G 的数据库空间, 另外 CSV 文件需要处理, 否则会被意外截断, 前面已经有文章说过.
CSV 导入 MySQL 数据库被意外截断解决 https://www.taterli.com/6240/
导入成功的最佳结果当然是 0 错误, 0 警告了.
第三步就是从数据库再提取回来, 生成 TXT 文本的小说, 当然, 都入库了也可以用来生成网站.
- import pymysql
- def make( id ):
- cursor = db.cursor()
- sql = "SELECT * FROM scrapy WHERE id_primary =" + str(id) + "ORDER BY id_subset ASC"
- cursor.execute(sql)
- result = cursor.fetchone()
- if result[3] == "":
- print('似乎出现了书名不正确的情况')
- print(result)
- return
- print('正在写入' + result[3] + '.txt')
- wf = open('/mnt/volume_fra1_02/books/' + result[3] + '.txt','a')
- #至少先做第一次提取, 写入标题, 然后检测标题是否在正文有重复, 如果有重复, 删除正文标题.
- wf.write(result[4]+'\r\n')
- content = result[5].replace(result[4],'')
- wf.write(content.strip('"')+'\r\n'+'\r\n')
- while result is not None:
- result = cursor.fetchone()
- if result is not None:
- wf.write(result[4]+'\r\n')
- content = result[5].replace(result[4],'')
- wf.write(content.strip('"')+'\r\n'+'\r\n')
- wf.close()
- db = pymysql.connect(host="127.0.0.1",user="root",db="books",cursorclass = pymysql.cursors.SSCursor)
- cursor = db.cursor()
- sql = "SELECT DISTINCT id_primary FROM scrapy"
- cursor.execute(sql)
- id_dict = []
- result = cursor.fetchone()
- id_dict.append(result[0])
- while result is not None:
- result = cursor.fetchone()
- if result is not None:
- id_dict.append(result[0])
- for tid in id_dict:
- make(tid)
- cursor.close()
- db.close()
写入数据中...
打开检查, 发现顺序正确, 内容没问题.
第四步, 导出的文件总量大小约等于 CSV 文件大小 (可能略大 / 略小), 有些只有几 MB, 有些几十上百 M, 抽查发现有些提取出现问题, 这个也是因为蜘蛛算法问题, 看起来需要一些容错机制才行.
BUG 举例:
导致原因, 我用的 XPATH 提取了第一个 ul, 但是有些地方目录在第二个 ul, 所以出错了.
第一代含 BUG 爬虫先结束他, 想搞第二代时候再说吧.
来源: http://www.tuicool.com/articles/7nEFfyr