由于版权问题,暂不对网站明述。
正常使用xpath进行爬取,没有反爬措施
爬取使用了进度条,说明一下进度条的使用和爬取遇到的问题:
-
\r 表示将光标的位置回退到本行的开头位置
\b表示将光标的位置回退一位 -
print("\r", end="") end=""表示下次打印不换行,又因为\r表示将光标的位置回退到本行的开头位置,所以也就是将上一次打印的覆盖掉
-
" / " 表示 浮点数除法,返回浮点结果; " // "表示整数除法。
-
xpath获取一个标签文本时出现乱码:对文本使用 .encode(‘ISO-8859-1’).decode(“gbk”) 即可
-
缓冲区的刷新方式:
flush()刷新缓存区
缓冲区满时,自动刷新
文件关闭或者是程序结束自动刷新。import time import sysfor i in range(5):print(i,end='')# sys.stdout.flush()time.sleep(0.001) #注释打开和关闭效果不同
当我们打印一些字符时,并不是调用print函数后就立即打印的。一般会先将字符送到缓冲区,然后再打印。这就存在一个问题,如果你想等时间间隔的打印一些字符,但由于缓冲区没满,不会打印。就需要采取一些手段。如每次打印后强行刷新缓冲区。
爬取结果:
代码
import requests
from lxml import etree
import re,os,time,sysm=0
k=0#解析小说正文页面
def parse_page(url):r = requests.get(url).texthtml = etree.HTML(r)title = html.xpath('//div[@class="content"]/h1/text()')[0]text = html.xpath('//div[@id="content"]/text()')if len(text)==0:passnew_text = []for te in text[:-4]:new_text.append(te)err = ['?', '?','\"', '“','|',':','(','*','(']#判断小说章节名是否合法if len([True for er in err if er in title])!=0:y = re.findall('[((\??"“”|:/\*].*',title)[0]new_title = title.replace(y,'')save(new_title,new_text)else: save(title,new_text)#使用进度条
def down_progress(len_url):global mglobal kif k!=0 and m<=99 and k%(int)(len_url/100)==0:m=m+1print("\r", end="")print("Download progress: {}%: ".format(m), "▋" * (m // 2), end="")sys.stdout.flush()k+=1#获取小说的所有正文Url
def get_url(url):global novel_nameglobal len_urlr = requests.get(url).texthtml = etree.HTML(r)novel_name = html.xpath('//div[@class="info"]/h2/text()')[0].encode('ISO-8859-1').decode("gbk")if not os.path.exists(novel_name):os.mkdir(novel_name)dd = html.xpath('//div[@class="listmain"]/dl//dd')len_url = len(dd)-12print("下载的小说名为:"+novel_name)print("共需要下载{}章".format(len_url))print("保存地址为:"+os.getcwd()+"\\"+ novel_name)print("下载大概需"+str('%.2f'%(len_url*1.1/60))+"分钟")print("*"*30+'下载开始'+"*"*30)for d in dd[12:]:#使用进度条down_progress(len_url)url = "https://www.bqkan.com/" + d.xpath('./a/@href')[0]parse_page(url)time.sleep(0.05)
#将小说正文写入文本文件中
def save(title,text):f = open(novel_name+"/"+title+'.txt','a',encoding='utf-8')for te in text:f.write(te)f.write('\n')def main():url = input("请输入小说目录下载地址:")get_url(url)if __name__ == '__main__':start = time.time()main()end = time.time()print()print("*"*30+'下载已完成'+"*"*30)print("下载耗费时间:{}分钟".format(str('%.2f'%((end-start)/60))))