一、前言
最近在学习爬虫,目前算是勉强入门了吧。今天分享一个练手项目,内容就是对小说内容进行爬取,将其保存在对应的txt文件中,这次没有使用selenium自动化,使用requests等库进行的。
这次是以这个网站为例:
应该是盗版网站,爬起来应该不碍事
二、思路
1、根据小说名创建对应的文件夹
2、获取查询结果并根据链接进行爬取
3、对爬取结果进行分析整理和保存
4、查验数据是否有误并退出
三、爬取详解
1、网页元素分析
网站首页如上,随便点击一个小说,进去看看网页元素;
想想我们需要的信息-小说名称,小说章节,小说内容等等,其中小说名称用来建立文件夹,小说章节用来创建对应txt文件,小说内容进行保存。
接下来就可以看看这些需要的信息保存在哪个位置了,因为这次使用的是requests库,所以需要看源代码,我习惯是看看源代码与网页代码(就是右键-检查-看到的代码)一不一样,有的时候源代码很不好看,不如看网页代码清晰;如果两者不一致,那就算了,搞不了。而且如果信息不在源代码里面,那也算了,使用这个requests搞不了,建议使用selenium。
这次选的网站就很nice,各种信息清晰明了,可以发现小说章节名和小说名称都很好找,那小说对应章节内容在哪呢,当然在链接里面啦,就是dd标签里面的href,它就是对应的小说章节链接,我们后续可以根据这个链接来爬取内容。
如上图所示,注意一下小说章节内容的网址与之前href里的链接的相同点和差异,后面会用到;然后看看红色框框,那里就是小说内容。
综上,我们所需要的信息的位置就都确定了,接下来就可以编写代码了。
2、编写代码
我习惯将过程合成函数形式,然后进行调用,这样看起来比较好看,也可以跟棍子一样,一股脑儿的写下去;
第一步---获取小说名,进而创建文件夹
def getwenjianja(name):#主要根据小说创建一个文件夹,文件夹名称就是小说名,name就是小说名
path = "example"#自己选择自己想放的位置
os.chdir(path)#打开这个目录
os.makedirs(name)#创建对应的文件夹
第二步---获取章节名,创建文件
def getwenjian(listtile):#根据小说章节创建对应的txt文件,传入的参数就是获取的章节名列表
for i in range(1,len(listtile)):
f=open('C:\\Users\\YEER\\Desktop\\{}\\{}.txt'.format(listtile[0][:4],listtile[i]),"a")#这里就是单纯的创建文件,不对文件做处理
f.close()#可以使用with-open,就可以不加这个close函数
第三步---获取信息并整理
def dettxt(url):#根据url获取网页响应及信息,后面会调用
hearders={"自己的hearders"}
response = requests.get(url, headers=hearders)
if response.status_code == 200:#判断网页是否正确访问
return response.text
else:
return "网页响应代码是:{}".format(response.status_code)
def gettitle(html,listtitle):#获取小说章节并返回章节链接列表,方便后面进行访问获取内容
soup = BeautifulSoup(html, 'html.parser')
list1=[]
listlink=[]
list2=[]
for title in soup.find_all('div',class_='listmain'):
list1.append(title.text)
list2=list1[0].split("\n")
for i in range(len(list2)):
if list2[i]!="":
listtitle.append(list2[i])
for i in range(len(listtitle)):
listtitle[i] = listtitle[i].replace('<<---展开全部章节--->>', '').replace('?','')#第10章名称包含特殊字符,无法创建文件,所以搞掉
listlink=re.findall('<dd><a href ="(.*?)">',html)#获取各个章节对应的网址
return listlink
def getcontent(url,path1):#根据链接和文件来获取章节内容并保存
r=dettxt(url)
soup=BeautifulSoup(r,'html.parser')
content1=soup.find_all('div',id="chaptercontent")
with open(path1,'w') as f:
f.write(str(content1[0].text.replace(" ","\n")))#对其进行段落换行,原始的数据就是一大串字符
print("{}输出完成".format(path1))#做一个进度显示,方便了解爬取进度,也可以使用计数方法来显示进度条
def main():#主函数
url="https://www.bqg128.com/book/16267/"
url1="https://www.bqg128.com"
r=dettxt(url)
listtitle=[]
listlink=gettitle(r,listtitle)
getwenjianja(listtitle[0][:4])#小说名称
getwenjian(listtitle)#小说内具体的章节名称
for i in range(len(listlink)):
getcontent(url1+listlink[i],'C:\\Users\\YEER\\Desktop\\{}\\{}.txt'.format(listtitle[0][:4],listtitle[i]))
3、爬取结果验证
可以看到,结果一致,这次实验成功啦
四、完整代码
#自动爬取网页小说并保存对应章节文件
import requests
from bs4 import BeautifulSoup
import re
import os
def dettxt(url):#根据url获取网页响应及信息
hearders={"自己的请求头"}
response = requests.get(url, headers=hearders)
if response.status_code == 200:#判断网页是否正确访问
return response.text
else:
return "网页响应代码是:{}".format(response.status_code)
def gettitle(html,listtitle):#获取小说章节
soup = BeautifulSoup(html, 'html.parser')
list1=[]
listlink=[]
list2=[]
for title in soup.find_all('div',class_='listmain'):
list1.append(title.text)
list2=list1[0].split("\n")
for i in range(len(list2)):
if list2[i]!="":
listtitle.append(list2[i])
for i in range(len(listtitle)):
listtitle[i] = listtitle[i].replace('<<---展开全部章节--->>', '').replace('?','')#第10章名称包含特殊字符,无法创建文件,所以搞掉
listlink=re.findall('<dd><a href ="(.*?)">',html)#获取各个章节对应的网址
return listlink
def getwenjianja(name):#主要根据小说创建一个文件夹,文件夹名称就是小说名
path = "C:\\Users\\YEER\\Desktop"
os.chdir(path)
os.makedirs(name)
def getwenjian(listtile):#根据小说章节创建对应的txt文件
for i in range(1,len(listtile)):
f=open('桌面\\{}\\{}.txt'.format(listtile[0][:4],listtile[i]),"a")
f.close()#可以使用with-open,就可以不加这个close函数
def getcontent(url,path1):#根据链接和文件来获取章节内容并保存
r=dettxt(url)
soup=BeautifulSoup(r,'html.parser')
content1=soup.find('div',id="chaptercontent")
with open(path1,'w') as f:
f.write(content1.text.replace(" ","\n"))#对其进行段落换行,原始的数据就是一大串字符
print("{}输出完成".format(path1))#做一个进度显示,方便了解爬取进度,也可以使用计数方法来显示进度条
def main():
url="https://www.bq01.cc/index/44368/"
url1="https://www.bq01.cc"#这个网址可能会不定期更换,盗版嘛,可以理解
r=dettxt(url)
listtitle=[]
listlink=gettitle(r,listtitle)
getwenjianja(listtitle[0][:4])#小说名称
getwenjian(listtitle)#小说内具体的章节名称
for i in range(len(listlink)):
getcontent(url1+listlink[i],'桌面\\{}\\{}.txt'.format(listtitle[0][:4],listtitle[i+1]))
main()
#若是换别的小说,可以更改url链接即可,一般情况下其html的位置不会变
五、总结
这次项目主要利用requests库来获取内容,但是这东西在效率上相对较慢,当然比人工要快一点,要加快效率的话,可以研究研究异步爬虫或者scrapy爬虫;当然了,玩这个的时候还是要注意一下素质,不要一个劲儿的去搞人家,羊毛不能逮着一只薅。
最后,欢迎各位大佬指导。