|
|
@@ -1,5 +1,7 @@
|
|
|
# -*- coding: utf-8 -*-
|
|
|
import re
|
|
|
+import time
|
|
|
+import random
|
|
|
from fastapi import FastAPI, HTTPException
|
|
|
import uvicorn
|
|
|
import httpx
|
|
|
@@ -32,26 +34,46 @@ HEADERS = {
|
|
|
|
|
|
@app.get("/coin/{proxy_type}/{coin_name}", response_class=HTMLResponse)
|
|
|
async def read_coin(coin_name: str, proxy_type: int = 0):
|
|
|
- coin_url = COIN_ITEMS.get(coin_name)
|
|
|
- if not coin_url:
|
|
|
- return HTMLResponse(content=f"<p style='text-align: center;'>error: {coin_name}</p>", status_code=200)
|
|
|
-
|
|
|
- try:
|
|
|
- result = get_coin_data(coin_url, HEADERS, PROXIES, proxy_type)
|
|
|
- # 使用HTMLResponse返回居中的HTML内容
|
|
|
- html_result = f"""<html>
|
|
|
- <title>{coin_name}</title>
|
|
|
- <body>
|
|
|
- <div style="width: 80%; margin: auto; text-align: center; font-size: 18px; padding: 10px;">
|
|
|
- {result}
|
|
|
- </div>
|
|
|
- </body>
|
|
|
- </html>"""
|
|
|
- return HTMLResponse(content=html_result, status_code=200)
|
|
|
- except httpx.RequestError as e:
|
|
|
- return HTMLResponse(content=f"<p style='text-align: center;'>Request Error: {e}</p>", status_code=200)
|
|
|
- except Exception as e:
|
|
|
- return HTMLResponse(content=f"<p style='text-align: center;'>Internal Error: {e}</p>", status_code=200)
|
|
|
+ # -------------------------------------------------------------------------------- 所有url --------------------------------------------------------------------------------
|
|
|
+ if coin_name == 'all':
|
|
|
+ try:
|
|
|
+ result = get_all_coin_data(COIN_ITEMS, HEADERS, PROXIES, proxy_type)
|
|
|
+ # 使用HTMLResponse返回居中的HTML内容
|
|
|
+ html_result = f"""<html>
|
|
|
+ <title>all</title>
|
|
|
+ <body>
|
|
|
+ <div style="width: 80%; margin: auto; text-align: center; font-size: 18px; padding: 10px;">
|
|
|
+ {result}
|
|
|
+ </div>
|
|
|
+ </body>
|
|
|
+ </html>"""
|
|
|
+ return HTMLResponse(content=html_result, status_code=200)
|
|
|
+ except httpx.RequestError as e:
|
|
|
+ return HTMLResponse(content=f"<p style='text-align: center;'>Request Error: {e}</p>", status_code=200)
|
|
|
+ except Exception as e:
|
|
|
+ return HTMLResponse(content=f"<p style='text-align: center;'>Internal Error: {e}</p>", status_code=200)
|
|
|
+
|
|
|
+ else: # -------------------------------------------------------------------------------- 单个url --------------------------------------------------------------------------------
|
|
|
+ coin_url = COIN_ITEMS.get(coin_name)
|
|
|
+ if not coin_url:
|
|
|
+ return HTMLResponse(content=f"<p style='text-align: center;'>error: {coin_name}</p>", status_code=200)
|
|
|
+
|
|
|
+ try:
|
|
|
+ result = get_coin_data(coin_url, HEADERS, PROXIES, proxy_type)
|
|
|
+ # 使用HTMLResponse返回居中的HTML内容
|
|
|
+ html_result = f"""<html>
|
|
|
+ <title>{coin_name}</title>
|
|
|
+ <body>
|
|
|
+ <div style="width: 80%; margin: auto; text-align: center; font-size: 18px; padding: 10px;">
|
|
|
+ {result}
|
|
|
+ </div>
|
|
|
+ </body>
|
|
|
+ </html>"""
|
|
|
+ return HTMLResponse(content=html_result, status_code=200)
|
|
|
+ except httpx.RequestError as e:
|
|
|
+ return HTMLResponse(content=f"<p style='text-align: center;'>Request Error: {e}</p>", status_code=200)
|
|
|
+ except Exception as e:
|
|
|
+ return HTMLResponse(content=f"<p style='text-align: center;'>Internal Error: {e}</p>", status_code=200)
|
|
|
|
|
|
|
|
|
def get_coin_data(url: str, headers: dict, proxies: dict, proxy_type: int):
|
|
|
@@ -96,6 +118,50 @@ def get_coin_data(url: str, headers: dict, proxies: dict, proxy_type: int):
|
|
|
|
|
|
return result.replace('\n', '<br>').replace('. ', '<br>')
|
|
|
|
|
|
+def get_all_coin_data(coin_item: str, headers: dict, proxies: dict, proxy_type: int):
|
|
|
+ result = ''
|
|
|
+
|
|
|
+ for c_name, url in coin_item.items():
|
|
|
+ if proxy_type:
|
|
|
+ resp = httpx.get(url=url, headers=headers, proxies=proxies, timeout=3)
|
|
|
+ else:
|
|
|
+ resp = httpx.get(url=url, headers=headers, timeout=3)
|
|
|
+ if resp.status_code != 200:
|
|
|
+ raise HTTPException(status_code=resp.status_code,detail=f"Failed to retrieve data, status code: {resp.status_code}")
|
|
|
+
|
|
|
+ page = resp.text
|
|
|
+ text = re.search('<strong>(.*?)sc-65e7f566-0', page)
|
|
|
+ if not text:
|
|
|
+ return 'No Data'
|
|
|
+
|
|
|
+ text = re.sub(r'</strong>', '', text.group(1))
|
|
|
+ text = re.sub(r'<!-- -->', '', text)
|
|
|
+ text = re.sub(r'</p></div></div><div class="', '', text)
|
|
|
+
|
|
|
+ prices = re.findall(r'today is (.*?) USD with', text)
|
|
|
+ volumes = re.findall(r'trading volume of (.*?) USD', text)
|
|
|
+ change = re.findall(r'(up|down) (\d+\.\d+)%', text)
|
|
|
+ live_market_cap = re.findall(r'with a live market cap of (.*?) USD', text)
|
|
|
+ max_circulating_supply = re.findall(r'max. supply of (.*?) ', text)
|
|
|
+
|
|
|
+ result += f'{c_name}\n'
|
|
|
+ if prices:
|
|
|
+ result += f'prices: {prices[0]}\n'
|
|
|
+ if volumes:
|
|
|
+ result += f'24-hour trading volume: {volumes[0]}\n'
|
|
|
+ if change:
|
|
|
+ c = ' '.join(change[0])
|
|
|
+ result += f'change: {c}%\n'
|
|
|
+ if live_market_cap and len(live_market_cap) == 3:
|
|
|
+ result += f'live market cap: {live_market_cap[2]}\n'
|
|
|
+ if max_circulating_supply:
|
|
|
+ result += f'max circulating supply: {max_circulating_supply[-1]}\n'
|
|
|
+
|
|
|
+ result += '\n'
|
|
|
+
|
|
|
+ time.sleep(random.uniform(0.2, 0.5))
|
|
|
+
|
|
|
+ return result.replace('\n', '<br>').replace('. ', '<br>')
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
uvicorn.run("main:app", host="0.0.0.0", port=32900, reload=True)
|