国际 网站制作公司,wordpress 百度网盘,谁做的四虎网站是多少钱,网站设计如何在ps先做从零开始写Python爬虫 --- 1.7 爬虫实践#xff1a; 排行榜小说批量下载Ehco
5 个月前
本来只是准备做一个爬起点小说名字的爬虫#xff0c;后来想了一下#xff0c;为啥不顺便把小说的内容也爬下来呢#xff1f;于是我就写了这个爬虫#xff0c;他爬下了各类小说排行榜上…从零开始写Python爬虫 --- 1.7 爬虫实践 排行榜小说批量下载Ehco
5 个月前
本来只是准备做一个爬起点小说名字的爬虫后来想了一下为啥不顺便把小说的内容也爬下来呢于是我就写了这个爬虫他爬下了各类小说排行榜上的所有章节内容并保存到本地。仔细想了一下各种盗版小说阅读器是不是就是这样做的呢
目标分析首先来看看我们排行榜的地址
http://www.qu.la/paihangbang/
我们的目的很明确
找到各类排行旁的的每一部小说的名字和在该网站的链接
观察一下网页的结构我们很容易就能发现每一个分类都是包裹在之中这种调理清晰的网站大大方便了我们爬虫的编写小说标题和链接我们在刚才那个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/依然是无比清晰的网页结构点个赞《择天记》正文 序 下山 第一章 我改主意了 第二章 为什么 第九章 我有做错什么吗?我们可以很容易的找到对应章节的连接这个代码是节选不能直接用后面会有说明linkhttp://www.qu.la/ url.a[href]好的这样我们就能把一篇小说的所有章节的链接爬下来了。剩下最后一步爬取文章内容文章内容的爬取首先我们打开一章并查看他的源代码我们能发现所有的正文内容都保存在所有的章节名就更简单了 第一章 我改主意了那我们通过bs4库的各种标签的查找方法就能很简单的找到啦好了让我们看看具体代码的实现代码的实现模块化函数式编程是一个非常好的习惯我们坚持把每一个独立的功能都写成函数这样会使你的代码简单又可复用。网页抓取头def get_html(url):try:r requests.get(url, timeout30)r.raise_for_status# 我手动测试了编码。并设置好这样有助于效率的提升r.encoding (utr-8)return r.textexcept: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.stringwith open(novel_list.csv, a) as f:f.write(\n小说种类{} \n.format(name))# 我们直接通过style属性来定位总排行榜general_list cate.find(styledisplay: 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.stringwith open(novel_list.csv, a) as f:f.write(\n小说种类{} \n.format(name))general_list cate.find(styledisplay: 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).textwith 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, idcontent).text.replace(chaptererror();, )title soup.find(title).textwith 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框架学到那里的时候我再把这里代码重构一边你会惊奇的发现速度几十倍甚至几百倍的提高了这其实也是多线程的威力最后看一下结果吧排行榜结果小说结果学到这里是不是越来越喜欢爬虫这个神奇的东西了呢加油更神奇的东西还在后面呢每天的学习记录都会 同步更新到微信公众号 findyourownway知乎专栏从零开始写Python爬虫 - 知乎专栏blog www.ehcoblog.mlGithub Ehco1996/Python-crawler