前言:

原标题----运用Python多线程爬虫下载纵横中文网上的小说

这篇博文之所以取一个这样的标题,除了是想吸引读者的眼球之外,更重要的是最后的确实在wps等工具上阅读小说的。

文章目录

  • 原标题----运用Python多线程爬虫下载纵横中文网上的小说
    • 1.做这个项目所需要的模块
    • 2.怎样实现
      • 2.1.得到小说的网址
      • 2.2. 得到小说目录的网址
      • 2.3.得到小说所有章节的网址
      • 2.4 爬取小说所有章节的内容
    • 3.最终代码
    • 4.改进与总结

1.做这个项目所需要的模块

python自带模块:os、threading
需要额外安装的模块:bs4、urllib、requests
怎样安装:
bs4 :pip install bs4
requests:pip install requests
urllib:pip install urllib3

2.怎样实现

2.1.得到小说的网址

我们首先要进入这个网址:
http://www.zongheng.com/
在搜索框中输入自己想看的小说的类型,点击搜索
如下:我输入的是 三国

这就是匹配到的小说名称了。
我们点击其中一本小说进入来到这个界面:

可以发现,这个界面的网址为:http://book.zongheng.com/book/591854.html
回到原来的那个界面,点击鼠标右键,然后点击检查,我们可以发现这个网址在上一个网址的这里。

代码:

def matching_book(): # 得到所有匹配到的小说keyword = input('请输入你想下载的小说标题:')key_word = parse.urlencode({'keyword': keyword})url='http://search.zongheng.com/s?%s'%(key_word)headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}html=requests.get(url=url,headers=headers)info=html.text     # 网页信息soup=BeautifulSoup(info,'lxml')list_1=soup.select('div.search-tab>div.search-result-list.clearfix')   # 小说信息book_url=[]book_name=[]for i in range(len(list_1)):str_1=list_1[i].select('div.fl.se-result-infos>h2>a')[0]['href']       # 小说的网址name_1=list_1[i].select('div.fl.se-result-infos>h2>a')[0].get_text()   # 匹配到的小说名称book_url.append(str_1)book_name.append(name_1)print('【{}】-{}'.format(i+1,name_1))id=int(input('请输入你想看的小说序号:'))return book_url[id-1],book_name[id-1]

这样我们就得到了自己想看的小说网址了。

2.2. 得到小说目录的网址

我们来到这个界面,跟上面一样,进行检查。
发现这个网址在div.fr.link-group>a.all-catalog里面

为了使读者对这篇小说更加理解,也可以将小说的简介和类型也爬取下来。
代码:

def get_catalog_url(url):def get_info(list_1):str_1=''for html_1 in list_1:str_1+=html_1.get_text()+','return str_1# url='http://book.zongheng.com/book/591854.html'html_1=requests.get(url=url)info_1=html_1.textsoup_1=BeautifulSoup(info_1,'lxml')info_book=soup_1.select('div.book-info')book_label_1=get_info(info_book[0].select('div.book-label>a'))book_label_2=get_info(info_book[0].select('div.book-label>span>a'))book_label=book_label_1+book_label_2jian_jie=(info_book[0].select('div.book-dec.Jbook-dec.hide>p'))[0].get_text()   #小说的简介book_mu_url=info_book[0].select('div.btn-group>div.fr.link-group>a.all-catalog')[0]['href']   # 小说目录的网址print('---->{}'.format(book_label))print('---->{}'.format(jian_jie))return book_mu_url

代码中需要传入的url就是上面2.1得到那个url

2.3.得到小说所有章节的网址

我们点击全部目录,来到这个界面,我们只需将这个界面里的所有小说章节的网址爬到,并进入这个网址就可以得到自己想看的小说内容了。

代码:

def get_catalog(url):# url='http://book.zongheng.com/showchapter/591854.html'headers_1={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}html_2=requests.get(url=url,headers=headers_1)soup_2=BeautifulSoup(html_2.text,'lxml')list_3=soup_2.select('div.volume-list>div')title_list=[]ti_url_list=[]for soup_3 in list_3:info_text=soup_3.select('div.volume ')[0].get_text().strip('\n')  #去掉左右换行title_list.append(info_text)list_text=soup_3.select('ul.chapter-list.clearfix>li>a')for i in range(len(list_text)):list_text[i]=[list_text[i].get_text(),list_text[i]['href']]ti_url_list.append(list_text)for i in range(len(title_list)):print(title_list[i])for j in range(len(ti_url_list[i])):print(ti_url_list[i][j][0])return ti_url_list

