之前试过用按照目录地址爬取正文内容的方法来爬取《鬓边不是海棠红》这本小说,结果由于它目录中的每一章又被分为了几页来展示,那种方法只能爬取到每章的第一页内容,剩下的内容都没有拿到,所以现在来换一种方法吧~
上一个方法的链接
之前的文章中已经详细地写了分析网页的方法,这里就不多写了,直接说一下实现思路吧:
①首先以小说第一章第一页作为开始爬取的页面,并爬取第一页的正文内容;
②然后获取到下一页的链接,继续爬取下一页的正文内容;
③就这样每爬取一页就更新需要爬取的页面链接,直到最后一页;
④最后把爬取到的正文保存在本地的txt文档中。
import requests
from bs4 import BeautifulSoup
requests 库是用来发网络请求的,BeautifulSoup 是用来解析和提取 HTML 数据的。
关于它俩的详细说明可以参考我之前的文章呀:爬虫学习笔记——爬取单个网页里的所有图片(入门)
这部分代码的详细说明建议参考前一篇文章——Python爬虫练习笔记——爬取一本小说《鬓边…》
def getHtml(url):
#获取网页数据
html = requests.get(url)
htmlCode = html.text
#解析网页
soup = BeautifulSoup(htmlCode,'html.parser')
#返回解析后的页面内容
return soup
这部分代码的详细说明建议继续参考前一篇文章——Python爬虫练习笔记——爬取一本小说《鬓边…》
def getNovelContent(url):
soup = getHtml(url)
#获得需要的正文内容
content = soup.find('div', class_="contentbox").text
content = content.strip()
contentCut = content.replace("本章未完,点击[ 下一页 ]继续阅读-->>","").replace("本章有错误,我要提交上一章 返回目录 下一章","").replace("小提示:按 回车[Enter]键 返回书目,按 ←键 返回上一页, 按 →键 进入下一页。","")
return contentCut
从这里开始就是新方法了!
在这个方法中,获取下一页的链接很重要。
以第一页为例:下一页的链接 “7489410_2.html” 格式与第一页链接的格式相同,就可以不做其它处理直接拿来用了。
这个链接放在 id="pager_next"
的 标签里,可以用
soup.find('a',id="pager_next")
拿出来,之后再用a['href']
取出里面的href属性值即可。
考虑到了最后一页爬取完成以后需要停止(这样会好看一些~),可以再看看最后一页里 “下一页” 的链接是什么样,根据它的特点来进行判断。
这里看到最后一页里 “下一章” 带的属性值内容是“javascript:opentks(‘已经是最后一章了!请等待更新……’);”,我就直接用判断'javascript:opentks'
字符串是否在 url 中来判断了~
这部分代码如下:
#获取下一页链接
def getNextPage(url):
soup = getHtml(url)
# 获得“下一章”按钮链接
nextUrl = soup.find('a',id="pager_next")['href']
if 'javascript:opentks' in nextUrl:
return False
else:
#返回下一页链接
return nextUrl
还是以第一页举栗子:
整个爬取的过程就是 先获取到第一页的正文内容,之后就需要获得下一页的链接,再获取下一页的正文内容,重复重复重复到最后就完成了。这个效果可以用while
循环来完成。
文件读写部分还是用 with open(…) as …
方法。
该方法的详细说明还是建议继续参考前一篇文章——Python爬虫练习笔记——爬取一本小说《鬓边…》
pageUrl = firstUrl
with open('%s.txt'%title, 'a' ,encoding='utf-8') as f:
while pageUrl:
# 拼接完整的章节链接地址
chapterUrl = url + pageUrl
chapterContent = getNovelContent(chapterUrl)
f.write(chapterContent)
print('***第{}页下载完成***'.format(num))
num += 1
#将pageUrl更新为下一页的地址
pageUrl = getNextPage(chapterUrl)
f.close()
RunRunRun!
最终的结果还是很漂亮的~
(直接看了大结局,小来明明没有死!!!有一起给导演寄刀片的吗?)
这篇文章里很多地方之前都是已经详细写过一次的,所以在这里没有重复复制粘贴一遍了,嗯,就这样。
最后附上完整代码:
import requests
from bs4 import BeautifulSoup
#获取网站数据
def getHtml(url):
#获取网页数据
html = requests.get(url)
htmlCode = html.text
#解析网页
soup = BeautifulSoup(htmlCode,'html.parser')
#返回解析后的页面内容
return soup
#获取标题
def getTitle(url):
soup = getHtml(url)
title = soup.find('div',class_="book_info").find('h1').string
return title
#获取各章节正文
def getNovelContent(url):
soup = getHtml(url)
#获得需要的正文内容
content = soup.find('div', class_="contentbox").text
content = content.strip()
contentCut = content.replace("本章未完,点击[ 下一页 ]继续阅读-->>","").replace("本章有错误,我要提交上一章 返回目录 下一章","").replace("小提示:按 回车[Enter]键 返回书目,按 ←键 返回上一页, 按 →键 进入下一页。","")
return contentCut
#获取下一页链接
def getNextPage(url):
soup = getHtml(url)
# 获得“下一章”按钮链接
nextUrl = soup.find('a',id="pager_next")['href']
if 'javascript:opentks' in nextUrl:
return False
else:
return nextUrl
#保存到本地
def saveNovel(url):
pageUrl = firstUrl
title = getTitle(url)
num = 1
with open('%s.txt'%title, 'a' ,encoding='utf-8') as f:
while pageUrl:
# 拼接完整的章节链接地址
chapterUrl = url + pageUrl
chapterContent = getNovelContent(chapterUrl)
f.write(chapterContent)
print('***第{}页下载完成***'.format(num))
num += 1
#将pageUrl更新为下一页的地址
pageUrl = getNextPage(chapterUrl)
print('***《%s》小说全文下载完成***'%title)
f.close()
if __name__=='__main__':
ListUrl='http://www.moyanxsw.com/binbianbushihaitanghong/'
firstUrl = '7489410.html'
saveNovel(ListUrl)
撒花~~~ ✿✿✿✿✿✿✿✿✿✿✿✿ヽ(°▽°)ノ✿✿✿✿✿✿✿✿✿✿✿