C'est pas plutôt ce genre de services que tu cherches, qui permet d'avoir les réponses en json (ou csv) :
https://www.icao.int/safety/iStars/P...OTAM-Data.aspx
Version imprimable
C'est pas plutôt ce genre de services que tu cherches, qui permet d'avoir les réponses en json (ou csv) :
https://www.icao.int/safety/iStars/P...OTAM-Data.aspx
Non pas tout a fait, car mon app sous le format dont je t'ai parlé precedemment dans ma réponse (que j'ai modifié) me permettra de mettre a jours un autre système. d'ou l'importance de mon format XML (ou txt d'ailleurs) mais il doit etre au format dit Raw (avec les Qcodes comme ils disent sur ta page web) ;-)
Tu peux générer le format que tu as besoin à partir du moment où tu as les données qu'il faut. Et c'est quand même plus simple de parser du json que de merdouiller du html qui est fait pour de la présentation...
ok j'en prends note.
il me suffit de remplacer les JSoup par Json ou c'est pas aussi simpàle que cela?
juste par ailleurs, j'ai copié mon projet sur un pc et après avoir adapté les chemin de certaine librairie (a savoir celle du Jsoup) j'ai une connection time out.
je vais pas y arriverCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 Exception in thread "main" java.net.ConnectException: Connection timed out: connect at java.net.DualStackPlainSocketImpl.connect0(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:666) at sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:173) at sun.net.NetworkClient.doConnect(NetworkClient.java:180) at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264) at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:259) at httpsrequesttest.HttpClientExample.sendData(HttpClientExample.java:39) at httpsrequesttest.HttpClientExample.post(HttpClientExample.java:31) at httpsrequesttest.HttpClientExample.main(HttpClientExample.java:19) BUILD FAILED (total time: 23 seconds)
Plus ou moins. Une bibliothèque qui peut être utilisée, c'est Unirest par exemple. Mais parcourir un JSon, ça ne se fait pas comme parcourir un document HTML, avec des sélecteurs CSS, mais plutôt avec des parcours standard (des for, des streams, etc). L'intérêt du JSon c'est qu'il est structuré (il n'y a pas de pollution due à des artifices de présentation comme en HTML) et que les informations sont typées (pas besoin de faire des conversions String vers...) et isolées (dans un site web, des informations distinctes peuvent être concaténées pour la présentation, et la séparation peut être un casse-tête, ou une usine à gaz), crues (raw donc, puisque les informations dans une page web peuvent être converties pour être lisibles (genre localisée, ou un code affiché sous forme de libellé correspondant, etc)), et complètes (toutes les informations disponibles ne sont pas forcément affichées dans la page web). En gros, il n'y a pas vraiment de débat entre la solution JSon et la solution HTML. Le HTML n'est que la dernière solution à envisager si on a pas le choix.
Mmm, je ne vois pas exactement ce que tu appelles "adapter les chemins". Y'a juste à copier le jar "core" dans le projet et configurer le classpath (voir faq).
Sauf que la stacktrace que tu montres ne correspond pas à une utilisation de JSoup, mais une utilisation de HttpUrlConnection... et une classe HttpClientExample dont je ne sais rien puisque je n'en ai pas le code...
Maintenant un timeout de connexion veut dire que le site ne répond pas dans un temps défini : il peut y avoir de nombreuses raisons pour ça, qui n'ont aucun rapport avec le code lui-même, mais plutôt avec l'état du réseau, ou du serveur, ou de l'url ciblée éventuellement.
Je pense que le problème du Time out comme tu le soumets est plus dû au pc que j’utilise sur lequel j’ai une tonne de sécurité.
Il y'a un appel de HttpURLConnection.setConnectTimeout() dans ce code ?
et bien non il n'y en a pas
voici le code PC...
tu vois bien qu'il est identique au precedent et il n'y a pas de HTTPURLConnection TimeoutCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package httpsrequesttest; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.jsoup.Connection; import org.jsoup.Connection.Method; import org.jsoup.Connection.Response; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class Notams { private static final String ICAO = "LFBO LFMK"; private static final String REPORTTYPE = "Raw"; private static final String ACTIONTYPE = "notamRetrievalByICAOs"; private static final String BUTTON = "Check All NOTAMs"; private static final String SUBMIT = "View NOTAMs"; private static final String POST_URL = "https://www.notams.faa.gov/dinsQueryWeb/queryRetrievalMapAction.do"; public static void main(String[] args) { Map<String, Object> parameters = new LinkedHashMap<>(); parameters.put("retrieveLocId", ICAO); parameters.put("reporType", REPORTTYPE); parameters.put("actionType", ACTIONTYPE); parameters.put("button", BUTTON); parameters.put("submit", SUBMIT); File file = new File(System.getProperty("user.home"), "Desktop/MonFichier.xml"); try { getData(parameters, file); } catch (IOException e) { e.printStackTrace(); } } public static void getData(Map<String, Object> params, File outputFile) throws IOException { Connection jsoup = Jsoup.connect(POST_URL).timeout(10 * 1000).method(Method.POST); params.entrySet().forEach(param -> jsoup.data(param.getKey(), String.valueOf(param.getValue()))); Response response = jsoup.execute(); // parse the document from response Document document = response.parse(); XMLOutputFactory xmlfactory = XMLOutputFactory.newInstance(); try (OutputStream output = Files.newOutputStream(outputFile.toPath())) { XMLStreamWriter xmlwriter = xmlfactory.createXMLStreamWriter(output); xmlwriter.writeStartDocument(); try { xmlwriter.writeStartElement("locations"); try { // on parcourt les tables de donnÈes List<Element> tables = document.select("form table table").stream().skip(1) // on ignore les headers .collect(Collectors.toList()); // les tables sont par paires, une pour le nom, une pour les data for (int i = 0; i < tables.size(); i += 2) { Element locationTable = tables.get(i); // pour obtenir le nom (titre) Element name = locationTable.selectFirst("tr:nth-child(2) > td:nth-child(1) > a"); if ( name==null ) continue; // on ignore les tables sans nom xmlwriter.writeStartElement("location"); try { // recherche du nom xmlwriter.writeAttribute("name", name.text()); // on rÈcupËre le texte exportData(xmlwriter,tables.get(i+1)); } finally { xmlwriter.writeEndElement(); // fermer location } } } finally { xmlwriter.writeEndElement(); // fermer locations } } finally { xmlwriter.writeEndDocument(); xmlwriter.close(); } } catch (XMLStreamException e) { throw new IOException(e); } } private static void exportData(XMLStreamWriter xmlwriter, Element element) throws XMLStreamException { xmlwriter.writeStartElement("data"); try { int index=1; for(Element tr : element.select("tr")) { xmlwriter.writeStartElement("ligne"); xmlwriter.writeAttribute("index", String.valueOf(index++)); try { for(Element td : element.select("td")) { xmlwriter.writeStartElement("cell"); try { xmlwriter.writeCharacters(td.text()); } finally { xmlwriter.writeEndElement(); } } } finally { xmlwriter.writeEndElement(); } } } finally { xmlwriter.writeEndElement(); // fermer location } } }
La stacktrace montrée précédemment ne correspond pas à ce dernier code, qui lui contient bien un timeout .timeout(10 * 1000)..
Bonjour Joel,
je te reposte le code qui je ne comprends pas semble être en partie marcher:
je dis en partie car qd je le lance il marque ceci dans la console :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package httpsrequesttest; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.jsoup.Connection; import org.jsoup.Connection.Method; import org.jsoup.Connection.Response; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; public class Notams { private static final String ICAO = "LFBO LFMK"; private static final String REPORTTYPE = "Raw"; private static final String ACTIONTYPE = "notamRetrievalByICAOs"; private static final String BUTTON = "Check All NOTAMs"; private static final String SUBMIT = "View NOTAMs"; private static final String POST_URL = "https://www.notams.faa.gov/dinsQueryWeb/queryRetrievalMapAction.do"; public static void main(String[] args) { Map<String, Object> parameters = new LinkedHashMap<>(); parameters.put("retrieveLocId", ICAO); parameters.put("reporType", REPORTTYPE); parameters.put("actionType", ACTIONTYPE); parameters.put("button", BUTTON); parameters.put("submit", SUBMIT); File file; file = new File(System.getProperty("user.home"), "Desktop/MonFichier.xml"); try { getData(parameters, file); } catch (IOException e) { } } public static void getData(Map<String, Object> params, File outputFile) throws IOException { Connection jsoup = Jsoup.connect(POST_URL).timeout(10 * 1000).method(Method.POST); params.entrySet().forEach(param -> jsoup.data(param.getKey(), String.valueOf(param.getValue()))); Response response = jsoup.execute(); // parse the document from response Document document = response.parse(); XMLOutputFactory xmlfactory = XMLOutputFactory.newInstance(); try (OutputStream output = Files.newOutputStream(outputFile.toPath())) { XMLStreamWriter xmlwriter = xmlfactory.createXMLStreamWriter(output); xmlwriter.writeStartDocument(); try { xmlwriter.writeStartElement("locations"); try { // on parcourt les tables de données List<Element> tables = document.select("form table table").stream().skip(1) // on ignore les headers .collect(Collectors.toList()); // les tables sont par paires, une pour le nom, une pour les data for (int i = 0; i < tables.size(); i += 2) { Element locationTable = tables.get(i); // pour obtenir le nom (titre) Element name = locationTable.selectFirst("tr:nth-child(2) > td:nth-child(1) > a"); if ( name==null ) continue; // on ignore les tables sans nom xmlwriter.writeStartElement("location"); try { // recherche du nom xmlwriter.writeAttribute("name", name.text()); // on récupère le texte exportData(xmlwriter,tables.get(i+1)); } finally { xmlwriter.writeEndElement(); // fermer location } } } finally { xmlwriter.writeEndElement(); // fermer locations } } finally { xmlwriter.writeEndDocument(); xmlwriter.close(); } } catch (XMLStreamException e) { throw new IOException(e); } } private static void exportData(XMLStreamWriter xmlwriter, Element element) throws XMLStreamException { xmlwriter.writeStartElement("data"); try { int index=1; for(Element tr : element.select("tr")) { xmlwriter.writeStartElement("ligne"); xmlwriter.writeAttribute("index", String.valueOf(index++)); try { for(Element td : element.select("td")) { xmlwriter.writeStartElement("cell"); try { xmlwriter.writeCharacters(td.text()); } finally { xmlwriter.writeEndElement(); } } } finally { xmlwriter.writeEndElement(); } } } finally { xmlwriter.writeEndElement(); // fermer location } } }
et rien de plus, pas de fichier créé ( introuvable meme après un scan de mon disque de l'element "MonFichier.xml")Code:
1
2
3 run: BUILD SUCCESSFUL (total time: 12 seconds)
Auriez-vous une piste s'il vous plait?
Le catch est vide, donc s'il y a une exception, tu n'en sais rien. On ne fait jamais ça.Code:
1
2
3
4 try { getData(parameters, file); } catch (IOException e) { }
Code:
1
2
3
4
5 try { getData(parameters, file); } catch (IOException e) { e.printStackTrace(); }
bien vu, j'ai toujours en effet la meme exception.
ne serait ce pas du au fait qu'a l'ouverture de la page il y a un "disclaimer" que je dois "agree" pour poursuivre l'operation ? et par consequent comme je ne valide pas la pop-up l'appli ne peut acceder a l'URL suivante
Essaye en augmentant le timeout
[/quote]
Non, la page html n'est pas traitée et le JavaScript non exécuté.En plus le disclaimer s'affiche sur la page avec le formulaire non ? Pas dans le résultat à priori. Éventuellement, si c'était fait par redirection sur une autre page, ça poserait un souci. M'enfin ce genre d'interactivité c'est un argument de plus pour utiliser un service plutôt que par un site web.
j'ai mis 30s (30000) et pareil...
Je vais essayer en Json alors...
Bonsoir Joel.Drigo, je viens enfin de trouver la réponse pour mon problème de format de sortie dans le XML
la raison etait toute simple
je demande un reportType=Raw dans la réalité sauf que dans le code j'ai écris un reporType (avec un seul T la ou la page en demande 2 reportType
Donc forcement ca marche moins bien.
Enfin un petit pb de réglé
Aussi pourriez vous me donner une explication supplémentaire s'il vous plait?
tout d'abord j'ai modifié un peu le Code en mettant juste les balises qui me convenaient mieux. Cependant, a la premiere ligne il me souligne td (le premier ) en me disant que la variable n'es pas utilisée ?Code:
1
2
3
4
5
6
7
8
9
10 for(Element td : element.select("td")) { xmlwriter.writeStartElement("ligne"); xmlwriter.writeAttribute("index", String.valueOf(index++)); try { for(Element PRE : element.select("PRE")) { xmlwriter.writeStartElement("cell\n"); try { xmlwriter.writeCharacters(PRE.text()); }
Enfin j'ai une dernière demande si vous le permettez, a savoir, y a t il un moyen de retourner a la ligne avant.apres chaque "cell"debutant/fermant? de maniere a mieux structure mon xml ?
cordialement
La variable td n'est pas utilisée dans la boucle for(Element td : element.select("td")). On la déclare, mais on n'en lit pas les informations. C'est juste un warning. Tu peux remplace ce for par un appel de forEarch avec un Consumer pour l'éviter, mais ce n'est pas très important d'avoir ce warning.
En revanche, ce qui n'est pas logique, c'est que tu cherches tous les td, et pour chaque td, tu cherches tous les pre... donc tu va te retrouver avec les pre duppliqués autant de fois qu'il y a de td. Donc soit il faut juste faire une boucle sur tous les pre, soit faire une boucle sur les pre à l'intérieur du chaque td : dans le premier cas, plus de boucle sur td, donc plus de td inutilisé, et dans le second, le td sera bien utilisé.
Peut-être plus facilement lisible par un humain, mais pas mieux structuré. Tu peux utiliser une application qui affiche le xml en plus lisible, genre Internet Explorer. Sinon, l'indentation n'est pas supportée nativement par StAX, mais il existe une blibliothèque stax_utils avec un composant IndentingXMLEventWriter qui le fait.
je ne maitrise pas le for each avec consumer dsl.
par contre je viens de me rendre compte que le xml en sortie fait une taille énorme.
Il semblerait que la boucle ne s'arrete qu'au bout du temps imparti. lol du coup ca me fait fichier de 134Mo 8O
Tu veux probablement parler de forEach().
Attention :
- Structure forEach
La structure forEach est une structure de boucle dont la syntaxe est : for(<un type> <une variable> : <un iterable ou un tableau d'éléments de type compatible avec type>.
Par exemple :
Code:
1
2
3
4 List<String> uneliste = Arrays.asList("a","b","c"); for(String machin : uneliste) { // ici on fait un truc avec machin (ou pas, mais on a un warning dans ce cas) }
- méthode forEach(), de certaines classes comme Collection (donc List, entre autres), ou Stream, etc.
Il s'agit d'une méthode qui prend en paramètre une instance de Consumer (paramétrée par le type de la classe qui a la méthode).
Code:
1
2
3
4 List<String> uneliste = Arrays.asList("a","b","c"); uneliste.forEach(machin-> { // ici on fait un truc avec machin (ou pas, mais pas de warning) });
Mais, comme je l'ai dit, le problème n'est pas là, mais dans le produit cartésien td × pre que tu fais. Il ne faut pas à priori boucle sur les tds, sauf si tu as besoin de parcourir que les pre qui sont dans ces td, mais dans ce cas, il faut le faire (il faut que le sélecteur soit relatif au td, d'une manière ou d'une autre)<;
si tu as une structure html comme ça :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 <html> <body> <table> <tr> <td> <pre id="1"></pre> </td> <td> <pre id="2"></pre> </td> </tr> <tr> <td> <pre id="3"></pre> </td> <td> <pre id="4"></pre> </td> </tr> </table> </body> </html>
Et que pour tout td, tu vas chercher tous les pre, tu auras :
- pre id=1
- pre id=2
- pre id=3
- pre id=4
- pre id=1
- pre id=2
- pre id=3
- pre id=4
- pre id=1
- pre id=2
- pre id=3
- pre id=4
- pre id=1
- pre id=2
- pre id=3
- pre id=4
pas
- pre id=1
- pre id=2
- pre id=3
- pre id=4
en gros, au lieu d'avoir le nombre d'élements xml représentant des "pre" égal au nombre de pre, tu auras le nombre d'élements xml égal au nombre de td multiplié par le nombre de pre. A noter que c'est aussi le cas, si les pre ne sont pas dans les td...
Je dirais que ce n'est pas surprenant vu le produit cartésien de td et de pre.
[/QUOTE]
Et ça s'arrête à priori quand c'est fini, donc quand on a parcouru tous les td trouvés. Je ne vois pas ce que tu désignes par "temps imparti"...