python 小说爬虫_从零开始写Python爬虫 --- 1.7 爬虫实践: 排行榜小说批量下载

从零开始写Python爬虫 --- 1.7 爬虫实践: 排行榜小说批量下载9f1957128c1651917b071e2e73a88f32.jpgEhco

5 个月前

本来只是准备做一个爬起点小说名字的爬虫,后来想了一下,为啥不顺便把小说的内容也爬下来呢?于是我就写了这个爬虫,他爬下了各类小说排行榜上的所有章节内容,并保存到本地。仔细想了一下,各种盗版小说阅读器,是不是就是这样做的呢?

目标分析:首先来看看我们排行榜的地址:

http://www.qu.la/paihangbang/

我们的目的很明确:

找到各类排行旁的的每一部小说的名字,和在该网站的链接:

观察一下网页的结构:

a7ad03c4a7ea9bd8f9b838d96af30611.png

我们很容易就能发现,每一个分类都是包裹在:

之中

这种调理清晰的网站,大大方便了我们爬虫的编写

小说标题和链接:我们在刚才那个div里自己寻找:

玄幻奇幻排行

05-061.择天记

05-062.大主宰

05-063.太古神王

05-064.雪鹰领主

05-0115.武动乾坤

发现所有的小说都是在一个个列表里,并且里面清晰的定义了:

标题:title = div.a['title']

链接:link = 'http://www.qu.la/'

+ div.a['href']

这样一来,我们只需要在当前页面找到所有小说的连接,并保存在列表就行了。

列表去重的小技巧:信息的同学会发现,就算是不同类别的小说,也是会重复出现在排行榜的。

这样无形之间就会浪费我们很多资源,尤其是在面对爬大量网页的时候。

那么我们如何从抓取的url列表里去重呢?

刚学Python的小伙伴可能会去实现一个循环算法,来去重,

但是Python的强大之处就在于他可以通过及其优美的方式来解决很多问题,这里其实只要一行代码就能解决:

url_list = list(set(url_list))

这里我们调用了一个list的构造函数set:这样就能保证列表里没有重复的元素了。是不是很简单?

单个小说所有章节链接:首先我们从前面获取到的小说url连接选取一个做实验:

比如我最爱的择天记:

http://www.qu.la/book/168/

依然是无比清晰的网页结构,点个赞:

825faaa1808c065ad80c314977313019.png

《择天记》正文

序 下山

第一章 我改主意了

第二章 为什么

第九章 我有做错什么吗?

我们可以很容易的找到对应章节的连接:

这个代码是节选,不能直接用!后面会有说明

link='http://www.qu.la/' + url.a['href']

好的,这样我们就能把一篇小说的所有章节的链接爬下来了。

剩下最后一步:爬取文章内容:

文章内容的爬取:首先我们打开一章,并查看他的源代码:

88b86e5cd37d311e477c54d37515668c.png

我们能发现所有的正文内容,都保存在:

所有的章节名就更简单了:

第一章 我改主意了

那我们通过bs4库的各种标签的查找方法,就能很简单的找到啦

好了,让我们看看具体代码的实现:

代码的实现:模块化,函数式编程是一个非常好的习惯,我们坚持把每一个独立的功能都写成函数,这样会使你的代码简单又可复用。

网页抓取头:def get_html(url):

try:

r = requests.get(url, timeout=30)

r.raise_for_status

# 我手动测试了编码。并设置好,这样有助于效率的提升

r.encoding = ('utr-8')

return r.text

except:

return "Someting Wrong!"

获取排行榜小说及其链接:def get_content(url):

'''

爬取每一类型小说排行榜,

按顺序写入文件,

文件内容为 小说名字+小说链接

将内容保存到列表

并且返回一个装满url链接的列表

'''

url_list = []

html = get_html(url)

soup = bs4.BeautifulSoup(html, 'lxml')

# 由于小说排版的原因,历史类和完本类小说不在一个div里

category_list = soup.find_all('div', class_='index_toplist mright mbottom')

history_finished_list = soup.find_all(

'div', class_='index_toplist mbottom')

for cate in category_list:

name = cate.find('div', class_='toptab').span.string

with open('novel_list.csv', 'a+') as f:

f.write("\n小说种类:{} \n".format(name))

# 我们直接通过style属性来定位总排行榜

general_list = cate.find(style='display: block;')

