Install
openclaw skills install @jorgeanais/astroph-arxiv-skill-repoEmbed the Python script directly into the skill for robust and reproducible XML parsing.
openclaw skills install @jorgeanais/astroph-arxiv-skill-repoWhen the user requests a literature search for a specific topic, execute these steps strictly:
Construct the Query:
https://export.arxiv.org/api/querycat:astro-ph with keywords and sortBy=submittedDate breaks the API's sorting and returns old papers (e.g., from 2008). To get truly recent papers, you MUST use a subcategory like cat:astro-ph.GA (Galactic Astrophysics), cat:astro-ph.SR, etc., or omit the cat: filter if the query is already specific enough.max_results=2. NEVER exceed the requested limit.?search_query=cat:astro-ph.GA+AND+all:"<user_topic>"&sortBy=submittedDate&sortOrder=descending&max_results=<number>%20AND%20).Execute Fetch and Parse:
parse_arxiv.py) to fetch, parse, and format the XML data perfectly. It ensures correct highlighting and formatting.import urllib.request
import xml.etree.ElementTree as ET
import re
import sys
# Inject the exact URL constructed in Step 1 here
URL = "YOUR_CONSTRUCTED_URL_HERE"
def highlight(text):
words_to_bold = [
"Gaia", "VVV", "VVVX", "H.E.S.S.", "ACS", "MACHO", "SEKBO",
"metallicity", "decontamination", "maximum likelihood",
"spectroscopy", "photometry", "kinematics", "proper-motion"
]
for w in words_to_bold:
pattern = re.compile(re.escape(w), re.IGNORECASE)
text = pattern.sub(lambda m: f"**{m.group(0)}**", text)
return text
try:
req = urllib.request.Request(URL, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req) as response:
xml_data = response.read()
except Exception as e:
print(f"Error fetching data: {e}")
sys.exit(1)
root = ET.fromstring(xml_data)
ns = {'atom': 'http://www.w3.org/2005/Atom'}
count = 0
for entry in root.findall('atom:entry', ns):
title_el = entry.find('atom:title', ns)
if title_el is None or title_el.text == 'Error':
continue
title = title_el.text.replace('\n', ' ').strip()
authors = [author.find('atom:name', ns).text for author in entry.findall('atom:author', ns)]
author_str = f"{authors[0]}, {authors[1]}, {authors[2]}, {authors[3]} et al." if len(authors) > 4 else ", ".join(authors)
published = entry.find('atom:published', ns).text[:10]
summary = highlight(entry.find('atom:summary', ns).text.replace('\n', ' ').strip())
link_abs = entry.find('atom:id', ns).text
link_pdf = link_abs.replace('/abs/', '/pdf/') + ".pdf"
print(f"**{title}**")
print(f"**Authors:** {author_str}")
print(f"**Date:** {published}")
print(f"**Links:** [Abstract]({link_abs}) | [PDF]({link_pdf})")
print(f"> {summary}\n\n---")
count += 1
print(f"Found {count} papers.")