爬虫实践---抓取小说网站

电子书网站:http://www.7kanshu.net/
对网页进行分析可知,玄幻奇幻排行武侠仙侠排行历史军事排行完本小说排行观察发现,历史军事和完本小说的时一致的,其余类别是一样的,所以进行分开处理。每一个分类都是包裹在: 之中 这种调理清晰的网站,大大方便了我们爬虫的编写一个类别里,出现了排行榜上所有的小说:玄幻奇幻排行05-061.择天记05-062.大主宰05-063.太古神王05-064.雪鹰领主05-0115

电子书网站:

http://www.7kanshu.net/

对网页进行分析可知,

玄幻奇幻排行
武侠仙侠排行
历史军事排行
完本小说排行

观察发现,历史军事和完本小说的时一致的,其余类别是一样的,所以进行分开处理。

每一个分类都是包裹在:

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

一个类别里,出现了排行榜上所有的小说:

玄幻奇幻排行
05-061.择天记
05-062.大主宰

05-063.太古神王
05-064.雪鹰领主
05-0115.武动乾坤

08-011.圣墟

标题:title = div.a['title'] 链接:link = 'http://www.7kanshu.net/' + div.a['href']

比如小说圣墟链接==http://www.7kanshu.net/0_11/index.html

观察可知==网站链接+书本链接

由于在总/周/月排行中难免出现重复的电子书,所以进行了列表去重操作:

列表去重的小技巧:

尤其是在面对爬大量网页的时候,会浪费大量的资源,那么我们如何从抓取的url列表里去重呢? 刚学Python的小伙伴可能会去实现一个循环算法,来去重, 但是Python的强大之处就在于他可以通过及其优美的方式来解决很多问题,这里其实只要一行代码就能解决: url_list = list(set(url_list)) 这里我们调用了一个list的构造函数set:这样就能保证列表里没有重复的元素了。

然后我们对于电子书《择天记》进行操作:

观察网页信息可知,

《择天记》正文
序 下山
第一章 我改主意了
第二章 为什么
......
重要通知
第一百四十一章 神隐之路
后记

link='http://www.7kanshu.net/' + url.a['href']

打开各章节的内容,查看可知:

《太古神王》正文卷
第一章 断脉修行
第二章 恩将仇报
第三章 天才觉醒
......

我们能发现所有的正文内容,都保存在: 所有的章节名就更简单了: 第一章 我改主意了 那我们通过bs4库的各种标签的查找方法,就能很简单的找到啦 好了,让我们看看具体代码的实现:

打开任意章节:

;

世界是相对的。

中土大陆隔着海洋与大西洲遥遥相对。东方地势较高,那里的天空似乎也高了起来,云雾从海上陆地上升腾而起,不停向着那处飘去,最终汇聚在一起,终年不散。

......

开始处,id="content"

结尾处,chaptererror();

这里有个小技巧: 我们从网上趴下来的文件很多时候都是带着
之类的格式化标签, 我们可以通过一个简单的方法把他过滤掉:

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

!/usr/bin/env python

coding=utf-8

import requests
import bs4
def get_html(url): #网页内容抓取
try:
r = requests.get(url,timeout=30)
r.raise_for_status
r.encoding = r.apparent_encoding

r.encoding = 'utf-8'

return r.text
except:
print("Open Error!!!")
def get_content(url):
"""
爬取每一类型小说排行榜,
按顺序写入文件,
文件内容为 小说名字+小说链接
将内容保存到列表
并且返回一个装满url链接的列表
"""
url_list = []
html = get_html(url)

煮汤

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

看到历史类和完本类的小说与其他小说不在一个div,分开读取

category_list = soup.find_all('div', attrs={'class:','index_toplist mright mbottom'})

匹配历史和完本类别的数目

histoty_finished_list = soup.find_all('div', attrs={'class:','index_toplist mbottom'})
for cate in category_list:
name = cate.find('div',attrs={'class:','toptab'}).span.string
with open('novel_list.csv', 'a+') as f:
f.write("/n小说种类:{} /n".format(name))

通过id来对总排行榜进行定位,

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

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

book_list = general_list.find_all('li')

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

for book in book_list:
link = 'http://www.7kanshu.net/' + 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 histoty_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.7kanshu.net/' + 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')

dd是包含小说每一章节链接

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

h1 是小说标题

with open ('小说/{}.txt'.format(txt_name),"a+") as f:
print("小说:%s文件创建成功!" %txt_name)
f.write('小说标题:{}/n'.format(txt_name))
for url in lista:
url_list.append('http://www.7kanshu.net/' + url.a['href'])
return url_list, txt_name
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 ('小说/{}.txt'.format(txt_name),"a") as f:
f.write(title+'/n/n')
f.write(txt)
print("当前小说:{} 当前章节:{} 已经下载完毕".format(txt_name,title))
except:
print("Something wrong")
def get_all_txt(url_list):
"""下载排行榜里所有的小说
并保存为txt格式
"""
for url in url_list:

获取当前小说的所有章节目录

并且声称小说头文件

page_list, txt_name = get_txt_url(url)
"""
for page_url in page_list:

遍历每一篇小说,并下载到目录

get_one_txt(page_url, txt_name)
print('当前进度 {}% '.format(url_list.index(url) / len(url_list) * 100))
"""
def main():

排行榜地址

base_url = 'http://www.7kanshu.net/top/allvisit/1.html'

获取排行榜中所有小说链接

url_list = get_content(base_url)

除去重复小说

url_list = list(set(url_list))
get_all_txt(url_list)
if __name__=='__main__':
main()
缺点:
本次爬虫写的这么顺利,更多的是因为爬的网站是没有反爬虫技术,以及文章分类清晰,结构优美。 但是,按照我们的这篇文的思路去爬取小说,我大概计算了一下: 一篇文章需要:0.5s 一本小说(1000张左右):8.5分钟 全部排行榜(60本): 8.5小时!
这种单线程的爬虫,速度如何能提高呢?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值