From 65a4a5b7a83a6addc6ed2e4597c2ea741168815a Mon Sep 17 00:00:00 2001 From: hillerliao Date: Sun, 15 Dec 2019 21:52:58 +0800 Subject: [PATCH] add cninfo announcement --- .coveragerc | 2 +- .flaskenv | 4 +- .gitignore | 32 +++--- rsshub/__init__.py | 140 ++++++++++++------------ rsshub/blueprints/main.py | 111 ++++++++++--------- rsshub/config.py | 64 +++++------ rsshub/extensions.py | 16 +-- rsshub/spiders/chuansongme/articles.py | 44 ++++---- rsshub/spiders/cninfo/announcement.py | 49 +++++++++ rsshub/spiders/ctolib/topics.py | 44 ++++---- rsshub/spiders/infoq/recommend.py | 46 ++++---- rsshub/static/css/style.css | 96 ++++++++--------- rsshub/templates/errors/400.html | 16 +-- rsshub/templates/errors/404.html | 16 +-- rsshub/templates/errors/500.html | 16 +-- rsshub/templates/layout.html | 138 ++++++++++++------------ rsshub/templates/main/atom.xml | 42 ++++---- rsshub/templates/main/feeds.html | 142 +++++++++++++------------ rsshub/templates/main/index.html | 24 ++--- rsshub/utils.py | 50 ++++----- tests/base.py | 30 +++--- tests/test_cli.py | 14 +-- tests/test_errors.py | 60 +++++------ tests/test_main.py | 16 +-- 24 files changed, 639 insertions(+), 573 deletions(-) create mode 100644 rsshub/spiders/cninfo/announcement.py diff --git a/.coveragerc b/.coveragerc index f32ec8f..413f6b1 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,2 @@ -[run] +[run] source = rsshub \ No newline at end of file diff --git a/.flaskenv b/.flaskenv index c40645d..1c7397e 100644 --- a/.flaskenv +++ b/.flaskenv @@ -1,3 +1,3 @@ -FLASK_ENV=development -FLASK_APP=rsshub +FLASK_ENV=development +FLASK_APP=rsshub FLASK_DEBUG=1 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 60bba3f..38946f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,17 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -.pytest_cache - -# Distribution / packaging -build/ -dist/ -*.egg-info/ -.idea -venv - -# Others -.vscode -.coverage -htmlcov/ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +.pytest_cache + +# Distribution / packaging +build/ +dist/ +*.egg-info/ +.idea +venv + +# Others +.vscode +.coverage +htmlcov/ data-dev.db \ No newline at end of file diff --git a/rsshub/__init__.py b/rsshub/__init__.py index 56ebe03..7d83e6a 100644 --- a/rsshub/__init__.py +++ b/rsshub/__init__.py @@ -1,70 +1,70 @@ -import os -from datetime import datetime -import click -from flask import Flask, render_template -from flask.cli import with_appcontext -from rsshub.config import config -from rsshub.extensions import * -from rsshub.blueprints.main import bp as main_bp -from rsshub.utils import XMLResponse - - -def create_app(config_name=None): - if config_name is None: - config_name = os.getenv('FLASK_CONFIG', 'development') - - app = Flask(__name__) - app.config.from_object(config[config_name]) - app.response_class = XMLResponse - - register_blueprints(app) - register_extensions(app) - register_errors(app) - register_context_processors(app) - register_cli(app) - - return app - - -def register_extensions(app): - bootstrap.init_app(app) - debugtoolbar.init_app(app) - moment.init_app(app) - - -def register_blueprints(app): - app.register_blueprint(main_bp) - - -def register_errors(app): - @app.errorhandler(400) - def bad_request(e): - return render_template('errors/400.html'), 400 - - @app.errorhandler(404) - def page_not_found(e): - return render_template('errors/404.html'), 404 - - @app.errorhandler(500) - def internal_server_error(e): - return render_template('errors/500.html'), 500 - - -def register_context_processors(app): - @app.context_processor - def inject_date_now(): - now = datetime.utcnow() - return {'now': now} - - -def register_cli(app): - @app.cli.command() - @with_appcontext - def ptshell(): - """Use ptpython as shell.""" - try: - from ptpython.repl import embed - if not app.config['TESTING']: - embed(app.make_shell_context()) - except ImportError: - click.echo('ptpython not installed! Use the default shell instead.') +import os +from datetime import datetime +import click +from flask import Flask, render_template +from flask.cli import with_appcontext +from rsshub.config import config +from rsshub.extensions import * +from rsshub.blueprints.main import bp as main_bp +from rsshub.utils import XMLResponse + + +def create_app(config_name=None): + if config_name is None: + config_name = os.getenv('FLASK_CONFIG', 'development') + + app = Flask(__name__) + app.config.from_object(config[config_name]) + app.response_class = XMLResponse + + register_blueprints(app) + register_extensions(app) + register_errors(app) + register_context_processors(app) + register_cli(app) + + return app + + +def register_extensions(app): + bootstrap.init_app(app) + debugtoolbar.init_app(app) + moment.init_app(app) + + +def register_blueprints(app): + app.register_blueprint(main_bp) + + +def register_errors(app): + @app.errorhandler(400) + def bad_request(e): + return render_template('errors/400.html'), 400 + + @app.errorhandler(404) + def page_not_found(e): + return render_template('errors/404.html'), 404 + + @app.errorhandler(500) + def internal_server_error(e): + return render_template('errors/500.html'), 500 + + +def register_context_processors(app): + @app.context_processor + def inject_date_now(): + now = datetime.utcnow() + return {'now': now} + + +def register_cli(app): + @app.cli.command() + @with_appcontext + def ptshell(): + """Use ptpython as shell.""" + try: + from ptpython.repl import embed + if not app.config['TESTING']: + embed(app.make_shell_context()) + except ImportError: + click.echo('ptpython not installed! Use the default shell instead.') diff --git a/rsshub/blueprints/main.py b/rsshub/blueprints/main.py index 286c040..ff42241 100644 --- a/rsshub/blueprints/main.py +++ b/rsshub/blueprints/main.py @@ -1,52 +1,59 @@ -from flask import Blueprint, render_template, request - -bp = Blueprint('main', __name__) - - -@bp.route('/') -def index(): - return render_template('main/index.html') - - -@bp.route('/feeds') -def feeds(): - return render_template('main/feeds.html') - - -@bp.app_template_global() -def filter_content(ctx): - include_title = request.args.get('include_title') - include_description = request.args.get('include_description') - exclude_title = request.args.get('exclude_title') - exclude_description = request.args.get('exclude_description') - limit = request.args.get('limit', type=int) - items = ctx['items'].copy() - items = [item for item in items if include_title in item['title']] if include_title else items - items = [item for item in items if include_description in item['description']] if include_description else items - items = [item for item in items if exclude_title not in item['title']] if exclude_title else items - items = [item for item in items if exclude_description not in item['description']] if exclude_description else items - items = items[:limit] if limit else items - ctx = ctx.copy() - ctx['items'] = items - return ctx - - -#---------- feed路由从这里开始 -----------# -@bp.route('/chuansongme/articles/') -@bp.route('/chuansongme/articles') -def chuansongme_articles(category=''): - from rsshub.spiders.chuansongme.articles import ctx - return render_template('main/atom.xml', **filter_content(ctx(category))) - - -@bp.route('/ctolib/topics/') -@bp.route('/ctolib/topics') -def ctolib_topics(category=''): - from rsshub.spiders.ctolib.topics import ctx - return render_template('main/atom.xml', **filter_content(ctx(category))) - - -@bp.route('/infoq/recommend') -def infoq_recommend(): - from rsshub.spiders.infoq.recommend import ctx - return render_template('main/atom.xml', **filter_content(ctx())) +from flask import Blueprint, render_template, request + +bp = Blueprint('main', __name__) + + +@bp.route('/') +def index(): + return render_template('main/index.html') + + +@bp.route('/feeds') +def feeds(): + return render_template('main/feeds.html') + + +@bp.app_template_global() +def filter_content(ctx): + include_title = request.args.get('include_title') + include_description = request.args.get('include_description') + exclude_title = request.args.get('exclude_title') + exclude_description = request.args.get('exclude_description') + limit = request.args.get('limit', type=int) + items = ctx['items'].copy() + items = [item for item in items if include_title in item['title']] if include_title else items + items = [item for item in items if include_description in item['description']] if include_description else items + items = [item for item in items if exclude_title not in item['title']] if exclude_title else items + items = [item for item in items if exclude_description not in item['description']] if exclude_description else items + items = items[:limit] if limit else items + ctx = ctx.copy() + ctx['items'] = items + return ctx + + +#---------- feed路由从这里开始 -----------# +@bp.route('/cninfo/announcement//') +@bp.route('/cninfo/announcement') +def cninfo_announcement(stock_id='', category=''): + from rsshub.spiders.cninfo.announcement import ctx + return render_template('main/atom.xml', **filter_content(ctx(stock_id,category))) + + +@bp.route('/chuansongme/articles/') +@bp.route('/chuansongme/articles') +def chuansongme_articles(category=''): + from rsshub.spiders.chuansongme.articles import ctx + return render_template('main/atom.xml', **filter_content(ctx(category))) + + +@bp.route('/ctolib/topics/') +@bp.route('/ctolib/topics') +def ctolib_topics(category=''): + from rsshub.spiders.ctolib.topics import ctx + return render_template('main/atom.xml', **filter_content(ctx(category))) + + +@bp.route('/infoq/recommend') +def infoq_recommend(): + from rsshub.spiders.infoq.recommend import ctx + return render_template('main/atom.xml', **filter_content(ctx())) diff --git a/rsshub/config.py b/rsshub/config.py index da9b0bb..2474e62 100644 --- a/rsshub/config.py +++ b/rsshub/config.py @@ -1,32 +1,32 @@ -import os -import sys - - -basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - - -class BaseConfig: - SITE_NAME = 'RSSHub' - GITHUB_USERNAME = 'alphardex' - EMAIL = '2582347430@qq.com' - SECRET_KEY = os.environ.get('SECRET_KEY') or 'f43hrt53et53' - DEBUG_TB_INTERCEPT_REDIRECTS = False - - -class DevelopmentConfig(BaseConfig): - pass - - -class TestingConfig(BaseConfig): - TESTING = True - - -class ProductionConfig(BaseConfig): - pass - - -config = { - 'development': DevelopmentConfig, - 'testing': TestingConfig, - 'production': ProductionConfig -} +import os +import sys + + +basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + + +class BaseConfig: + SITE_NAME = 'RSSHub' + GITHUB_USERNAME = 'alphardex' + EMAIL = '2582347430@qq.com' + SECRET_KEY = os.environ.get('SECRET_KEY') or 'f43hrt53et53' + DEBUG_TB_INTERCEPT_REDIRECTS = False + + +class DevelopmentConfig(BaseConfig): + pass + + +class TestingConfig(BaseConfig): + TESTING = True + + +class ProductionConfig(BaseConfig): + pass + + +config = { + 'development': DevelopmentConfig, + 'testing': TestingConfig, + 'production': ProductionConfig +} diff --git a/rsshub/extensions.py b/rsshub/extensions.py index 3d5cc33..2ce9714 100644 --- a/rsshub/extensions.py +++ b/rsshub/extensions.py @@ -1,8 +1,8 @@ -from flask_bootstrap import Bootstrap -from flask_debugtoolbar import DebugToolbarExtension -from flask_moment import Moment - - -bootstrap = Bootstrap() -debugtoolbar = DebugToolbarExtension() -moment = Moment() +from flask_bootstrap import Bootstrap +from flask_debugtoolbar import DebugToolbarExtension +from flask_moment import Moment + + +bootstrap = Bootstrap() +debugtoolbar = DebugToolbarExtension() +moment = Moment() diff --git a/rsshub/spiders/chuansongme/articles.py b/rsshub/spiders/chuansongme/articles.py index 3040ff8..bab2426 100644 --- a/rsshub/spiders/chuansongme/articles.py +++ b/rsshub/spiders/chuansongme/articles.py @@ -1,23 +1,23 @@ -from rsshub.utils import fetch - -domain = 'https://chuansongme.com' - - -def parse(post): - item = {} - item['title'] = post.css('a.question_link::text').extract()[-1].strip() - link = f"{domain}{post.css('a.question_link::attr(href)').extract_first()}" - item['link'] = link - return item - - -def ctx(category=''): - tree = fetch(f"{domain}/{category}") - posts = tree.css('.feed_body .pagedlist_item') - return { - 'title': '传送门', - 'link': domain, - 'description': '传送门:微信公众号订阅', - 'author': 'alphardex', - 'items': list(map(parse, posts)) +from rsshub.utils import fetch + +domain = 'https://chuansongme.com' + + +def parse(post): + item = {} + item['title'] = post.css('a.question_link::text').extract()[-1].strip() + link = f"{domain}{post.css('a.question_link::attr(href)').extract_first()}" + item['link'] = link + return item + + +def ctx(category=''): + tree = fetch(f"{domain}/{category}") + posts = tree.css('.feed_body .pagedlist_item') + return { + 'title': '传送门', + 'link': domain, + 'description': '传送门:微信公众号订阅', + 'author': 'alphardex', + 'items': list(map(parse, posts)) } \ No newline at end of file diff --git a/rsshub/spiders/cninfo/announcement.py b/rsshub/spiders/cninfo/announcement.py new file mode 100644 index 0000000..f7e82b9 --- /dev/null +++ b/rsshub/spiders/cninfo/announcement.py @@ -0,0 +1,49 @@ +import requests +from rsshub.utils import DEFAULT_HEADERS + +domain = 'http://www.cninfo.com.cn' + + +def parse(post): + item = {} + item['title'] = post['secName'] + '(' + post['secCode'] + ')' + ': ' + post['announcementTitle'] + item['description'] = item['title'] + item['link'] = 'http://static.cninfo.com.cn/' + post['adjunctUrl'] + item['pubDate'] = post['announcementTime'] + return item + + +def ctx(stock_id='', category=''): + stock_id = '' if stock_id == 'all' else stock_id + stock_name = '' + stock_list = requests.get('http://www.cninfo.com.cn/new/data/szse_stock.json', headers=DEFAULT_HEADERS).json()['stockList'] + for stock in stock_list: + if stock['code'] == stock_id : + stock_id = stock['orgId'] + stock_name = stock['zwjc'] + break + + import datetime + nowtime = datetime.datetime.now() + deltaday=datetime.timedelta(days=1) + start_date = datetime.datetime.strftime(nowtime- 5 * deltaday, '%Y-%m-%d') + end_date = datetime.datetime.strftime(nowtime + 2 * deltaday, '%Y-%m-%d') + seDate = start_date + '~' + end_date + + searchkey = '' + if '_' in category: + searchkey = category.split('_')[-1] + category = category.split('_')[0] + + + DEFAULT_HEADERS.update({'Referer': domain}) + posts = requests.post(f'{domain}/new/hisAnnouncement/query', \ + data={'pageSize': '30','tabName':'fulltext', 'plate': '', 'category':f'category_{category}_szsh', \ + 'secid': stock_id,'seDate':'', 'seDate': seDate, 'searchkey': searchkey }, headers=DEFAULT_HEADERS).json()['announcements'] + return { + 'title': f'{stock_name}-{category}-公告-巨潮资讯', + 'link': f'{domain}/new/commonUrl/pageOfSearch?url=disclosure/list/search&checkedCategory=category_{category}_szsh&searchkey={searchkey}', + 'description': f'{stock_name}关于{category}的公告-巨潮资讯', + 'author': 'hillerliao', + 'items': list(map(parse, posts)) + } \ No newline at end of file diff --git a/rsshub/spiders/ctolib/topics.py b/rsshub/spiders/ctolib/topics.py index aadc255..45d5b2f 100644 --- a/rsshub/spiders/ctolib/topics.py +++ b/rsshub/spiders/ctolib/topics.py @@ -1,23 +1,23 @@ -from rsshub.utils import fetch - -domain = 'https://www.ctolib.com' - - -def parse(post): - item = {} - item['title'] = post.css('a.title::text').extract_first() - item['description'] = post.css('p.abstract::text').extract_first() - item['link'] = f"{domain}{post.css('a.title::attr(href)').extract_first()}" - return item - - -def ctx(category=''): - tree = fetch(f'{domain}/python/topics/{category}') - posts = tree.css('ul.note-list li') - return { - 'title': 'CTOLib码库', - 'link': domain, - 'description': 'Python开发社区', - 'author': 'alphardex', - 'items': list(map(parse, posts)) +from rsshub.utils import fetch + +domain = 'https://www.ctolib.com' + + +def parse(post): + item = {} + item['title'] = post.css('a.title::text').extract_first() + item['description'] = post.css('p.abstract::text').extract_first() + item['link'] = f"{domain}{post.css('a.title::attr(href)').extract_first()}" + return item + + +def ctx(category=''): + tree = fetch(f'{domain}/python/topics/{category}') + posts = tree.css('ul.note-list li') + return { + 'title': 'CTOLib码库', + 'link': domain, + 'description': 'Python开发社区', + 'author': 'alphardex', + 'items': list(map(parse, posts)) } \ No newline at end of file diff --git a/rsshub/spiders/infoq/recommend.py b/rsshub/spiders/infoq/recommend.py index b328c21..6a35a0d 100644 --- a/rsshub/spiders/infoq/recommend.py +++ b/rsshub/spiders/infoq/recommend.py @@ -1,24 +1,24 @@ -import requests -from rsshub.utils import DEFAULT_HEADERS - -domain = 'https://www.infoq.cn' - - -def parse(post): - item = {} - item['title'] = post['article_title'] - item['description'] = f"{post['article_summary']}
" - item['link'] = f"{domain}/article/{post['uuid']}" - return item - - -def ctx(): - DEFAULT_HEADERS.update({'Referer': 'https://www.infoq.cn'}) # 必须设置Referer,不然会451错误 - posts = requests.post(f'{domain}/public/v1/my/recommond', data={'size': 20}, headers=DEFAULT_HEADERS).json()['data'] - return { - 'title': 'infoq', - 'link': domain, - 'description': 'InfoQ - 促进软件开发领域知识与创新的传播', - 'author': 'alphardex', - 'items': list(map(parse, posts)) +import requests +from rsshub.utils import DEFAULT_HEADERS + +domain = 'https://www.infoq.cn' + + +def parse(post): + item = {} + item['title'] = post['article_title'] + item['description'] = f"{post['article_summary']}
" + item['link'] = f"{domain}/article/{post['uuid']}" + return item + + +def ctx(): + DEFAULT_HEADERS.update({'Referer': 'https://www.infoq.cn'}) # 必须设置Referer,不然会451错误 + posts = requests.post(f'{domain}/public/v1/my/recommond', data={'size': 20}, headers=DEFAULT_HEADERS).json()['data'] + return { + 'title': 'infoq', + 'link': domain, + 'description': 'InfoQ - 促进软件开发领域知识与创新的传播', + 'author': 'alphardex', + 'items': list(map(parse, posts)) } \ No newline at end of file diff --git a/rsshub/static/css/style.css b/rsshub/static/css/style.css index 9be19e6..d06621b 100644 --- a/rsshub/static/css/style.css +++ b/rsshub/static/css/style.css @@ -1,48 +1,48 @@ -/* global */ - -nav { - margin-bottom: 30px; -} - -.jumbotron { - margin-top: 20px; - padding-top: 38px; - padding-bottom: 38px; -} - -.tip { - /* from github.com */ - position: relative; - padding: 40px; - text-align: center; - background-color: #fafbfc; - border: 1px solid #e1e4e8; - border-radius: 3px; - box-shadow: inset 0 0 10px rgba(27, 31, 35, 0.05); -} - -.hide { - display: none; -} - -.inline { - display: inline; -} - -.page-header { - padding-top: 20px; - padding-bottom: 20px; -} - -.page-footer { - padding-top: 40px; -} - - -/* footer */ - -footer { - margin: 30px 0; - padding: 20px 0; - border-top: 1px solid #e5e5e5; -} +/* global */ + +nav { + margin-bottom: 30px; +} + +.jumbotron { + margin-top: 20px; + padding-top: 38px; + padding-bottom: 38px; +} + +.tip { + /* from github.com */ + position: relative; + padding: 40px; + text-align: center; + background-color: #fafbfc; + border: 1px solid #e1e4e8; + border-radius: 3px; + box-shadow: inset 0 0 10px rgba(27, 31, 35, 0.05); +} + +.hide { + display: none; +} + +.inline { + display: inline; +} + +.page-header { + padding-top: 20px; + padding-bottom: 20px; +} + +.page-footer { + padding-top: 40px; +} + + +/* footer */ + +footer { + margin: 30px 0; + padding: 20px 0; + border-top: 1px solid #e5e5e5; +} diff --git a/rsshub/templates/errors/400.html b/rsshub/templates/errors/400.html index b01e20c..68d8d75 100644 --- a/rsshub/templates/errors/400.html +++ b/rsshub/templates/errors/400.html @@ -1,9 +1,9 @@ -{% extends 'layout.html' %} - -{% block title %}400 错误{% endblock %} - -{% block content %} -
-

