Une liste des packages est disponible sur la page d'accueil http://rforge.net. Nous allons parser cette liste afin de récupérer chaque nom de package, et ensuite nous téléchargeons les meta-data associées à chaque package.
Ces meta-data sont accessibles directement en ligne. Par exemple, pour le package Acinonyx, le fichier est disponible à l'adresse suivante : http://svn.rforge.net/Acinonyx/trunk/DESCRIPTION
In [1]:
import requests
import BeautifulSoup as bs
PKG_LIST_URL = 'http://rforge.net'
PKG_DETAILS_URL = 'http://svn.rforge.net/{name}/trunk/DESCRIPTION'
In [2]:
content = requests.get(PKG_LIST_URL).content
soup = bs.BeautifulSoup(content)
In [3]:
table = soup.find('b', text='Current projects').findNext('table')
anchors = filter(lambda x: x, (row.find('a') for row in table.findAll('tr') if row))
urls = map(lambda a: a['href'], anchors)
packages = map(lambda u: u[1:-1], urls)
In [4]:
packages[:10]
Out[4]:
Nous allons maintenant récupérer les fichiers descriptions. Nous les parserons directement dans un dictionnaire, afin de générer un joli petit fichier .csv avec pandas à la fin.
In [5]:
d = {}
err404 = []
for name in packages:
r = requests.get(PKG_DETAILS_URL.format(name=name))
if r.status_code != 200:
err404.append(name)
else:
d[name] = {}
for line in r.content.split('\n'):
if len(line) > 0:
# Si la ligne débute par des tabulations ou espace, continuation de la ligne précédente
if line.startswith((' ', '\t')):
d[name][key] += ' ' + line.strip() # key a encore la bonne valeur
else:
try:
key, value = line.split(':', 1)
d[name][key.strip()] = value.strip()
except Exception as e:
print name
print line
print '---'
print content
raise
In [6]:
len(d), len(err404), len(packages)
Out[6]:
In [14]:
import pandas
pandas.DataFrame.from_dict(d, orient='index').to_csv('../data/rforge_description.csv')