python自动下载小说

Myth丶恋晨 2023-06-27 08:58 116阅读 0赞

大家好呀,空虚且漫长的三天小长假终于过去了,,哈哈哈哈,又是一个愉快的周一
在这里插入图片描述
刚到公司还没坐下,我旁边的IOS同学就悄悄告诉我项目出了BUG,并给我投来了一个神秘的微笑。。。
在这里插入图片描述
在我吃完早餐,喝完开水,上完厕所之后,手终于没那么抖了,慢慢的打开电脑,才发现只是一个小问题。哈哈哈哈,花费一分钟解决。哎哟,可把我牛逼坏了
在这里插入图片描述
旁边的IOS同学凑过来,用他那不太飘准的普通发给我说:“兄die,上次那个爬图片的很好用啊,不过我这几天看图片看太多了,灵感倒是有很多,就是身体有点吃不消。最近迷上了看小说,可是正版的冲不起钱,盗版的广告又太多,你给我解决解决?”
我:“作为一个优雅的社畜,怎么能看盗版呢?朕瞧不起你这无耻之徒。发过来,朕先举报(保存)一手”
在这里插入图片描述
半小时后,IOS同学:“兄die,怎么样了,解决了吗”
我心想:卧槽,看入迷了,还没开始写,怎么办。
表面稳如老狗,答曰:“emmmmm,这个比较有技术难度,稍等一下,就快好了”
在这里插入图片描述
当然,小说要看,问题还是要解决。怎么才能只看自己想看的内容,去掉自己不想看的内容呢?心念电转,还是用爬虫吧,内容都拿下来,只保存自己想看的不就行了。说干就干。。。
书名《全职法师》,url在代码里
页面大概长这样:
在这里插入图片描述
爬虫三连:获取网页,解析网页,保存目标
随手写个第一版,将内容保存在文件里面,以title做文件名:

  1. import queue
  2. import requests
  3. from lxml import etree as et
  4. import re
  5. import random
  6. import time
  7. import os
  8. # 请求头
  9. headers = {
  10. # 用户代理
  11. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
  12. }
  13. USER_AGENT_LIST = [
  14. 'MSIE (MSIE 6.0; X11; Linux; i686) Opera 7.23',
  15. 'Opera/9.20 (Macintosh; Intel Mac OS X; U; en)',
  16. 'Opera/9.0 (Macintosh; PPC Mac OS X; U; en)',
  17. 'iTunes/9.0.3 (Macintosh; U; Intel Mac OS X 10_6_2; en-ca)',
  18. 'Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)',
  19. 'iTunes/4.2 (Macintosh; U; PPC Mac OS X 10.2)',
  20. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0',
  21. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0',
  22. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0',
  23. 'Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)',
  24. 'Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)'
  25. ]
  26. # 保存小说文件
  27. def save_file(dir,filename,content):
  28. # 如果目录不存在,则新建
  29. if not os.path.exists(dir):
  30. os.makedirs(dir)
  31. save_dir = dir+'/'+filename+'.txt'
  32. #注意:win系统默认新文件编码格式gbk,这里需指定utf-8编码
  33. with open(save_dir, 'w',encoding='utf-8') as f:
  34. f.write(content)
  35. print('ok')
  36. def get_chapter_url(list_url, base_url, queue):
  37. # 获取页面信息
  38. response = requests.get(url=list_url, headers=headers)
  39. # 获取请求状态码
  40. code = response.status_code
  41. if code == 200:
  42. html = et.HTML(response.content)
  43. # 获取该小说章节list
  44. chapter_url = html.xpath('//*[@id="list"]/dl/dd/a/@href')[9:40]
  45. k = 1
  46. for i in chapter_url:
  47. #组装小说章节url
  48. page_url = base_url + i
  49. #将小说章节url+章节编号入队
  50. queue_element = page_url, str(k)
  51. queue.put(queue_element)
  52. k = k + 1
  53. def get_detail_html(queue):
  54. while not queue.empty():
  55. #休息一下,太快会503.等待时长可根据实际情况调节,你可以在503的边缘疯狂试探
  56. time_num = 5
  57. time.sleep(time_num)
  58. # Queue队列的get方法用于从队列中提取元素
  59. queue_element = queue.get()
  60. queue.task_done()
  61. # 获取章节url
  62. page_url = queue_element[0]
  63. # 获取章节编号
  64. chapter_num = queue_element[1]
  65. headers = {
  66. # 从代理列表随机获取代理
  67. 'User-Agent': random.choice(USER_AGENT_LIST)
  68. }
  69. response = requests.get(url=page_url, headers=headers)
  70. response.encoding = "utf-8"
  71. # 请求状态码
  72. code = response.status_code
  73. if code == 200:
  74. html = et.HTML(response.content)
  75. # 获取该章小说title
  76. title = html.xpath('//h1/text()')[0]
  77. # 获取该章小说内容
  78. r = html.xpath('//*[@id="content"]/text()')
  79. content = ''
  80. for i in r:
  81. # 正则匹配,去除干扰字符,只保留汉字和数字
  82. #\u标识unicode编码,u不能大写;之后跟一个十六进制,表示相应字符对应的unicode值,十六进制中英文不区分大小写
  83. #data = re.sub(u"([^\u4E00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])","",i)
  84. content = content + i
  85. # 去除两端空格
  86. title = title.strip()
  87. content = content.strip()
  88. #保存文件
  89. save_file(save_dir, title, content)
  90. else:
  91. print(code)
  92. print(title)
  93. # 主函数
  94. if __name__ == "__main__":
  95. # 小说章节基地址
  96. base_url = 'https://www.biqugecom.com'
  97. # 小说章节列表页地址
  98. list_url = 'https://www.biqugecom.com/0/15/'
  99. #文件保存目录,自由设置,开心就好a
  100. save_dir = os.path.abspath('../quanzhifashi/')
  101. # 用Queue构造一个先进先出队列
  102. urls_queue = queue.Queue()
  103. #获取章节url列表
  104. get_chapter_url(list_url,base_url,urls_queue)
  105. #获取章节内容,存入数据库
  106. get_detail_html(urls_queue)
  107. print('the end!')