400 Bad Request

-
+{% extends 'layout.html' %} + +{% block title %}400 错误{% endblock %} + +{% block content %} +
+

400 Bad Request

+
{% endblock %} \ No newline at end of file diff --git a/rsshub/templates/errors/404.html b/rsshub/templates/errors/404.html index 9480d26..43c494a 100644 --- a/rsshub/templates/errors/404.html +++ b/rsshub/templates/errors/404.html @@ -1,9 +1,9 @@ -{% extends 'layout.html' %} - -{% block title %}404 错误{% endblock %} - -{% block content %} -
-

404 Not Found

-
+{% extends 'layout.html' %} + +{% block title %}404 错误{% endblock %} + +{% block content %} +
+

404 Not Found

+
{% endblock %} \ No newline at end of file diff --git a/rsshub/templates/errors/500.html b/rsshub/templates/errors/500.html index 8e4546a..98e424e 100644 --- a/rsshub/templates/errors/500.html +++ b/rsshub/templates/errors/500.html @@ -1,9 +1,9 @@ -{% extends 'layout.html' %} - -{% block title %}500 错误{% endblock %} - -{% block content %} -
-

服务器出错

-
+{% extends 'layout.html' %} + +{% block title %}500 错误{% endblock %} + +{% block content %} +
+

