爬取背景
小说网站:纵横中文网
爬取网站小说,算是一个简单的爬虫基础入门。新手可能会遇到一些不懂得地方,适合用来练手。
优化部分
- 可以添加代理IP,防止IP被封。(未添加)可参考 爬取西刺可用代理IP。
开始实战
-
爬虫准备:
pip install requests
pip install BeautifulSoup
作用:
requests
用来请求网页。
BeautifulSoup
用来解析网页,这个可以使用正则表达式
代替。 -
文章内容获取:
1.有个简单的方法,浏览器上右键元素审查即可。但是小说网站上,一般不能右键查看源代码…
2.所以,我们可以使用requests
输出网页源码
3.我们发现,正文内容在标签为<div class="content" itemprop="acticleBody">
下面。
4.可以使用’BeautifulSoup’来进行正文匹配。
代码:def download(): cnt=0 print("正在下载....") for i in range(file_num): target=file_list_url[i] #获取下载地址 r=requests.get(target) html=r.text #得到html bf=BS(html,"lxml") texts=bf.find_all('div',class_='content',itemprop='acticleBody') #寻找正文部分 ac=[] for k in range(len(texts[0].contents)): tmp=str(texts[0].contents[k]).replace("</p>","\n") ac.append(tmp.replace("<p>","")) #ac= texts[0].text.replace("。","。\n") #切割换行 write_text(str(file_list_name[i]+".txt"),ac) #写入 time.sleep(3) #等待3s,防止出现验证码 print("已完成"+str(i+1)+"部章节")
这里有一点需要注意,没用直接使用
texts[0].text
的原因是,获取的文本内容全部在一起,中间没有换行。因此,使用的方法是,将contents
里面的内容进行处理,用来代替text
。 -
文章目录获取:
文章目录的获取,和正文类似。需要注意的是,获取下载链接。
可以看到,文章的链接为href="xxxx"
,可以直接通过’attrs’来获取,也可以使用get()
方法。
代码:def get_list(url): r=requests.get(url) html=r.text bf=BS(html,"lxml") texts=bf.find_all('div', class_ = 'volume-list') #获取标题的列表 bf=BS(str(texts[0]),"lxml") texts=bf.find_all('a') #从标题列表中筛选出需要的 file = [] #标题列表 for ac in texts: if(str(ac.text)=="[分卷阅读]"): #除去目录中无用的url continue file.append(str(ac.text)+" "+str(ac.get('href'))+'\n')#标题名加入到列表中 #file_list_url.append(str(ac.get('href'))) #存入下载地址 file_list_url.append(ac.attrs['href']) #存入下载地址 file_list_name.append(str(ac.text)) #存入小说名 global file_num #全局变量必须在函数内部说明 使用 global file_num = file_num + 1 #下载数目 print("获得目录数量:"+str(file_num)) write_text("目录.txt",file) #写入文件
-
总体代码:
import requests #获取网页信息 from bs4 import BeautifulSoup as BS #解析网页,比正则表达式好用太多了 import time #定时 url="http://book.zongheng.com/showchapter/490327.html" #需要填写的目录列表 file_num = 0 #下载文件数目 file_list_url = [] #下载的url file_list_name = [] #下载的名字 def download(): cnt=0 print("正在下载....") for i in range(file_num): target=file_list_url[i] #获取下载地址 r=requests.get(target) html=r.text #得到html bf=BS(html,"lxml") texts=bf.find_all('div',class_='content',itemprop='acticleBody') #寻找正文部分 ac=[] for k in range(len(texts[0].contents)): tmp=str(texts[0].contents[k]).replace("</p>","\n") ac.append(tmp.replace("<p>","")) #ac= texts[0].text.replace("。","。\n") #切割换行 write_text(str(file_list_name[i]+".txt"),ac) #写入 time.sleep(3) #等待3s,防止出现验证码 print("已完成"+str(i+1)+"部章节") def get_list(url): r=requests.get(url) html=r.text bf=BS(html,"lxml") texts=bf.find_all('div', class_ = 'volume-list') #获取标题的列表 bf=BS(str(texts[0]),"lxml") texts=bf.find_all('a') #从标题列表中筛选出需要的 file = [] #标题列表 for ac in texts: if(str(ac.text)=="[分卷阅读]"): #除去目录中无用的url continue file.append(str(ac.text)+" "+str(ac.get('href'))+'\n')#标题名加入到列表中 #file_list_url.append(str(ac.get('href'))) #存入下载地址 file_list_url.append(ac.attrs['href']) #存入下载地址 file_list_name.append(str(ac.text)) #存入小说名 global file_num #全局变量必须在函数内部说明 使用 global file_num = file_num + 1 #下载数目 print("获得目录数量:"+str(file_num)) write_text("目录.txt",file) #写入文件 def write_text( name , text ): file = open(str(name),'w') #打开文件,覆盖写文件 if(str(type(text))==r"<class 'list'>"): #当为列表的时候,逐行输出 for i in text: file.write(i) else: file.write(str(text)) #写入文件 file.flush() #刷新缓冲区 file.close() #关闭文件 if __name__ == '__main__': get_list(url) #下载 download() #下载章节 print("\n---finish!---")
-
成果展示
- 运行窗口
- 下载目录
- 下载内容