这个函数跟上面一样,传入参数是2.2得到的那个网址,返回的是一个列表,也就是小说的所有章节的网址。

2.4 爬取小说所有章节的内容

我们随便点击其中的一章阅读,本来想跟上面一样,结果不行,在这个网址下无法按鼠标右键,不过,可以按F12,可以发现所有内容都在div.content下面的p标签里,我们只需爬取相应内容即可。

def Write_To_Wps(ti_url_list,book_name):def Thread_write(ti_url_list:list,book_name:str):while True:if len(ti_url_list)==0:breaklist_2=ti_url_list.pop()while True:if len(list_2)==0:breakurl_text=list_2.pop()# url_1='http://book.zongheng.com/chapter/591854/38192586.html'url_1=url_text[-1]text_name=url_text[0]headers_1={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}info_4=requests.get(url=url_1,headers=headers_1).textsoup_4=BeautifulSoup(info_4,'lxml')text_info=soup_4.select('div.reader_box')# text_name=text_info[0].select('div.title>div.title_txtbox')[0].get_text()   #小说一章的标题list_1=text_info[0].select('div.content>p')    #小说一章的内容path_1='./{}'.format(book_name)try:os.mkdir(path_1)except:passfinally:str_info=''for str_1 in list_1:str_info+=str_1.get_text()+'\n'path_2=path_1+'/{}.doc'.format(text_name)print('当前线程为{1},正在下载{0}'.format(text_name,threading.current_thread().getName()))text_name=' '*30+text_name+'\n'with open(path_2,'w',encoding='utf-8') as f:f.write(text_name)f.write(str_info)threading_list=[]for i in range(10):threading_1=threading.Thread(target=Thread_write,args=(ti_url_list,book_name,))threading_1.start()threading_list.append(threading_1)for i in threading_list:i.join()print('------------下载完毕!当前线程为{}'.format(threading.current_thread().getName()))

这个函数传入的参数就是***2.3***得到那个列表。
在这里,运用了多线程。不过,有个小问题,就是实际上用到的线程好像没有10个(原本创建了10个线程),不知道是不是我在代码中用到两个while循环的原因。

3.最终代码

import requests
from bs4 import BeautifulSoup
from urllib import parse
import os
import threadingdef matching_book(): # 得到所有匹配到的小说keyword = input('请输入你想下载的小说标题:')key_word = parse.urlencode({'keyword': keyword})url='http://search.zongheng.com/s?%s'%(key_word)headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}html=requests.get(url=url,headers=headers)info=html.text     # 网页信息soup=BeautifulSoup(info,'lxml')list_1=soup.select('div.search-tab>div.search-result-list.clearfix')   # 小说信息book_url=[]book_name=[]for i in range(len(list_1)):str_1=list_1[i].select('div.fl.se-result-infos>h2>a')[0]['href']       # 小说的网址name_1=list_1[i].select('div.fl.se-result-infos>h2>a')[0].get_text()   # 匹配到的小说名称book_url.append(str_1)book_name.append(name_1)print('【{}】-{}'.format(i+1,name_1))id=int(input('请输入你想看的小说序号:'))return book_url[id-1],book_name[id-1]def get_catalog_url(url):def get_info(list_1):str_1=''for html_1 in list_1:str_1+=html_1.get_text()+','return str_1# url='http://book.zongheng.com/book/591854.html'html_1=requests.get(url=url)info_1=html_1.textsoup_1=BeautifulSoup(info_1,'lxml')info_book=soup_1.select('div.book-info')book_label_1=get_info(info_book[0].select('div.book-label>a'))book_label_2=get_info(info_book[0].select('div.book-label>span>a'))book_label=book_label_1+book_label_2jian_jie=(info_book[0].select('div.book-dec.Jbook-dec.hide>p'))[0].get_text()   #小说的简介book_mu_url=info_book[0].select('div.btn-group>div.fr.link-group>a.all-catalog')[0]['href']   # 小说目录的网址print('---->{}'.format(book_label))print('---->{}'.format(jian_jie))return book_mu_urldef get_catalog(url):# url='http://book.zongheng.com/showchapter/591854.html'headers_1={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}html_2=requests.get(url=url,headers=headers_1)soup_2=BeautifulSoup(html_2.text,'lxml')list_3=soup_2.select('div.volume-list>div')title_list=[]ti_url_list=[]for soup_3 in list_3:info_text=soup_3.select('div.volume ')[0].get_text().strip('\n')  #去掉左右换行title_list.append(info_text)list_text=soup_3.select('ul.chapter-list.clearfix>li>a')for i in range(len(list_text)):list_text[i]=[list_text[i].get_text(),list_text[i]['href']]ti_url_list.append(list_text)for i in range(len(title_list)):print(title_list[i])for j in range(len(ti_url_list[i])):print(ti_url_list[i][j][0])return ti_url_listdef Write_To_Wps(ti_url_list,book_name):def Thread_write(ti_url_list:list,book_name:str):while True:if len(ti_url_list)==0:breaklist_2=ti_url_list.pop()while True:if len(list_2)==0:breakurl_text=list_2.pop()# url_1='http://book.zongheng.com/chapter/591854/38192586.html'url_1=url_text[-1]text_name=url_text[0]headers_1={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}info_4=requests.get(url=url_1,headers=headers_1).textsoup_4=BeautifulSoup(info_4,'lxml')text_info=soup_4.select('div.reader_box')# text_name=text_info[0].select('div.title>div.title_txtbox')[0].get_text()   #小说一章的标题list_1=text_info[0].select('div.content>p')    #小说一章的内容path_1='./{}'.format(book_name)try:os.mkdir(path_1)except:passfinally:str_info=''for str_1 in list_1:str_info+=str_1.get_text()+'\n'path_2=path_1+'/{}.doc'.format(text_name)print('当前线程为{1},正在下载{0}'.format(text_name,threading.current_thread().getName()))text_name=' '*30+text_name+'\n'with open(path_2,'w',encoding='utf-8') as f:f.write(text_name)f.write(str_info)threading_list=[]for i in range(10):threading_1=threading.Thread(target=Thread_write,args=(ti_url_list,book_name,))threading_1.start()threading_list.append(threading_1)for i in threading_list:i.join()print('------------下载完毕!当前线程为{}'.format(threading.current_thread().getName()))if __name__ == '__main__':tuple_1=matching_book()    # 这个返回的是一个元组,第一个参数是小说的网址,第二个参数是小说的名称url,book_name=tuple_1[0],tuple_1[1]catalog_url=get_catalog_url(url)    #小说目录的urlti_url_list=get_catalog(catalog_url)Write_To_Wps(ti_url_list=ti_url_list,book_name=book_name)

