flask-celery异步执行sitemap任务并生成文件
此次主要是将python生成的sitemap文件,转入到flask做出的api接口上,这样每次进行api请求就可以获取到网站的所有的url并生成sitemap文件。首先看看运行效果。
本地地址请求接口url:http://127.0.0.1:5100/sitemap?site=http://www.seoyiwu.com
运行命令:
1、宝塔服务器开启redis服务(安装一下redis就行了)
2、启动celery异步执行任务命令 : celery --app=run.celery worker -P eventlet -l INFO
3、启动flask命令 python run.py
接下来用postman进行测试看看。可以看到返回一个任务id,这个任务id代表任务执行的状态,是否执行完毕
如果没有执行完毕则返回 当前执行步骤
执行完毕后,就会返回执行终止状态以及返回了sitemap文件
然后我们在当前目录可以看到生成的sitemap文件,可以看到已经生成成功。
好了,接下来看看代码的实现流程:
一、flask创建任务,成功celery实例
创建celery队形,并配置好redis数据库
二、sitemap任务
这是celery异步执行的任务,放到一个方法里。
@celery.task(bind=True) def proSitemap(self,urls): allUrls = set() rootUrl = urls[0] while True: with ThreadPoolExecutor(max_workers=10) as executor: urls = executor.map(getsitemap_url,urls) urls = [url for url in urls if url][0] urls = set(urls) - allUrls if not urls:break for url in urls: if url.find(rootUrl) == -1:continue allUrls.add(url) self.update_state(state='PROGRESS',meta={'status':f'正在抓取的url: {url}'}) urls = list(urls) allUrls = sorted(list(allUrls),key=lambda url:len(url)) print(allUrls) return {'rootUrl':rootUrl,'allUrls':allUrls,'status':200,'result':'生成完毕'}
三、请求接口
配置好请求接口,生成sitemap任务运行api
@app.route('/sitemap', methods=['GET']) def sitemap(): site = request.args.get('site','') urls = [site] task = proSitemap.apply_async(args=[urls]) print(task.id) return jsonify({ 'Location':request.host_url + url_for('taskstatus',task_id=task.id).replace('/status','status') }) @app.route('/status/<task_id>') def taskstatus(task_id): task = proSitemap.AsyncResult(task_id) if task.state == 'PENDING': response = { 'state':task.state, 'status':'pending' } elif task.state != 'FAILURE': rootUrl = task.info.get('rootUrl',0) allUrls = task.info.get('allUrls',1) response = { 'state':task.state, 'status':task.info.get('status',100), 'rootUrl':rootUrl,#rootUrl, 'allUrls':allUrls,#allUrls, } if 'result' in task.info: makeSitemap(rootUrl,allUrls) response['result'] = task.info['result'] else: response = { 'state':task.state, 'status':str(task.info) } return jsonify(response)
四、生成sitemap文件
def makeSitemap(rootUrl,allUrls): fw = open('sitemap.xml', 'w', encoding="utf-8") fw.write('<?xml version="1.0" encoding="UTF-8"?>') fw.write( '\n<urlset xmlns="http://video.sitemaps.org/schemas/sitemap/0.9">' ) for url in allUrls: fw.write('\n\t<url>') fw.write('\n\t\t<loc>' + url + '</loc>') fw.write("\n\t\t<lastmod>" +time.strftime('%Y-%m-%d', time.localtime(time.time())) + "</lastmod>") fw.write('\n\t\t<changefreq>daily</changefreq>') if re.findall(rootUrl + "$", url) or re.findall( rootUrl + "/$", url): fw.write('\n\t\t<priority>1.0</priority>') elif re.findall(rootUrl + "[^/]*/$", url) or re.findall( rootUrl + "/[^/]*/$", url): fw.write('\n\t\t<priority>0.8</priority>') elif re.findall(rootUrl + "[^/]*/[^/]*$", url) or re.findall( rootUrl + "/[^/]*/[^/]*$", url): fw.write('\n\t\t<priority>0.6</priority>') else: fw.write('\n\t\t<priority>0.4</priority>') fw.write('\n\t</url>') fw.write('\n</urlset>')
整体的核心步骤就这些了,接下来我们就可以将代码上传到服务器中,然后就可以在服务器调用,方便随意使用,也可以在服务器里开启一个定时任务进行定时更新sitemap文件。如果需要生成sitemap的朋友,可以私信我,获取免费接口生成!