# 找到全部的小说名字,发现他们全部都包含在li标签之中

book_list = general_list.find_all('li')

# 循环遍历出每一个小说的的名字,以及链接

for book in book_list:

link = 'http://www.qu.la/' + book.a['href']

title = book.a['title']

# 我们将所有文章的url地址保存在一个列表变量里

url_list.append(link)

# 这里使用a模式,防止清空文件

with open('novel_list.csv', 'a') as f:

f.write("小说名:{:<} \t 小说地址:{:<} \n".format(title, link))

for cate in history_finished_list:

name = cate.find('div', class_='toptab').span.string

with open('novel_list.csv', 'a') as f:

f.write("\n小说种类:{} \n".format(name))

general_list = cate.find(style='display: block;')

book_list = general_list.find_all('li')

for book in book_list:

link = 'http://www.qu.la/' + book.a['href']

title = book.a['title']

url_list.append(link)

with open('novel_list.csv', 'a') as f:

f.write("小说名:{:<} \t 小说地址:{:<} \n".format(title, link))

return url_list

获取单本小说的所有章节链接:def get_txt_url(url):

'''

获取该小说每个章节的url地址:

并创建小说文件

'''

url_list = []

html = get_html(url)

soup = bs4.BeautifulSoup(html, 'lxml')

lista = soup.find_all('dd')

txt_name = soup.find('h1').text

with open('/Users/ehco/Documents/codestuff/Python-crawler/小说/{}.txt'.format(txt_name), "a+") as f:

f.write('小说标题:{} \n'.format(txt_name))

for url in lista:

url_list.append('http://www.qu.la/' + url.a['href'])

return url_list, txt_name

获取单页文章的内容并保存到本地:这里有个小技巧:

我们从网上趴下来的文件很多时候都是带着
之类的格式化标签,

我们可以通过一个简单的方法把他过滤掉:

