鱼C论坛

 找回密码
 立即注册
查看: 1387|回复: 2

[作品展示] 再写一个爬取小说的虫虫

[复制链接]
发表于 2020-6-19 13:43:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 chenxz186 于 2020-6-19 18:29 编辑

好久没有再写爬小说了,今天放了一个上来,不多说了,直接上图上代码。


  1. import requests
  2. import pyquery
  3. import os
  4. import easygui as g
  5. import time
  6. import datetime


  7. def catch_exception(func):
  8.     """抓取错误"""

  9.     def error_func(*args, **kwargs):
  10.         try:
  11.             func(*args, **kwargs)
  12.         except TimeoutError:
  13.             msg = '由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败,是否继续'
  14.             title = '出错显示'
  15.             choices = ['continue', 'exit']
  16.             choice = g.buttonbox(msg, title, choices)
  17.             if choice is None or choice == choices[1]:
  18.                 exit()
  19.             if choice == choices[0]:
  20.                 Fiction.main()
  21.         except AttributeError:
  22.             msg = 'NoneType object has no attribute find_all'
  23.             title = '出错显示'
  24.             choices = ['continue', 'exit']
  25.             choice = g.buttonbox(msg, title, choices)
  26.             if choice is None or choice == choices[1]:
  27.                 exit()
  28.             if choice == choices[0]:
  29.                 Fiction.main()

  30.     return error_func


  31. def statistics_time(func):
  32.     """统计程序运行时间"""

  33.     def test_time(*args, **kwargs):
  34.         start_time = datetime.datetime.now()
  35.         func(*args, **kwargs)
  36.         end_time = datetime.datetime.now()
  37.         result = end_time - start_time
  38.         print(result)

  39.     return test_time


  40. class ParentFrame(object):
  41.     """建立此父类框架,将通用的方法写进去,方便下次写别的爬虫,不用重写,直接继承。"""

  42.     def __init__(self):
  43.         self.headers = {
  44.             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/'
  45.                           '78.0.3904.108 Safari/537.36'
  46.         }

  47.     def open_url(self, url):
  48.         """获取网页响应"""
  49.         res = requests.get(url, headers=self.headers)
  50.         return res

  51.     @staticmethod
  52.     def build_doc(res):
  53.         """将网页响应进行PyQuery"""
  54.         html = res.text
  55.         doc = pyquery.PyQuery(html)
  56.         return doc

  57.     @staticmethod
  58.     def save_path():
  59.         """选择你要存放的路径,,小说会下载在此文件夹内。"""
  60.         msg = '小说会保存在此路径下'
  61.         title = '存放路径选择'
  62.         dir_path = g.diropenbox(msg, title)
  63.         if dir_path is None:
  64.             exit()
  65.         os.chdir(dir_path)
  66.         return os.getcwd()


  67. class Fiction(ParentFrame):
  68.     """小说下载"""

  69.     def __init__(self, search_url):
  70.         super().__init__()
  71.         self.dir_path = self.save_path()
  72.         self.home_url = 'https://www.23txt.com'
  73.         self.search_url = search_url

  74.     def find_fiction(self, name, url):
  75.         res = self.open_url(url)
  76.         res.encoding = 'utf-8'
  77.         doc = self.build_doc(res)
  78.         need_tags = doc('h3').items()
  79.         fiction_names_urls = {}
  80.         choices = []
  81.         for each in need_tags:
  82.             fiction_name = each.find('a').attr('title')
  83.             fiction_url = each.find('a').attr('href')
  84.             fiction_names_urls[fiction_name] = fiction_url
  85.             choices.append(fiction_name)
  86.         print(fiction_names_urls)
  87.         msg = '选择你要下载的小说'
  88.         title = '选择框'
  89.         choice = g.choicebox(msg, title, choices)
  90.         if choice == 'Add more choices':
  91.             print('没有这部小说,要重新选择')
  92.             self.run()
  93.         if choice is None:
  94.             exit()
  95.         return choice, fiction_names_urls[choice]

  96.     def download_tool(self, filename, url):
  97.         res = self.open_url(url)
  98.         res.encoding = 'GBK'
  99.         doc = self.build_doc(res)
  100.         title_tag = doc('h1').text()
  101.         content_tags = doc('#content').text()
  102.         chapter_content = title_tag + '\n\n' + content_tags + '\n\n\n\n'
  103.         with open(filename, 'a', encoding='utf-8') as f:
  104.             f.write(chapter_content)

  105.     @statistics_time
  106.     def fiction_chapters_download(self, filename, url):
  107.         """这里有BUG,不过已经解决了。"""
  108.         res = self.open_url(url)
  109.         res.encoding = 'GBK'
  110.         doc = self.build_doc(res)
  111.         need_tags = doc('dd').items()
  112.         if os.path.exists(filename):
  113.             with open(filename, 'r', encoding='utf-8') as f:
  114.                 fiction_content = f.read()
  115.                 not_download_chapters = []
  116.                 for each in need_tags:
  117.                     chapter_title = each.text()
  118.                     if chapter_title not in fiction_content:
  119.                         not_download_chapters.append((chapter_title, self.home_url + each.find('a').attr('href')))
  120.                 length = len(not_download_chapters)
  121.                 if length != 0:
  122.                     for chapter_title, chapter_url in not_download_chapters:
  123.                         print(chapter_title)
  124.                         self.download_tool(filename, chapter_url)
  125.                         time.sleep(0.5)
  126.                 else:
  127.                     if g.msgbox('没有可更新的章节') is None:
  128.                         exit()
  129.         else:
  130.             for each in need_tags:
  131.                 chapter_url = self.home_url + each.find('a').attr('href')
  132.                 chapter_title = each.text()
  133.                 print(chapter_title)
  134.                 self.download_tool(filename, chapter_url)
  135.                 time.sleep(0.5)

  136.     def run(self):
  137.         while True:
  138.             msg = '请输入你要查找的小说名,例如《我老婆是鬼王》,即输入 我老婆是鬼王 '
  139.             title = '小说搜索'
  140.             name = g.enterbox(msg, title)
  141.             if name is None:
  142.                 exit()
  143.             if name == '':
  144.                 continue
  145.             name = name.replace(' ', '')
  146.             print(name)
  147.             fiction_search_url = self.search_url + name
  148.             fiction_name, fiction_url = self.find_fiction(name, fiction_search_url)
  149.             print(fiction_name, fiction_url)
  150.             filename = self.dir_path + '/' + fiction_name + '.txt'
  151.             self.fiction_chapters_download(filename, fiction_url)

  152.     @classmethod
  153.     @catch_exception
  154.     def main(cls):
  155.         search_url = 'https://www.23txt.com/search.php?keyword='
  156.         fiction = cls(search_url)
  157.         fiction.run()


  158. if __name__ == '__main__':
  159.     Fiction.main()
复制代码
1.jpg
360截图20200619134101834.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-6-19 13:52:20 | 显示全部楼层
20行
  1. if choice is None and choice == choices[1]:
复制代码
这个条件不可能为真。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-19 15:10:24 | 显示全部楼层
永恒的蓝色梦想 发表于 2020-6-19 13:52
20行这个条件不可能为真。

谢谢指正,我当时定得急了,应用or
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-22 04:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表