运行结果:

这个运行完之后,可以发现在当前文件夹下面多了一个文件夹,文件夹的名称就是自己选的小说名称,所下载的小说章节就在这个文件夹下面。

感觉这个效果好像不是很好,为了更加清晰看到自己下载的总章节和方便阅读,我们可以执行一下这个代码:

import ospath_1=input('输入路径:')
list_1=os.listdir(path_1)
dict_1 = {'一': '1','二': '2','三': '3','四': '4','五': '5','六': '6','七': '7','八': '8','九': '9','零': '0'
}
list_2=[]
for i in range(len(list_1)):str_1=list_1[i][list_1[i].find('第')+1:list_1[i].find('章 ')]for j in dict_1:str_1=str_1.replace(j,dict_1[j])if '十' in str_1:if len(str_1) == 1:str_1 = '10'elif str_1[-1]=='十':str_1=str_1.replace('十','0')elif str_1[0]=='十':str_1=str_1.replace('十','1')else:str_1=str_1.replace('十','')if '百' in str_1:if len(str_1)==2:str_1=str_1.replace('百','00')else:str_1=str_1.replace('百','')str_1=list_1[i].replace(list_1[i][list_1[i].find('第')+1:list_1[i].find('章 ')],str_1)list_2.append(str_1)for i in range(len(list_1)):print(list_1[i],list_2[i])os.rename(path_1+'\\'+list_1[i],path_1+'\\'+list_2[i])

运行结果:

4.改进与总结

  1. 也许是访问次数过多的原因,服务器会封掉我们的ip地址,如果讲改进的话,希望用到代理ip;
  2. 有一些小说因为章节名称的原因,会包错,这个解决我已经在最终代码上进行改进了,但在2.4那里没有改,希望大家谅解;
  3. 本代码仅供娱乐和学习,切莫用于商业,一经发现,概不负责!
  4. 因为有的小说部分章节需要登陆,才能阅读所有内容,所以这些章节最终爬取得到的内容只有一点点,不知道大家有什么好的改进措施吗?欢迎留言。