html = get_html(url).replace('
', '\n')

我这里单单过滤了一种标签,并将其替换成‘\n’用于文章的换行,

具体怎么扩展,大家可以开动一下自己的脑袋啦

还有,我这里的代码是不能直接在你们的机子上用的,

因为在写入文件的时候,绝对目录不一样

def get_one_txt(url, txt_name):

'''

获取小说每个章节的文本

并写入到本地

'''

html = get_html(url).replace('
', '\n')

soup = bs4.BeautifulSoup(html, 'lxml')

try:

txt = soup.find('div', id='content').text.replace(

'chaptererror();', '')

title = soup.find('title').text

with open('/Users/ehco/Documents/codestuff/Python-crawler/小说/{}.txt'.format(txt_name), "a") as f:

f.write(title + '\n\n')

f.write(txt)

print('当前小说:{} 当前章节{} 已经下载完毕'.format(txt_name, title))

except:

print('someting wrong')

缺点:本次爬虫写的这么顺利,更多的是因为爬的网站是没有反爬虫技术,以及文章分类清晰,结构优美。

但是,按照我们的这篇文的思路去爬取小说,

我大概计算了一下:

一篇文章需要:0.5s

一本小说(1000张左右):8.5分钟

全部排行榜(60本): 8.5小时!

是的! 时间太长了!

那么,这种单线程的爬虫,速度如何能提高呢?

自己洗个多线程模块?

其实还有更好的方式:下一个大的章节我们将一起学习Scrapy框架

学到那里的时候,我再把这里代码重构一边,

你会惊奇的发现,速度几十倍甚至几百倍的提高了!

这其实也是多线程的威力!

最后看一下结果吧:排行榜结果:

7ae258b72e1d88fd7539a687df481a90.png

小说结果:

b159d629e9a9a32b2d2c3541ce437621.png

学到这里是不是越来越喜欢爬虫这个神奇的东西了呢?

加油,更神奇的东西还在后面呢!

每天的学习记录都会 同步更新到:

微信公众号: findyourownway

知乎专栏:从零开始写Python爬虫 - 知乎专栏

blog : www.ehcoblog.ml

Github: Ehco1996/Python-crawler

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/534102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 某个字符在字符串中出现的所有位置_Java面试常考核心概念

这篇文章专注于Java基础知识&#xff0c;不涉及List、Map、多线程、锁相关的内容&#xff0c;需要的可以查看我的其他博客hofes blog​hhf443.github.ioJDK&JRE&JVMJDK&#xff08;Java Development Kit&#xff09;是针对 Java 开发员的产品&#xff0c;是整个 Java 的…

lan交换和无线教师手册_简单几步,无线路由器变交换机

当原来的路由器lan口不够用&#xff0c;可以加一个交换机扩展lan口数量&#xff0c;如果需要增加的lan口数量不超过3个可以考虑找台不用的无线路由器当交换机用。另外&#xff0c;随着交换机更新家中都有旧无线路由器闲置&#xff0c;完全可以再次利用。下面看一下&#xff0c;…

revit找不到附加模块程序集_TensorFlow基础知识——常用模块(一)

1本节简述对于开展深度学习开发的目标而言&#xff0c;我们需要掌握的除了必要的深度学习理论基础、必要的开发依赖库基础知识、基本的开发套路之外&#xff0c;我们还需要掌握它常见的外围小帮手都有哪些。这些小帮手就是深度学习依赖库中的其他并不是核心的模块&#xff0c;但…

99 网络编程_网络工程师技能图谱,看看你会多少技能

技术推动了时代变革&#xff0c;互联网则加速了这场变革。在蓬勃发展的互联网浪潮下&#xff0c;网络作为基础设施的关键纽带保障着网路流量的顺利流通&#xff0c;维持着赛博世界的繁荣。而在这繁荣之下&#xff0c;生存着这样一个群体——网络工程狮&#xff0c;为网络纽带保…

python 3.8.0安卓_Python for Mac v3.8.0 官方最新版

Python for Mac是一款全新推出的编程工具&#xff0c;所有 python.org macOS 安装程序都附带了 OpenSSL 的内置副本。此外&#xff0c;还有一个针对 macOS 10.9 的新增安装程序变体&#xff0c;其中包含 Tcl / Tk 8.6的内置版本&#xff0c;有需要的朋友快来下载试试吧!Python …

线程join_Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

点击上方“Coder编程”&#xff0c;选择“置顶公众号”技术文章第一时间送达&#xff01;并发编程.png每天进步一点&#xff0c;不做curd工程师与Api调用工程师 欢迎访问个人博客网站&#xff1a;https://www.coder-programming.cn/ 作者&#xff1a;liuxiaopeng | http://www…

4位先行进位电路 logisim_你真的了解74系列集成电路吗?让我帮你总结一下

74系列集成电路大致可分为6大类&#xff1a;74(标准型)74LS(低功耗肖特基)74S(肖特基)74ALS(先进低功耗肖特基)74AS(先进肖特基)74F(高速)HC为COMS工作电平&#xff1b;HCT为TTL工作电平&#xff0c;可与74LS系列互换使用HCU适用于无缓冲级的CMOS电路。这9种74系列产品&#xf…

android ios av tv,iOS使用AVPlayer制作战旗TvDEMO OC版

在视频教学中看到一个别人写的战旗TvDEMO写得很好&#xff0c;于是自己动手试着制作一个。效果如下图所示主界面竖屏播放横屏播放点击出现工具栏视频播放使用的是AVPlayer,具体的使用方式如下//---PlayView---_playView [[UIView alloc]init];_playView.frame CGRectMake(0, …

matlab 子图title的位置_matlab 画图基本介绍

1.在命令窗口输入命令时&#xff0c;可以不必每输入一条命令就按enter键执行&#xff0c;可以在输入几行后一同运行。方法是&#xff1a;换行时&#xff0c;只要在按住<shift>键的同时按<enter>键即可&#xff0c;否则matlab就会执行上面输入的所有语句。2.如何将数…

二元一次方程有唯一解的条件_人教版初中数学七年级下册用适当方法解二元一次方程组公开课优质课课件教案视频...

解二元一次方程组---加减法一、教学目的&#xff1a;1&#xff0e;使学生掌握用加减法解二元一次方程组的步骤。2&#xff0e;熟练运用加减法解二元一次方程组。3&#xff0e;培养学生分析问题、解决问题的能力。二、教学重点、难点和关键&#xff08;一&#xff09;重点&#…

为什么从网页上打印怎们好像被缩放_全网最详细关于3D打印的zbrush技术

这个小教程旨在为刚开始对3D打印感兴趣的新人朋友提供一些快速上手小技巧&#xff0c;以便在zbrush中制作适合桌面FDM 3D打印的创作&#xff0c;本次小教程需要读者已经有一些zbrush基础知识。1设置系统单位导入1英尺的box&#xff0c;1英尺X1英尺X1英尺。一旦导入到场景中&…

android图片浏览远近,快图浏览编辑图片方法介绍_怎么编辑图片_3DM手游

既然是图片管理工具&#xff0c;那么快图浏览肯定也是少不了图片编辑功能的。如何使用快图浏览编辑图片呢&#xff1f;下面小编带来的详细的使用方法&#xff0c;有需要的小伙伴一起来看看吧&#xff01;编辑照片方法介绍&#xff1a;1.第一步&#xff0c;下载安装快图浏览&…

matlab 三维 作图 坐标轴_MATLAB学习——MATLAB中的三维绘图指令

2 基本XYZ立体绘图命令mesh和plot是三度空间立体绘图的基本命令&#xff0c;mesh可画出立体网状图&#xff0c;plot则可画出立体曲面图&#xff0c;两者产生的图形都会依高度而有不同颜色。下列命令可画出由函数形成的立体网状图: xlinspace(-2, 2, 25); % 在x轴上取25点 ylins…

说说python程序的执行过程_表示说的词语

展开全部1、奉劝 [ fng qun ] 释义&#xff1a;敬辞。郑重劝说62616964757a686964616fe58685e5aeb931333365653331。 造句&#xff1a;我们厌恶那些阴险的恶人&#xff0c;奉劝他们改恶为善&#xff0c;才能得到社会的原谅&#xff01; 2、劝告 [ qun go ] 释义&#xff1a;拿道…

HTML4基本编译原理,Stanford公开课《编译原理》学习笔记(1~4课)

课程里涉及到的内容讲的还是很清楚的&#xff0c;但个别地方有点脱节&#xff0c;任何看不懂卡住的地方&#xff0c;请自行查阅经典著作《Compilers——priciples, Techniques and Tools》(也就是大名鼎鼎的龙书)的对应章节。一. 编译的基本流程完整的编译的5个基本步骤包括lex…

rocketmq 消息指定_SpringBoot 整合 RocketMQ 如何实现消息生产消费?

有时候我们在使用消息队列的时候&#xff0c;往往需要能够保证消息的顺序消费&#xff0c;而RocketMQ是可以支持消息的顺序消费的。RocketMQ在发送消息的时候&#xff0c;是将消息发送到不同的队列中&#xff0c;然后消费端从多个队列中读取消息进行消费&#xff0c;很明显&…

mysql怎么看实例名_南方“中看不中吃”的前4名水果,莲雾只是垫底,你怎么看?...

水果很多人都喜欢吃&#xff0c;南方人可以说是最幸福的&#xff0c;因为南方的水果种类有很多种&#xff0c;而且水果的价格也很便宜&#xff0c;一年四季都能吃到便宜又好吃的水果&#xff0c;南方的很多水果&#xff0c;北方人可能都没有吃过&#xff0c;虽然南方的水果种类…

vuex中的值变化 页面重新渲染_浅谈浏览器的渲染过程,重绘与回流

浏览器的渲染过程 首先&#xff0c;我们先来了解一下浏览器的渲染过程是什么样的&#xff0c;也就是说浏览器把一堆代码呈现到页面上的过程是什么样子的&#xff0c;浏览器采用流式布局模型(Flow Bsaed Layout)&#xff0c;根据下图&#xff0c;我们可以总结出浏览器的渲染步骤…

vc 将已有项目打包成dll 并应用于其他项目_.NET混淆器 Dotfuscator使用教程:保护你的应用之存档报告文件...

Dotfuscator是一款.NET混淆器和压缩器&#xff0c;防止你的应用程序被反编译。本篇文章将继续上一篇文章与大家分享保护应用程序的后续三个部分&#xff1a;存档报告文件、加强保护和替代方法。存档报告文件作为构建的一部分&#xff0c;Dotfuscator会生成报告文件(在Dotfuscat…

html文件内容搜索,html读出文本文件内容

html读出文本文件内容更新时间&#xff1a;2007年01月22日 00:00:00 作者&#xff1a;Function bytes2BSTR(vIn)strReturn ""For i 1 To LenB(vIn)ThisCharCode AscB(MidB(vIn,i,1))If ThisCharCode strReturn strReturn & Chr(ThisCharCode)ElseNextCharC…