main.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. <title>{coin_name}</title>
  37. <body>
  38. <div style="width: 80%; margin: auto; text-align: center; font-size: 18px; padding: 10px;">
  39. {result}
  40. </div>
  41. </body>
  42. </html>"""
  43. return HTMLResponse(content=html_result, status_code=200)
  44. except httpx.RequestError as e:
  45. return HTMLResponse(content=f"<p style='text-align: center;'>Request Error: {e}</p>", status_code=200)
  46. except Exception as e:
  47. return HTMLResponse(content=f"<p style='text-align: center;'>Internal Error: {e}</p>", status_code=200)
  48. def get_coin_data(url: str, headers: dict, proxies: dict, proxy_type: int):
  49. result = ''
  50. if proxy_type:
  51. resp = httpx.get(url=url, headers=headers, proxies=proxies, timeout=3)
  52. else:
  53. resp = httpx.get(url=url, headers=headers, timeout=3)
  54. if resp.status_code != 200:
  55. raise HTTPException(status_code=resp.status_code,detail=f"Failed to retrieve data, status code: {resp.status_code}")
  56. page = resp.text
  57. text = re.search('<strong>(.*?)sc-65e7f566-0', page)
  58. if not text:
  59. return 'No Data'
  60. text = re.sub(r'</strong>', '', text.group(1))
  61. text = re.sub(r'<!-- -->', '', text)
  62. text = re.sub(r'</p></div></div><div class="', '', text)
  63. prices = re.findall(r'\$(\d+\.\d+)', text)
  64. volumes = re.findall(r'\$(\d{1,3}(?:,\d{3})*(?:\.\d+)?)', text)
  65. change = re.findall(r'(up|down) (\d+\.\d+)%', text)
  66. live_market_cap = re.findall(r'\$(\d{1,3}(?:,\d{3})*(?:\.\d+)?)', text)
  67. max_circulating_supply = re.findall(r'(\d{1,3}(?:,\d{3})*)', text)
  68. result += text.replace('我们会实时更新SUI兑换为CNY的价格。 ', '')
  69. if prices:
  70. result += f'\n\nprices: ${prices[0]}'
  71. if volumes:
  72. result += f'\n24-hour trading volume: ${volumes[1]}'
  73. if change:
  74. c = ' '.join(change[0])
  75. result += f'\nchange: {c}%'
  76. if live_market_cap and len(live_market_cap) == 3:
  77. result += f'\nlive market cap: ${live_market_cap[2]}'
  78. if max_circulating_supply:
  79. result += f'\nmax circulating supply: {max_circulating_supply[-1]}'
  80. if result:
  81. result = re.sub(r'price([\S\s]*)?coins\.\n', '', result)
  82. return result.replace('\n', '<br>').replace('. ', '<br>')
  83. if __name__ == "__main__":
  84. uvicorn.run("main:app", host="0.0.0.0", port=32900, reload=True)