Package: onwebchange
onwebchangeDefault Console Web UI.RSS support.Release on pypi.Addtagfilter, to distinguish all the RSS sites. Add multiple tags support.Add .pyz usage for fast deploying.Support one-key sub RSSInstall>pip3installonwebchange-U

>python3-monwebchange-fwc.config-i300--host=127.0.0.1-p8080--username=admin--password=adminor shiv as one file "onwebchange.pyz", for fast deploying>pip3installshiv-U
>shiv-oonwebchange.pyz-eonwebchange.__main__:main--compressedonwebchange
>python3.7onwebchange.pyz--username=admin--password=adminRequirementstorequests
click
bottle
objectpath
beautifulsoup4Quick startinstallpython3 -m onwebchangeadd shell command  to systemd / supervisor.Run with username & password.python3 -m onwebchange -f wc.config -i 300 --host=127.0.0.1 -p 8080 --username=admin --password=adminAdd TasksPress [AddTask] buttonFill the blank:name: "pypi trending projects no1"request_args: "https://pypi.org/"parser_name: "css"operation: "#content > div:nth-child(4) > div > div:nth-child(1) > ul > li:nth-child(1) > a > h3 > span.package-snippet__name"value: "$text"check_interval: 300max_change: 10Press [Update Task] buttonSubscribe RSS from chrome RSS reader extensionDefault Web UIExamplerun as main package with commandpython3 -m onwebchange -f wc.config -i 300 -aorfromonwebchange.coreimportWebHandlerfromonwebchange.webuiimportappif__name__=="__main__":wh=WebHandler(app,file_path=None,loop_interval=300,auto_open_browser=True,change_callback=lambdatask:print(task.name),app_kwargs={'port':9988})# python3 -m onwebchange -f wc.config -i 300 -awh.run()Parser examplesregexparser_name: reoperation: class="(.*?)"value: $1css selector for attributeparser_name: cssoperation: #J_all_item_910789value: @classvalue also can be:$stringlist of outer HTML$textlist of node.text$get_textlist of node.get_text()json (ObjectPath).https://httpbin.org/get​	with json-handle chrome extention.parser_name: jsonoperation: $.headers["Accept-Encoding"]value: $textpythonparser_name: pythonoperation:defparse(resp):returnresp.text[:10]value as nullNew Task template"name":"task name0","request_args":"https://pypi.org",# could be url, curl string, request args dict."parser_name":"css",# could be re/css/json/python"operation":".lede-paragraph","value":"$text","check_interval":300,"max_change":2,"sorting_list":true,"origin_url":"https://pypi.org","encoding":null{"name":"task name1","request_args":"https://pypi.org","parser_name":"re","operation":"class=\"(lede-paragraph)\"","value":"$1","check_interval":300,"max_change":2,"sorting_list":true,"origin_url":"","encoding":null}{"name":"task name2","request_args":"http://httpbin.org/get","parser_name":"json","operation":"$.url","value":"","check_interval":300,"sorting_list":true,"origin_url":"","encoding":null}More docsWatchdogtask.:paramname:Taskname.:typename:str:paramrequest_args:argforsendingarequest,couldbeurl/curl_string/dict.:typerequest_args:dict/str:paramparser_name:re,css,json,python,defaultstoNone,usetheresp.text.:typeparser_name:str,optional:paramoperation:parseoperationfortheparser_name,defaultstoNone:typeoperation:str,optional:paramvalue:valueoperationfortheparser,defaultstoNone:typevalue:str,optional:paramsorting_list:whethersortingthelistofresultfrom`cssorotherparsers`,defaultstoTrue:typesorting_list:bool,optional:paramcheck_interval:check_interval,defaultsto60seconds:typecheck_interval:int,optional:parammax_change:saveresultincheck_result_list,savethelatest2change,defaultsto2:typemax_change:list,optional:paramcheck_result_list:latest`max_change`checkingresult,usuallyusemd5toshortenit,defaultstoNone:typecheck_result_list:list,optional:paramorigin_url:theurltoseethechangement,defaultstorequest_args['url']:typeorigin_url:str,optionalrequest_argsexamples:url:http://pypi.orgargs:{'url':'http://pypi.org','method':'get'}curl:curl'https://pypi.org/'-H'authority: pypi.org'-H'cache-control: max-age=0'-H'upgrade-insecure-requests: 1'-H'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'-H'sec-fetch-mode: navigate'-H'sec-fetch-user: ?1'-H'dnt: 1'-H'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3'-H'sec-fetch-site: none'-H'accept-encoding: gzip, deflate, br'-H'accept-language: zh-CN,zh;q=0.9'-H'cookie: user_id__insecure=; session_id='--compressedparserexamples:re:operation='.*?abc'value='$0'(or'$1',`$`meansthegroupindexforregexresult)css:operation=".className"value='$string'$string:return[node]asouterhtml$text:return[node.text]$get_text:return[node.get_text()]@attr:[getattributefromnode]json:viewmore:https://github.com/adriank/ObjectPath# input response JSON string: {"a": 1}operation="$.a"value=Nonepython:!functionnameshouldalwaysbe`parse`ifvalueisNone,oruse`value`asthefunctionname.`operationcanbeafunctionobject.`operation=lambdaresp:resp.textoperation=r'''def parse(resp):return md5(resp.text)'''value=None