略一运行:
在这里插入图片描述
保存下来的小说:
在这里插入图片描述
过了一会儿,IOS:“老哥,你这个txt让我很为难啊,用户体验不怎么的,优化一下?”
沉思五秒后,我:“那我给你写成接口,你自己随便写一个APP,调我的接口怎么样?这样的话,界面你可以自己DIY,还能根据你的内裤颜色换小说背景色。”
IOS:“这个好,这个好,虽然我不怎么穿内裤,嘿嘿”
我:“。。。。。。。。。。。”
在这里插入图片描述
niubi要吹,代码还是要写。数据库那么多,选什么牌子呢?数据库技术哪家强,mysql数据库帮你忙,好用开源是真香
先安装一个mysql驱动吧:pip3 install mysql-connector
建个表保存小说章节编号,title和正文内容:

  1. # Host: localhost (Version: 5.7.26)
  2. # Date: 2020-01-06 11:28:42
  3. # Generator: MySQL-Front 5.3 (Build 4.234)
  4. /*!40101 SET NAMES utf8 */;
  5. #
  6. # Structure for table "novel"
  7. #
  8. DROP TABLE IF EXISTS `novel`;
  9. CREATE TABLE `novel` (
  10. `id` int(11) NOT NULL AUTO_INCREMENT,
  11. `chapter_num` int(11) DEFAULT NULL COMMENT '章节编号',
  12. `title` varchar(20) NOT NULL DEFAULT '0' COMMENT '章节标题',
  13. `content` varchar(15000) DEFAULT NULL COMMENT '章节内容',
  14. `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  15. `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  16. PRIMARY KEY (`id`)
  17. ) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8;

