python爬虫初学入门实战(附完整代码)
——下载笔趣阁里的书籍并保存为txt文档(1)
文章目录
实验环境
操作系统:windows 10
版本:python 3.8,并且已经安装requests库和bs4库
时间:2020-08-14
实验过程
http://www.biquge.info/92_92843/
以此链接的书籍为例子,进行书籍的下载
解析书本目录
在目录页面上点击ctrl+u进行源码分析,
分析出每一章节的url,并且获得每一章节的章节名,以便后面写入txt文档
这里使用了beautiful soup来解析源码
def geturl_list(path, url):
text = gethtml(url)
soup = BeautifulSoup(text, "html.parser")
#获得书名
name = soup.find("h1").string
#保存到txt文件
fp = create_file(path,name)
for i in soup.find_all('dd'):
i_in = i.find("a")
each_url = url + i_in.get("href")
#章节名
chapter_name = i.string
#文章内容
chapter = get_chapter(each_url)
fp.write("\n\n"+chapter_name+"\n"+chapter)
print(chapter_name+"下载成功")
fp.close()
解析章节内容
进入其中一个章节,继续检查源码
文章内容都放在“<!-go->” 到“<!-over->”之间,我们可以使用正则表达式匹配,提取出整个文章。使用re.S,不会对\n进行中断,保证文章的完整性。
re.findall('<!--go-->(.*?)<!--over-->',text,re.S)
提取出的文章带有其他标签,稍微处理一下
chapter = re.sub('<br/>','\n',chapter)
chapter = re.sub(' ',' ',chapter)
文章就成功提取出来了
其他的完善
判断下载链接是否正确
使用正则去判断,如果找不到,则说明输入错误
def judge(url):
c = re.findall("http://www\.biquge\.info/[0-9\_]+/",url)
if(len(c) != 0):
return c[0]
else:
print("请检查是否输入正确的下载链接,当前只能下载biquge.info下的书籍")
return ""
判断路径并创建txt文件
先判断路径是否正确,如正确,创建以文章为名字的txt文件,不正确则重新输入
#创建txt文件并打开
def create_file(path,txtname):
#文件路径处理
if(path == ''):
full_path = txtname + ".txt"
else:
full_path = path + "\\" + txtname + ".txt"
try:
fp = open(full_path, 'w', encoding='utf-8')
return fp
except:
newpath = input("文件路径不正确,请重新输入文件路径")
fp = create_file(newpath, txtname)
return fp
基础伪装,章节读取失败的措施
首先是稍微进行伪装,更改请求头
myheaders={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"}
其次问题是,访问频率过高,可能会导致访问失败。
所以可以增加随机数降低爬取的速度。最简单的方法,使用sleep函数。
time.sleep(random.randint(int(beg), int(end)))
实验效果
在beg和end都是0的情况下(即0延迟)进行的下载
只有一章下载失败,下载失败的那一章经过5秒,重新下载
获得的txt效果图
完整代码
import requests
from bs4 import BeautifulSoup
import random
import time
import re
#@@@荒晓芜@@@
#可更改:希望延迟秒数范围beg<= ? <=end
beg = 0
end = 0
#请求头
myheaders = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"}
#创建txt文件并打开
def create_file(path,txtname):
#文件路径处理
if(path == ''):
full_path = txtname + ".txt"
else:
full_path = path + "\\" + txtname + ".txt"
try:
fp = open(full_path, 'w', encoding='utf-8')
return fp
except:
newpath = input("文件路径不正确,请重新输入文件路径")
fp = create_file(newpath,txtname)
return fp
#获取页面
def gethtml(url, code="utf-8"):
try:
r = requests.get(url,headers=myheaders)
r.raise_for_status()
r.encoding = code
time.sleep(random.randint(int(beg),int(end)))
return r.text
except:
print("获取文章失败,5秒后将重新获取")
time.sleep(5)
return ""
#获取文章目录并开始写入txt
def geturl_list(path,url):
text = gethtml(url)
soup = BeautifulSoup(text, "html.parser")
#获取书名
name = soup.find("h1").string
#获得该文件
fp = create_file(path,name)
for i in soup.find_all('dd'):
i_in = i.find("a")
each_url = url + i_in.get("href")
#章节名
chapter_name = i.string
#文章内容
chapter = get_chapter(each_url)
fp.write("\n\n"+chapter_name+"\n"+chapter)
print(chapter_name+"下载成功")
fp.close()
#获得每个页面的文本
def get_chapter(each_url):
text = gethtml(each_url)
#重新获取
while(text == ""):
text = gethtml(each_url)
#.就是任意字符,*就是前面字符有任意多个,参数有re.S,不会对\n进行中断
try:
correct = re.findall('<!--go-->(.*?)<!--over-->',text,re.S)
chapter = correct[0]
chapter = re.sub('<br/>','\n',chapter)
chapter = re.sub(' ',' ',chapter)
return chapter
except:
print("程序意外终止")
#检查延迟秒数是否更改正确
def check_environment():
if (beg < 0) or (beg > end):
print("请检查程序延迟秒数是否配置正确,请退出程序重新配置")
input("任意键退出")
exit(0)
else:
print("============欢迎使用============")
#判断连接是否正确输入
def judge(url):
c = re.findall("http://www\.biquge\.info/[0-9\_]+/", url)
if (len(c) != 0):
return c[0]
else:
print("请检查是否输入正确的下载链接,当前只能下载biquge.info下的书籍")
return ""
def main():
check_environment()
while(True):
html_url = input("请输入要爬取的笔趣阁书籍")
html_url = judge(html_url)
if (html_url != ""):
break
path = input("保存的路径(可不填)")
geturl_list(path, html_url)
input("下载结束")
main()
写在最后
感谢小伙伴天天提供的一些思路~以及帮忙发现了一个致命的bug
不多说,我天最牛逼
同时也学习了正则表达式的使用
参考资料:
Python re.findall中正则表达式(.*?)和参数re.S使用
不足:
1.没有多线程增加爬取速度
2.未使用多ip,减少访问失败的问题
3.没有解决其他笔趣阁网站的爬取不兼容的问题
初学者,后续应该还会继续改进和完善qwq
新留言:大改了个框架,可以判断和爬不同的笔趣阁或者其他网站,只需要自己简单在函数里增加相应代码即可,这个就不贴源码了。
有兴趣的也可以和我互相学习交流
仅供个人学习,禁止用作其他用途