Auteur Sujet: #openData #python les incidents de l'Autorité de Sureté Nucléaire  (Lu 1504 fois)

Jessica Nichenin

  • Carnivorous Salami
  • *
  • Messages: 83
Voici donc un script pour transformer en un seul fichier XML tous les incidents nucléaires de l'Autorité de Sureté Nucléaire.
du type

Citer
<incident><URL>http://www.asn.fr/index.php/content/view/full/149941</URL><titre>Sortie du domaine d’exploitation « pression – température »</titre><date>11-Octobre-2013</date><lieu>Centrale nucléaire de Dampierre-en-Burly</lieu><niveau>niveau 1</niveau><text>Le 25 septembre 2013, alors que le réacteur 1 de la centrale nucléaire de Dampierre était en phase de redémarrage suite à son arrêt pour maintenance, la température du circuit primaire a atteint une valeur supérieure au domaine de fonctionnement autorisé. Sur les réacteurs à eau pressurisée exploités par EDF, le circuit primaire est un circuit fermé, contenant de l’eau sous pression qui s’échauffe dans la cuve du réacteur au contact des éléments combustibles. Les règles générales d’exploitation définissent les limites autorisées pour la pression et la température du circuit primaire qui doivent être suivies en permanence notamment pendant les opérations de mise à l’arrêt ou de redémarrage du réacteur. Lors de l'événement, le circuit primaire du réacteur 1 est fermé, pressurisé à 27 bars, à 127°C. Dans cette configuration, l’exploitant doit s’assurer que la température du circuit primaire ne descende pas sous 120°C. Afin de s'assurer de l’élimination de résidus détectés dans les générateurs de vapeur lors de l'arrêt pour maintenance, les opérateurs arrêtent deux des trois pompes primaires pour limiter la vitesse de montée en température du circuit primaire. Pour cette activité, les opérateurs ont focalisé leur attention sur la pression du circuit primaire et non sur sa température. Or l’arrêt des deux pompes a conduit à un refroidissement non prévu du circuit primaire, et à une sortie du domaine autorisé. Les opérateurs ont détecté cet écart au bout de six minutes. Ils ont alors relancé les deux pompes pour réchauffer le circuit primaire. Sa température est remontée au-dessus du seuil de 120° C une heure trente plus tard. Cet événement n’a pas eu de conséquence sur le personnel ni sur l’environnement de l’installation. Toutefois, en raison d’un non respect d’une prescription permanente  des règles générales d’exploitation, cet évènement a été classé au niveau 1 de l’échelle internationale des évènements nucléaires INES. </text></incident><incident>
Trois petits points
* Le site a un système anti flood, si on lance trop de requêtes en même temps, votre ip est bloqué d'ou la présence d'un time.sleep dans le code.
* Les Mentions Légales sont ici
http://asn.fr/index.php/Bas-de-page/Pied-de-Page/Mentions-legales
Citer
La reproduction sur support électronique

La reproduction de tout ou partie de ce site sur un support électronique est autorisée sous réserve de l'ajout de façon claire et lisible de la source (http://www.asn.fr) et de la mention "Droits réservés".
Les informations utilisées ne doivent l'être qu'à des fins personnelles, associatives ou professionnelles ; toute utilisation à des fins commerciales ou publicitaires est exclue.
L'intégrité des documents reproduits doit être respectée (aucune modification, ni altération d'aucune sorte).
* Je suis disponible pour toute association/personne qui voudrait l'utiliser, le modifier et publier de par le monde les incidents.

#! /usr/bin/python
import re
import urllib
from BeautifulSoup import BeautifulSoup
from elementtree.SimpleXMLWriter import XMLWriter
import logging
import time
# -*- coding: utf-8 -*-

def remove_values_from_list(the_list, val):

return [value for value in the_list if value != val]

def formatage(text):

texte = (" ".join(text.split()))
return texte.replace("&nbsp;","")

def formatagetitre(table,myurl):