服务器出错

+
{% endblock %} \ No newline at end of file diff --git a/rsshub/templates/layout.html b/rsshub/templates/layout.html index 86c8ff5..d08fdb9 100644 --- a/rsshub/templates/layout.html +++ b/rsshub/templates/layout.html @@ -1,70 +1,70 @@ -{% from 'bootstrap/nav.html' import render_nav_item %} - - - - - {% block head %} - - - {% block title %}{% endblock title %} - - - {% block styles %} - {{ bootstrap.load_css() }} - - - {% endblock styles %} - {% endblock head %} - - - - {% block nav %} - - {% endblock nav %} -
- {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} - {% for category, message in messages %} - - {% endfor %} - {% endif %} - {% endwith %} - {% block content %}{% endblock %} - {% block footer %} - - {% endblock footer %} -
- {% block scripts %} - {{ bootstrap.load_js() }} - {{ moment.include_moment() }} - {{ moment.locale('zh-cn') }} - {% endblock %} - - +{% from 'bootstrap/nav.html' import render_nav_item %} + + + + + {% block head %} + + + {% block title %}{% endblock title %} + + + {% block styles %} + {{ bootstrap.load_css() }} + + + {% endblock styles %} + {% endblock head %} + + + + {% block nav %} + + {% endblock nav %} +
+ {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + + {% endfor %} + {% endif %} + {% endwith %} + {% block content %}{% endblock %} + {% block footer %} + + {% endblock footer %} +
+ {% block scripts %} + {{ bootstrap.load_js() }} + {{ moment.include_moment() }} + {{ moment.locale('zh-cn') }} + {% endblock %} + + \ No newline at end of file diff --git a/rsshub/templates/main/atom.xml b/rsshub/templates/main/atom.xml index 042ab43..27481ae 100644 --- a/rsshub/templates/main/atom.xml +++ b/rsshub/templates/main/atom.xml @@ -1,22 +1,22 @@ - - - {{config['SITE_NAME']}} - {{config['EMAIL']}} - zh-cn - {{link}} - <![CDATA[{{title|safe}}]]> - - - - - {% for item in items %} - - {{item.link}} - <![CDATA[{{item.title|safe}}]]> - {{item.pubDate|default(now)}} - {{item.pubDate|default(now)}} - - - - {% endfor %} + + + {{config['SITE_NAME']}} + {{config['EMAIL']}} + zh-cn + {{link}} + <![CDATA[{{title|safe}}]]> + + + + + {% for item in items %} + + {{item.link}} + <![CDATA[{{item.title|safe}}]]> + {{item.pubDate|default(now)}} + {{item.pubDate|default(now)}} + + + + {% endfor %} \ No newline at end of file diff --git a/rsshub/templates/main/feeds.html b/rsshub/templates/main/feeds.html index 24381a0..39336e5 100644 --- a/rsshub/templates/main/feeds.html +++ b/rsshub/templates/main/feeds.html @@ -1,67 +1,77 @@ -{% extends "layout.html" %} - -{% block title %}All Feeds{% endblock title %} - -{% block content %} -
-
-

传送门

-
文章 by alphardex
-

举例:https://rsshub-python.herokuapp.com/chuansongme/articles

-

路由:/chuansongme/articles/:category

-

参数:category [默认为“最新”]

- - - - {% for th in ['精选','区块链','汽车','创意科技','媒体达人','电影音乐','娱乐休闲','生活旅行','学习工具','历史读书','金融理财','美食菜谱'] %} - - {% endfor %} - - - - - {% for td in ['select', 'blockchain', 'auto', 'ideatech', 'newsmedia', 'moviemusic', 'fun', 'lifejourney', 'utility', 'hisbook', 'finance', 'food']%} - - {% endfor %} - - -
{{th}}
{{td}}
-
-
-
-
-
-

CTOLib

-
话题 by alphardex
-

举例:https://rsshub-python.herokuapp.com/ctolib/topics

-

路由:/ctolib/topics/:category

-

参数:category [默认为“默认排序”]

- - - - {% for th in ['最新发布', '优质主题'] %} - - {% endfor %} - - - - - {% for td in ['last', 'popular']%} - - {% endfor %} - - -
{{th}}
{{td}}
-
-
-
-
-
-

InfoQ

-
推荐内容 by alphardex
-

举例:https://rsshub-python.herokuapp.com/infoq/recommend

-

路由:/infoq/recommend

-
-
-
+{% extends "layout.html" %} + +{% block title %}All Feeds{% endblock title %} + +{% block content %} +
+
+

传送门

+
文章 by alphardex
+

举例:https://rsshub-python.herokuapp.com/chuansongme/articles

+

路由:/chuansongme/articles/:category

+

参数:category [默认为“最新”]

+ + + + {% for th in ['精选','区块链','汽车','创意科技','媒体达人','电影音乐','娱乐休闲','生活旅行','学习工具','历史读书','金融理财','美食菜谱'] %} + + {% endfor %} + + + + + {% for td in ['select', 'blockchain', 'auto', 'ideatech', 'newsmedia', 'moviemusic', 'fun', 'lifejourney', 'utility', 'hisbook', 'finance', 'food']%} + + {% endfor %} + + +
{{th}}
{{td}}
+
+
+
+
+
+

CTOLib

+
话题 by alphardex
+

举例:https://rsshub-python.herokuapp.com/ctolib/topics

+

路由:/ctolib/topics/:category

+

参数:category [默认为“默认排序”]

+ + + + {% for th in ['最新发布', '优质主题'] %} + + {% endfor %} + + + + + {% for td in ['last', 'popular']%} + + {% endfor %} + + +
{{th}}
{{td}}
+
+
+
+
+
+

InfoQ

+
推荐内容 by alphardex
+

举例:https://rsshub-python.herokuapp.com/infoq/recommend

+

路由:/infoq/recommend

+
+
+
+
+
+

巨潮资讯

+
公司公告 by hillerliao
+

举例:https://rsshub-python.herokuapp.com/cninfo/announcement/all/gqjl

+

举例:https://rsshub-python.herokuapp.com/cninfo/announcement/all/gqbd_预披露,股权变动类公告中标题含有「预披露」的公告

+

路由:/cninfo/announcement/:stock_id/:category

+
+
+
{% endblock content %} \ No newline at end of file diff --git a/rsshub/templates/main/index.html b/rsshub/templates/main/index.html index ba61cdf..fb8d083 100644 --- a/rsshub/templates/main/index.html +++ b/rsshub/templates/main/index.html @@ -1,13 +1,13 @@ -{% extends 'layout.html' %} - -{% block title %}Welcome to RSShub!{% endblock title %} - -{% block content %} -
-

Welcome to RSSHub!

-

If you see this page, the RSSHub is successfully installed and working.

-

- View Source -

-
+{% extends 'layout.html' %} + +{% block title %}Welcome to RSShub!{% endblock title %} + +{% block content %} +
+

Welcome to RSSHub!

+

If you see this page, the RSSHub is successfully installed and working.

+

+ View Source +

+
{% endblock %} \ No newline at end of file diff --git a/rsshub/utils.py b/rsshub/utils.py index b1cd5e8..5cdbbe7 100644 --- a/rsshub/utils.py +++ b/rsshub/utils.py @@ -1,25 +1,25 @@ -from flask import Response -import requests -from parsel import Selector - -DEFAULT_HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'} - - -class XMLResponse(Response): - def __init__(self, response, **kwargs): - if 'mimetype' not in kwargs and 'contenttype' not in kwargs: - if response.startswith('