main.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. # -*- coding: utf-8 -*-
  2. import re
  3. from fastapi import FastAPI, HTTPException
  4. import uvicorn
  5. import httpx
  6. from fastapi.responses import HTMLResponse
  7. app = FastAPI()
  8. COIN_ITEMS = {
  9. 'btc': 'https://coinmarketcap.com/currencies/bitcoin/',
  10. 'eth': 'https://coinmarketcap.com/currencies/ethereum/',
  11. 'sol': 'https://coinmarketcap.com/currencies/solana/',
  12. 'sui': 'https://coinmarketcap.com/currencies/sui/',
  13. 'doge': 'https://coinmarketcap.com/currencies/dogecoin/',
  14. 'x': 'https://coinmarketcap.com/currencies/x-empire/',
  15. 'arb': 'https://coinmarketcap.com/currencies/arbitrum/',
  16. 'pepe': 'https://coinmarketcap.com/currencies/pepe/',
  17. 'grass': 'https://coinmarketcap.com/currencies/grass/',
  18. 'bome': 'https://coinmarketcap.com/currencies/book-of-meme/',
  19. }
  20. PROXIES = {
  21. "http://": "http://127.0.0.1:7890",
  22. "https://": "http://127.0.0.1:7890"
  23. }
  24. HEADERS = {
  25. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107"
  26. }
  27. @app.get("/coin/{proxy_type}/{coin_name}", response_class=HTMLResponse)
  28. async def read_coin(coin_name: str, proxy_type: int = 0):
  29. coin_url = COIN_ITEMS.get(coin_name)
  30. if not coin_url:
  31. return HTMLResponse(content=f"<p style='text-align: center;'>error: {coin_name}</p>", status_code=200)
  32. try:
  33. result = get_coin_data(coin_url, HEADERS, PROXIES, proxy_type)
  34. # 使用HTMLResponse返回居中的HTML内容
  35. html_result = f"""<html>
  36. <body>
  37. <div style="width: 80%; margin: auto; text-align: left; font-size: 16px; padding: 20px;">
  38. {result}
  39. </div>
  40. </body>
  41. </html>"""
  42. return HTMLResponse(content=html_result, status_code=200)
  43. except httpx.RequestError as e:
  44. return HTMLResponse(content=f"<p style='text-align: center;'>Request Error: {e}</p>", status_code=200)
  45. except Exception as e:
  46. return HTMLResponse(content=f"<p style='text-align: center;'>Internal Error: {e}</p>", status_code=200)
  47. def get_coin_data(url: str, headers: dict, proxies: dict, proxy_type: int):
  48. result = ''
  49. if proxy_type:
  50. resp = httpx.get(url=url, headers=headers, proxies=proxies, timeout=3)
  51. else:
  52. resp = httpx.get(url=url, headers=headers, timeout=3)
  53. if resp.status_code != 200:
  54. raise HTTPException(status_code=resp.status_code,detail=f"Failed to retrieve data, status code: {resp.status_code}")
  55. page = resp.text
  56. text = re.search('<strong>(.*?)sc-65e7f566-0', page)
  57. if not text:
  58. return 'No Data'
  59. text = re.sub(r'</strong>', '', text.group(1))
  60. text = re.sub(r'<!-- -->', '', text)
  61. text = re.sub(r'</p></div></div><div class="', '', text)
  62. prices = re.findall(r'\$(\d+\.\d+)', text)
  63. volumes = re.findall(r'\$(\d{1,3}(?:,\d{3})*(?:\.\d+)?)', text)
  64. change = re.findall(r'(up|down) (\d+\.\d+)%', text)
  65. live_market_cap = re.findall(r'\$(\d{1,3}(?:,\d{3})*(?:\.\d+)?)', text)
  66. max_circulating_supply = re.findall(r'(\d{1,3}(?:,\d{3})*)', text)
  67. result += text.replace('我们会实时更新SUI兑换为CNY的价格。 ', '')
  68. if prices:
  69. result += f'\n\nprices: ${prices[0]}'
  70. if volumes:
  71. result += f'\n24-hour trading volume: ${volumes[1]}'
  72. if change:
  73. c = ' '.join(change[0])
  74. result += f'\nchange: {c}%'
  75. if live_market_cap and len(live_market_cap) == 3:
  76. result += f'\nlive market cap: ${live_market_cap[2]}'
  77. if max_circulating_supply:
  78. result += f'\nmax circulating supply: {max_circulating_supply[-1]}'
  79. if result:
  80. result = re.sub(r'price([\S\s]*)?coins\.\n', '', result)
  81. return result.replace('\n', '<br>').replace('. ', '<br>')
  82. if __name__ == "__main__":
  83. uvicorn.run("main:app", host="0.0.0.0", port=32900, reload=True)