titre = ""
try:
titre = (table.find("h1").renderContents().replace('\n','')).decode("utf-8")
except:
logging.info("Erreur inclusion Titre %s: %s" % ( titre,myurl))
return titre

def formatagemap(table,myurl):

date = ""
try:
date = table.find("span",{"class" : "date"}).renderContents().split(",")[1].replace("le ","").lstrip().replace(" ","-")
except:
logging.info("Erreur inclusion Date %s: %s" % ( date,myurl))
return date

def formatagelieu(table,myurl):

lieu = ""
try:
lieu = table.find("span",{"class" : "bold"}).find("a").string
except:
logging.info("Erreur inclusion Lieu %s: %s" % ( lieu,myurl))
return lieu

def formatagelist(table,myurl):

niveau = ""
try:
temp = table.findAll("strong")
liste = (re.sub("au n","n",temp[1].renderContents()))
except:
try:
element = "niveau"
index = str(table).find(element)
niveau = str(table)[index:index + 8]
logging.info("Erreur inclusion Niveau Autre %s: %s" % ( niveau,myurl))
except:
logging.info("Erreur inclusion Niveau %s: %s" % ( niveau,myurl))

return niveau

def formatagecontent(table,myurl):

content = ""
try:
divp = table.find("p",{"class":"pdf_link"})
divp.extract()
divblock1 = table.find("div",{"class":"block1"})
divblock1.extract()
for div in table.findAll("span"):
div.extract()
divblockul = table.find("ul",{"class":"list"})
divblockul.extract()
content = formatage("".join(table.findAll(text=True)))
except:
logging.info("Erreur inclusion Content %s: %s" % ( content,myurl))
return content

def rassemblement():

listurl= []
''' 61 au lieu de 1'''
for i in range(0,66):
if i<1:
url = "http://www.asn.fr/index.php/content/view/full/1524//%28offset%29/"
else:
url = "http://www.asn.fr/index.php/content/view/full/1524//%28offset%29/"+str(int(i*20))
f = urllib.urlopen(url)
htmldata = f.read()
soup = BeautifulSoup(htmldata,convertEntities=BeautifulSoup.HTML_ENTITIES)
table3 = soup.find("div", { "id" : "min_height" })
table = table3.findAll( 'a',href = re.compile("^/index.php/Les-activites-controlees-par-l-ASN/Production-d-Electricite/Avis-d-incidents-dans-les-installations-nucleaires/.*"))
for element in table:
listurl.append(element['href'])
table2 = table3.findAll( 'a',href = re.compile("^/index.php/content/view/full/.*"))
for element in table2:
match = re.match("^/index.php/content/view/full/1524/.*",element['href'])
if match is not None:
pass
else:
match = re.match("^/index.php/content/view/full/900/.*",element['href'])
if match is not None:
pass
else:
listurl.append(element['href'])
i = i + 1
f.close()
return listurl

def traitement(myurl):

w.start("incident")
w.element("URL","http://www.asn.fr/" + myurl)
f = urllib.urlopen("http://www.asn.fr/" + myurl)
htmldata = f.read()

soup = BeautifulSoup(htmldata)
table = soup.find("div",{"class" : "col4 entry"})
w.element("titre",formatagetitre(table,myurl))

w.element("date",formatagemap(table,myurl))

w.element("lieu",formatagelieu(table,myurl))
w.element("niveau",formatagelist(table,myurl))

table2 = soup.find("div",{"id" : "min_height"})
w.element("text",formatagecontent(table2,myurl))
w.end("incident")

if __name__ == '__main__':

logging.basicConfig(filename='erreur.log',level=logging.INFO,format='%(asctime)s %(levelname)s - %(message)s',datefmt='%d/%m/%Y %H:%M:%S')
listurl = rassemblement()
listurl = remove_values_from_list(listurl,"/index.php/content/view/full/1524")
w = XMLWriter("asn.xml","utf-8")
w.declaration()

for element in listurl:
time.sleep(10)
print "http://www.asn.fr/" + element
traitement(element)

playlist = w.start("asn")
w.close(playlist)