分享一个简单网络小说爬取案例,代码中附有注释。
import urllib.request
import re
#conding:utf-8
import requests #导入库
from bs4 import BeautifulSoup #导入bs
import re
def get_novel_chapters(): #获取小说每一章的链接
root_url="小说首页根目录网址"
r = requests.get(root_url) #发送request请求
r.encoding="utf-8" #网页编码为utf-8
soup = BeautifulSoup(r.text,"html.parser")#创建bs4对象,解析器用官方的html.parser
data = [] #创建一个列表保存每一章的链接
print(soup)
for li in soup.find_all("dd",):#匹配所有li标签
link=li
link = li.find("a",href=re.compile("info"))
# 匹配所有的href带info字样的链接
if not link: #如果没获取到链接,就忽略
continue
text=re.findall("\d+",link.get_text().strip())
if len(text)!=0:
count=re.findall("\d+",link.get_text().strip())[0]#获取小说章节号,便于排序章节
data.append(["小说网站首页网址%s"%link['href'],link.get_text().strip(),count])
else:
print("不在范围内",link.get_text().strip(),"小说网站首页网址%s"%link['href'])
print(data)#去掉小说重复章节
a = data
b = []
for i in a:
if i not in b:
i[2]=int(i[2])
b.append(i)
data=b
data=sorted(data,key=lambda x:x[2])
return data #返回小说所有章节的链接和标题,link.get_text()
def get_chapter_content(url): #从所有小说的链接中解析每一章链接中的小说正文部分和标题
r = requests.get(url)
r.encoding="utf-8"
soup = BeautifulSoup(r.text,"html.parser")
try:
mystr=soup.find("div",class_='showtxt').get_text()
# print(mystr)
# print("".join([s for s in mystr.splitlines(True) if s.strip()]) )
return "".join([s for s in mystr.splitlines(True) if s.strip()]) #获取div标签里的文本get.text()
except: #忽略没有获取到的小说文本的链接
pass
import time
for j,chapter in enumerate(get_novel_chapters()):
if j%100==0:
time.sleep(10)#设置推迟调用线程的运行,降低请求频率
url,title,count = chapter #从data文件中读取每一章小说的链接和标题并赋值
print(chapter)
f=open("novel.txt","a",encoding='utf-8')
f.write("\n"+title+"\n")
f.write((get_chapter_content(url)).strip())
print("%s.txt"%title) #打印已经写入小说的文本