然后写个方法存数据,抱着试一试的心态,点击运行,得如下结果:
在这里插入图片描述
打开mysql一看。
在这里插入图片描述
呵,我可真是天选之子
在这里插入图片描述
完整代码:

  1. import queue
  2. import requests
  3. from lxml import etree as et
  4. import re
  5. import random
  6. import time
  7. import os
  8. import mysql.connector
  9. # 请求头
  10. headers = {
  11. # 用户代理
  12. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
  13. }
  14. #用户代理列表
  15. USER_AGENT_LIST = [
  16. 'MSIE (MSIE 6.0; X11; Linux; i686) Opera 7.23',
  17. 'Opera/9.20 (Macintosh; Intel Mac OS X; U; en)',
  18. 'Opera/9.0 (Macintosh; PPC Mac OS X; U; en)',
  19. 'iTunes/9.0.3 (Macintosh; U; Intel Mac OS X 10_6_2; en-ca)',
  20. 'Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)',
  21. 'iTunes/4.2 (Macintosh; U; PPC Mac OS X 10.2)',
  22. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0',
  23. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0',
  24. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0',
  25. 'Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)',
  26. 'Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)'
  27. ]
  28. # 保存小说文件
  29. def save_file(dir,filename,content):
  30. # 如果目录不存在,则新建
  31. if not os.path.exists(dir):
  32. os.makedirs(dir)
  33. save_dir = dir+'/'+filename+'.txt'
  34. #注意:win系统默认新文件编码格式gbk,这里需指定utf-8编码
  35. with open(save_dir, 'w',encoding='utf-8') as f:
  36. f.write(content)
  37. print('ok')
  38. # 插入数据库
  39. def insert_data(chapter_num, title, content):
  40. conn = mysql.connector.connect(user='root', password='root', database='test')
  41. cursor = conn.cursor()
  42. try:
  43. cursor.execute('insert into novel (chapter_num, title, content) values (%s, %s, %s)', [chapter_num, title, content])
  44. conn.commit()
  45. except Exception as e:
  46. print('Error:', e)
  47. finally:
  48. cursor.close()
  49. conn.close()
  50. def get_chapter_url(list_url, base_url, queue):
  51. # 获取页面信息
  52. response = requests.get(url=list_url, headers=headers)
  53. # 获取请求状态码
  54. code = response.status_code
  55. if code == 200:
  56. html = et.HTML(response.content)
  57. # 获取该小说章节list
  58. chapter_url = html.xpath('//*[@id="list"]/dl/dd/a/@href')[9:40]
  59. k = 1
  60. for i in chapter_url:
  61. #组装小说章节url
  62. page_url = base_url + i
  63. #将小说章节url+章节编号入队
  64. queue_element = page_url, str(k)
  65. queue.put(queue_element)
  66. k = k + 1
  67. #获取章节内容,存入数据库
  68. def get_detail_html(queue):
  69. while not queue.empty():
  70. #休息一下,太快会503.等待时长可根据实际情况调节,你可以在503的边缘疯狂试探
  71. time_num = 5
  72. time.sleep(time_num)
  73. # Queue队列的get方法用于从队列中提取元素
  74. queue_element = queue.get()
  75. queue.task_done()
  76. # 获取章节url
  77. page_url = queue_element[0]
  78. # 获取章节编号
  79. chapter_num = queue_element[1]
  80. headers = {
  81. # 从代理列表随机获取代理
  82. 'User-Agent': random.choice(USER_AGENT_LIST)
  83. }
  84. response = requests.get(url=page_url, headers=headers)
  85. response.encoding = "utf-8"
  86. # 请求状态码
  87. code = response.status_code
  88. if code == 200:
  89. html = et.HTML(response.content)
  90. # 获取该章小说title
  91. title = html.xpath('//h1/text()')[0]
  92. # 获取该章小说内容
  93. r = html.xpath('//*[@id="content"]/text()')
  94. content = ''
  95. for i in r:
  96. content = content + i
  97. # 去除两端空格
  98. title = title.strip()
  99. content = content.strip()
  100. #插入数据库
  101. insert_data(chapter_num, title, content)
  102. #保存文件
  103. #save_file(save_dir, title, content)
  104. else:
  105. print(code)
  106. print(title)
  107. # 主函数
  108. if __name__ == "__main__":
  109. # 小说章节基地址
  110. base_url = 'https://www.biqugecom.com'
  111. # 小说章节列表页地址
  112. list_url = 'https://www.biqugecom.com/0/15/'
  113. #文件保存目录,自由设置,开心就好a
  114. save_dir = os.path.abspath('../quanzhifashi/')
  115. # 用Queue构造一个先进先出队列
  116. urls_queue = queue.Queue()
  117. #获取章节url列表
  118. get_chapter_url(list_url,base_url,urls_queue)
  119. #获取章节内容,存入数据库
  120. get_detail_html(urls_queue)
  121. print('the end!')

又过了一会儿,IOS同学:“兄die,你这个有点慢啊,下载一章还要休息几秒”
我:“因为这个网站有限制,太快了会503,再说就算你一目十行也看不了那么快吧”
IOS:“看小说倒是不影响,就是你这样的代码影响我吹牛逼”
我:“emmmmm,那我搭建个IP池,然后给你改成多线程”
在这里插入图片描述
当朕准备搭建IP池的时候,产品经理的头像突然闪了起来。
只见消息列表里面躺着一个需求文档,并附文:
在这里插入图片描述
emmmmmm,溜了溜了。

The end !

学到了就要教人,赚到了就要给人
薪火相传,方能生生不息

发表评论

表情:
评论列表 (有 0 条评论,116人围观)

还没有评论,来说两句吧...

相关阅读

    相关 python自动下载小说

    大家好呀,空虚且漫长的三天小长假终于过去了,,哈哈哈哈,又是一个愉快的周一 ![在这里插入图片描述][20200106095612416.png] 刚到公司还没坐下,我

    相关 java爬虫之下载txt小说

    最近迷上了天蚕土豆写的《大主宰》这本玄幻小说,无奈找不到下载链接。于是就萌生了自己爬取小说章节的想法,代码其实很简单,主要在于分析网页结构、正则匹配以及文件保存. 1