- Trading skills (OKX, dividend, lottery, quantitative) - Creative skills (ASCII art, diagrams, video) - Development skills (GitHub, debugging, TDD) - Research skills (arXiv, blog monitoring) - Productivity skills (email, documents, notes) - MCP integration skills - Custom user skills
88 lines
3.2 KiB
Python
88 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Parse GitHub Trending page via curl + regex.
|
|
|
|
Use this when browser_navigate to GitHub trending fails (CDP timeout).
|
|
Write to /tmp/parse_trending.py, then run: python3 /tmp/parse_trending.py
|
|
|
|
Usage:
|
|
python3 /tmp/parse_trending.py # daily trending (default)
|
|
python3 /tmp/parse_trending.py weekly # this week
|
|
python3 /tmp/parse_trending.py monthly # this month
|
|
|
|
Output: JSON array of repo objects.
|
|
"""
|
|
|
|
import subprocess, re, json, sys
|
|
|
|
since = sys.argv[1] if len(sys.argv) > 1 else "daily"
|
|
url = f"https://github.com/trending?since={since}"
|
|
|
|
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
|
|
html = result.stdout
|
|
|
|
# Find all article elements (each is a trending repo card)
|
|
articles = re.findall(r'<article[^>]*>(.*?)</article>', html, re.DOTALL)
|
|
|
|
results = []
|
|
for art in articles:
|
|
# Extract repo name from h2 > a href=\"/owner/repo\"
|
|
# ⚠️ The FIRST <a> in <h2> is often a /sponsors/ or /login? link, NOT the repo.
|
|
# Skip any href starting with "sponsors/" or "login?".
|
|
h2_section = re.search(r'<h2[^>]*>(.*?)</h2>', art, re.DOTALL)
|
|
if h2_section:
|
|
repo_hrefs = re.findall(r'href=\"/[^\"#]+/[^\"]+\"', h2_section.group(1))
|
|
# Pick the first href that is NOT a sponsors or login link
|
|
name = ''
|
|
for href in repo_hrefs:
|
|
href_val = href.split('"')[1] # extract value from href="..."
|
|
if not href_val.startswith('/sponsors/') and not href_val.startswith('/login?'):
|
|
name = href_val.lstrip('/')
|
|
break
|
|
else:
|
|
# Fallback: scan the whole article
|
|
all_hrefs = re.findall(r'href=\"/[^\"#]+/[^\"]+\"', art)
|
|
for href in all_hrefs:
|
|
href_val = href.split('"')[1]
|
|
if not href_val.startswith('/sponsors/') and not href_val.startswith('/login?'):
|
|
name = href_val.lstrip('/')
|
|
break
|
|
else:
|
|
name = ''
|
|
|
|
# Extract description from <p class="col-9...>
|
|
desc_match = re.search(r'<p class=\"col-9[^>]*>(.*?)</p>', art, re.DOTALL)
|
|
desc = desc_match.group(1).strip() if desc_match else ''
|
|
|
|
# Extract total stars from stargazers link
|
|
stars_match = re.search(r'href=\"[^\"]*stargazers\"[^>]*>\s*(.*?)\s*</a>', art, re.DOTALL)
|
|
stars = ''
|
|
if stars_match:
|
|
s = stars_match.group(1).strip()
|
|
s = re.sub(r'[,\s]', '', s)
|
|
stars = s
|
|
|
|
# Extract language (known languages only)
|
|
lang_match = re.search(
|
|
r'<span[^>]*>(TypeScript|Python|JavaScript|Rust|Go|C\+\+|Java|Kotlin|Swift|Ruby|PHP|Shell|HTML|CSS|Jupyter Notebook)</span>',
|
|
art
|
|
)
|
|
lang = lang_match.group(1) if lang_match else ''
|
|
|
|
# Extract stars today / this week / this month
|
|
stars_period = ''
|
|
for span in re.finditer(r'<span[^>]*>(.*?)</span>', art, re.DOTALL):
|
|
t = span.group(1).strip()
|
|
if 'stars today' in t or 'stars this week' in t or 'stars this month' in t:
|
|
stars_period = t
|
|
|
|
if name:
|
|
results.append({
|
|
'name': name,
|
|
'desc': desc,
|
|
'stars': stars,
|
|
'lang': lang,
|
|
'starsPeriod': stars_period,
|
|
})
|
|
|
|
print(json.dumps(results, ensure_ascii=False, indent=2))
|