WPS,我的阅读小说工具相关推荐

  1. 白嫖系列软件-------阅读(小说)

    白嫖系列软件-------阅读(小说) 简介: 阅读是一款提供网络文学搜索的工具,为广大网络文学爱好者提供一种方便.快捷舒适的试读体验. 自定义书源,一切尽有可能. 开源 下载地址 下载地址 相关说明 ...

  2. Linux内核源码阅读以及工具(转)

    Linux内核源码阅读以及工具(转) 转载地址:Linux内核源码阅读以及工具(转)

  3. Android4.1.0实战教程---自动阅读小说

    APK下载地址: https://download.csdn.net/download/zy0412326/12370131 邀请码:七猫免费小说 5K9FRS 番茄免费小说:782383363 免费 ...

  4. Calibre for Mac v5.29.0电子书阅读管理工具

    Calibre Mac版是 macOS 系统上一款简单实用的电子书阅读管理工具,比普通的电子书软件相比,性能有了更高的提升,可以进行电子书的格式转换.阅读等,把你的电子书图书馆进行图书管理. 应用介绍 ...

  5. Calibre for Mac v5.20.0 中文版 电子书阅读管理工具

    Calibre Mac版是 macOS 系统上一款简单实用的电子书阅读管理工具,比普通的电子书软件相比,性能有了更高的提升,可以进行电子书的格式转换.阅读等,把你的电子书图书馆进行图书管理. 应用介绍 ...

  6. 利用Python, PyQt5,Selenium,百度图像识别API制作文献阅读辅助工具

    开发背景 作为一名科研狗,经常需要读一些外文文献并且做笔记,有时还需要全文翻译以备后用.这时候会遇到一些问题: PDF和CAJ文件直接复制出来的东西含有大量无用的换行符,手动删除十分麻烦: 有的文献是 ...

  7. 【工具】PDF阅读器工具推荐

    [工具]PDF阅读器工具推荐 Download Sumatra PDF - a free reader

  8. 用txt阅读器按目录分章节阅读小说

    用txt阅读器按目录分章节阅读小说 最近,我从网上下载了一部名为<大主宰>的长篇玄幻小说.这是一部章回小说,截至目前,已写到第1330章,真可谓宏篇巨制.我想用一个分章节的文本阅读器阅读它 ...

  9. 《构建之法》阅读以及工具调研

    <构建之法>阅读以及工具调研 项目 内容 这个作业属于哪个课程 2022年北航敏捷软件工程社区 这个作业的要求在哪里 传送门 我在这个课程的目标是 1. 提升自身在技术硬实力上的竞争力 2 ...

最新文章

  1. python发邮件实例_python 发邮件实例
  2. bootstrap使用总结(导航在carousel居中之上)
  3. 操作系统--中断和异常
  4. python控件随窗口变化而适配_Tkinter窗口/控件比例调整
  5. 直接上干货!技术水平真的很重要!复习指南
  6. 20162329 张旭升 2017 - 2018 《程序设计与数据结构》第五周总结
  7. ssh 配置:在 Linux 中 ssh 配置无密码登陆完整步骤以及易错点分析
  8. MySQL 中 count(*) 和 count(1) 有什么区别?哪个性能最好?
  9. Python使用装饰器和线程限制函数执行时间的方法
  10. gen_fsm的学习笔记
  11. 【电脑维修系列】妈妈再也不用担心 我装不了电脑系统 全攻略
  12. ARM体系结构与编程-3
  13. 如何把大写金额变为小写数字_word中怎么将小写金额数字转换为大写
  14. 关于zip包解压之后文件打开出现文件损坏的问题
  15. GHM:Gradient Harmonized Single-stage Detector
  16. 当机器学习遇到病理学,机遇和挑战(UCL柴秉浩博士 | 钰沐菡 公益公开课)
  17. 微信小程序商城搭建二手交易网站购物+后台管理系统|前后分离VUE.js
  18. 芝诺数解|「十」渝味之城,愉味无穷——重庆十一旅游数据分析报告
  19. 你了解通配符泛域名https证书吗
  20. 计算机高配方案,intel酷睿i9-9900KF搭配RTX2080高配游戏电脑配置单,游戏直播高端装机方案...

热门文章

  1. 2017php免杀大马,cs 免杀 payload 绕过 360 全家桶
  2. 南京地平线机器人无人驾驶算法面经--已获offer!
  3. MATLAB|awgn函数的说明
  4. MQTT协议详解,非常易懂
  5. 智能电销机器人对企业的营销助力
  6. python单下划线和双下滑线
  7. CRC32加密算法原理
  8. 如何快速创建IC类封装及封装下载网址
  9. 人民银行备案企业AAA信用评级7证包含哪些?
  10. 【数学】Frobenius介值定理:非负矩阵最大特征值的上下界