Enregistrer ou imprimer toutes les pages d'un sujet
2 participants
Forum gratuit : Le forum des forums actifs :: Entraide & Support... :: Problème divers :: Archives des problèmes divers
Page 1 sur 1 • Partagez
Enregistrer ou imprimer toutes les pages d'un sujet
Détails techniques
Version du forum : phpBB2
Poste occupé : Fondateur
Navigateur(s) concerné(s) : Google Chrome
Personnes concernées par le problème : Tous les utilisateurs
Lien du forum :
Description du problème
Bonjour,Je cherche à récupérer le contenu de différents sujets... dont certains font plusieurs dizaines de pages !
Autant vous dire que après avoir commencé avec des copier/coller (pour récupérer seulement le contenu des messages), puis être passée sur une impression directe de chaque page une par une, pour ensuite fusionner mes documents par sujet... ma motivation en a pris assez vite un coup !
Existe-t-il une astuce ou un code permettant d'enregistrer ou d'imprimer toutes les pages d'un sujet d'un seul coup ?
(sinon, je sens que je vais le proposer en suggestion, même si je doute de son succès )
Merci !
MlleAlys- Membre actif
- Messages : 5967
Inscrit(e) le : 12/09/2012
Re: Enregistrer ou imprimer toutes les pages d'un sujet
Bonjour !
Je pense pouvoir bricoler quelque chose en passant par un HTML personnalisé avec un champ à remplir (un lien vers le sujet en question). Un script irait alors automatiquement regarder le sujet, recopierait les messages, et parcourrait toutes les pages dudit sujet pour afficher toutes les réponses les unes à la suite des autres sur une seule et même page.
Ça permettrait de pouvoir sauvegarder la page ainsi générée, ou même l'imprimer.
Est-ce que ça conviendrait ?
Est-ce qu'il y aurait des choses particulières à récupérer ou à ne pas récupérer ?
Est-ce qu'on garde les profils, les messages, la mise en forme, les signatures, tout ?
Je pense pouvoir bricoler quelque chose en passant par un HTML personnalisé avec un champ à remplir (un lien vers le sujet en question). Un script irait alors automatiquement regarder le sujet, recopierait les messages, et parcourrait toutes les pages dudit sujet pour afficher toutes les réponses les unes à la suite des autres sur une seule et même page.
Ça permettrait de pouvoir sauvegarder la page ainsi générée, ou même l'imprimer.
Est-ce que ça conviendrait ?
Est-ce qu'il y aurait des choses particulières à récupérer ou à ne pas récupérer ?
Est-ce qu'on garde les profils, les messages, la mise en forme, les signatures, tout ?
Re: Enregistrer ou imprimer toutes les pages d'un sujet
ooooooh merci Toryudo !
J'essayais aussi de faire une sorte de formulaire sur une page html de mon forum test !
Et... bon... clairement pour l'instant sans succès, le javascript c'est toujours pas mon truc, je galère, j'ai l'impression d'écrire des trucs hyper moches et peu efficaces, je ne sais pas me servir de la console et je me retrouve à ajouter des alert() à chaque nouvelle ligne pour voir si ça fonctionne !
Ton aide sera la bienvenue !
Je souhaite pouvoir récupérer le titre du sujet, le sondage s'il y en a un, le contenu des messages avec le pseudo du posteur ;
Si possible sans signature, et pour les champs du profil à vrai dire j'ai hésité mais j'ai finalement choisi non !
Attention, réflexions d'une pas douée en javascript qui a essayé quand même :
BREF,
tout ça pour dire que je ne suis pas sûre que mon code soit vraiment efficace, j'ai conscience qu'il faudra sûrement de toute façon tout refaire, mais si on pouvait au moins m'éclairer sur ce dernier point qui reste pour moi un mystère, ça serait super....
Ma page html actuelle :
https://mllealys2.forumactif.org/h16-chargement-sujet-entier
mon fabuleux code de cette page :
J'ai testé sur différents sujets de mon forum test et d'autres forums à gauche à droite, dont par exemple ceux-ci, qui ne sont pas trop personnalisés :
EDIT :
- J'avais également pensé à la possibilité d'avoir un bouton pour pouvoir, à la fin du chargement, copier tout le contenu du sujet d'un coup, ou au moins tout sélectionner ; mais pareil c'est du bonus auquel je n'ai même pas encore réfléchi ! xP
J'essayais aussi de faire une sorte de formulaire sur une page html de mon forum test !
Et... bon... clairement pour l'instant sans succès, le javascript c'est toujours pas mon truc, je galère, j'ai l'impression d'écrire des trucs hyper moches et peu efficaces, je ne sais pas me servir de la console et je me retrouve à ajouter des alert() à chaque nouvelle ligne pour voir si ça fonctionne !
Ton aide sera la bienvenue !
Je souhaite pouvoir récupérer le titre du sujet, le sondage s'il y en a un, le contenu des messages avec le pseudo du posteur ;
Si possible sans signature, et pour les champs du profil à vrai dire j'ai hésité mais j'ai finalement choisi non !
Attention, réflexions d'une pas douée en javascript qui a essayé quand même :
- Première étape de ma réflexion : réussir à charger les éléments de la première page donnée :
- souhaitant possiblement l'utiliser sur plusieurs forums, je me suis dit que soit il fallait que le code soit capable de reconnaitre ces éléments sur la page de lui même, quelque soit les possibles personnalisations du forum.... soit, étant incapable de faire cette première possibilité, j'allais lui donner moi même les sélecteurs des éléments en question ! xD Donc j'ai fait un formulaire avec différents champs pour le lien, le sélecteur de la pagination, celui du titre, des messages, et des pseudos (pré-remplis avec les sélecteurs de mon forum test).
- je souhaitais au départ faire sur une page html vierge, mais sans jquery et ne sachant pas comment intégrer cette bibliothèque, j'ai finalement opté par défaut pour une page html avec le haut et le bas de mon forum test.
- j'ai utilisé la fonction load(), mais je ne savais pas s'il valait mieux charger chaque élément dans le bloc voulu, ou bien charger en une seule fois toute la page puis redistribué les éléments dans les blocs voulus... J'ai opté pour la première version, mais je ne sais pas tellement si ça ralenti beaucoup ou pas.
- quand il s'agit de charger un seul élément dans une div cible tout va bien (genre le titre), mais pour ce qui est des messages + pseudos, pour l'instant il me met ça en vrac, dans l'ordre dans lequel il les a trouvés sur la page (donc si les profils sont à droite des messages, il affiche le pseudo après le message). Je ne sais pas s'il y a un moyen de "trier" chaque élément pour les placer et les encadrer de balises ; j'imagine que oui, mais dans ce cas j'imagine qu'il faudrait plutôt passer par un chargement complet de la page avant de pouvoir redistribuer les éléments obtenus ?
En vrai, j'aimerais pouvoir appliquer une mise en forme extrêmement simple (mais pour l'instant ça dépend justement des sélecteurs du forum du sujet), et avoir le pseudo avant le message (ou à côté), mais ça reste de la mise en forme et du bonus pour moi xD - je me suis demandé si c'était possible de faire un message d'erreur quand il n'y a pas d'accès au sujet (manque de permission ou besoin de se connecter) et... je me suis dit que ce serai également du bonus à la fin ! xP
Deuxième étape de ma réflexion : charger les pages suivantes : - J'ai bien réussi je pense à récupérer la pagination, à récupérer à partir de celle-ci le nombre de pages.
- j'ai utilisé split() pour récupérer seulement le début du lien, jusqu'au numéro du sujet
j'ai ajouté manuellement dans ma boucle pour chaque page le "p" avec le nombre de messages par page (que j'ai également mis dans le formulaire, parce que avec les contenus sponsorisés etc, je ne savais pas comment le retrouver automatiquement).
Jusque là tout allait bien, j'avais bien les différents liens de toutes les pages du sujet. - Je me suis demandé si je devais charger toutes les pages dans une variable et les afficher seulement à la fin, ou bien les afficher au fur et à mesure. en parallèle, je ne savais pas comment ajouter mon contenu à la suite de la première page plutôt que de remplacer tout le contenu. J'ai croisé la fonction get(), j'ai essayé, ça n'a rien donné... Du coup j'ai contourné le problème en créant un nouveau bloc pour chaque nouvelle page, je me suis dit que c'était pas plus mal pour une possible mise en forme future
- j'ai tenté de charger donc toujours avec load dans chacun de ces blocs. J'ai bien les blocs. Je peux écrire dedans avec html(). Mais le load ne fonctionne pas.
Je me suis demandée si ça pouvait venir du fait que le lien était "incomplet", dans le titre du sujet.
Je me suis dit qu'à cela ne tienne, je récupère mon lien split, j'ajoute mon petit bout, et je reforme mon lien complet à nouveau à partir de là !
Pour éviter que les numéros de pages ne s'accumulent plutôt que de se remplacer, j'ai utilisé deux variables, une pour garder le lien de départ de côté, l'autre pour ajouter à chaque itération de ma boucle le numéro de page.
ET LA, LA !!!!! Je ne comprends pas !! ça ne fonctionne pas, ma première variable est modifiée en même temps que la deuxième et ça me parait tellement illogique que je bloque complètement ! j'ai essayé de tourner mon code de toutes les façons imaginables, rentrer ou sortir les variables de la boucle, réinitialiser à chaque fois, générer le lien à partir de la première, de la deuxième, j'ai mis des alert partout pour tenter de comprendre, rien n'y fait, alors que c'est précisément ce que je veux éviter, les numéros de pages s'accumulent au lieu d'être remplacés !!
Je ne comprends pas !!
BREF,
tout ça pour dire que je ne suis pas sûre que mon code soit vraiment efficace, j'ai conscience qu'il faudra sûrement de toute façon tout refaire, mais si on pouvait au moins m'éclairer sur ce dernier point qui reste pour moi un mystère, ça serait super....
Ma page html actuelle :
https://mllealys2.forumactif.org/h16-chargement-sujet-entier
mon fabuleux code de cette page :
- Code:
<script>
function charger() {
//chargement des éléments
//lien
var lien = document.getElementById("liensujet").value;
//charger titre
var selecttitre = document.getElementById("selecttitre").value;
$("#sujettitre").load( lien + " " + selecttitre );
//sondage
$("#sondage").load( lien + " table.poll-result" );
//pseudos
var selectpseudo = document.getElementById("selectpseudo").value;
if(selectpseudo != ""){ selectpseudo = " " + selectpseudo };
//messages
var selectmsg = document.getElementById("selectmsg").value;
if(selectmsg != ""){ selectmsg = ", " + selectmsg };
//charger le rp
$("#sujetcontenu").load( lien + selectpseudo + selectmsg );
//charger pagination
var selectpag = document.getElementById("selectpag").value;
$("#pagination").load( lien + " " + selectpag , function(){
//tester pagination
var pages = $('#pagination').text();
if ( pages == "") { alert("Pas d\'autres pages trouvées."); $('#pagination').text("Pas d\'autres pages trouvées.");}
else {
// s'il y a d'autres pages
$('#pagination img').parent().remove();
var nbpages = parseInt($('#pagination a:last-child').text());
if( confirm( nbpages + " autres pages ont été trouvées ! Les charger ?") !=true){return;};
// chargement des pages
var increment = parseInt( document.getElementById("increment").value );
lien = lien.split('-');
for( var i=1; i < nbpages ; i++ ) {
var page = lien ;
page[0] = page[0] + "p" + increment * i ;
page = page.join('-');
alert ( page );
var num = i + 1 ;
var blocsuite = '<div id="p' + num + '"></div>';
$("#sujet").append( blocsuite );
$("#sujet>div:last-child").html( "load page " + num );
delete page ;
}; //fin du for
}; // fin du else
}); // fin du load pagination
}; // fin de la fonction du bouton
</script>
<form>
<input type="url" placeholder="lien du sujet" value="" id="liensujet" name="liensujet" />
<input type="text" placeholder="sélecteur pagination" value="td.pagination span.gensmall" id="selectpag" />
<input type="text" placeholder="nombre de posts par page" value="5" id="increment" />
<input type="text" placeholder="sélecteur titre du rp" value=".catHead h1" id="selecttitre" />
<input type="text" placeholder="sélecteur pseudo" value=".post .name" id="selectpseudo" />
<input type="text" placeholder="sélecteur message" value="tr.post .postbody" id="selectmsg" />
<button type="button" onclick="charger();">Charger le sujet !</button>
</form>
<div id="pagination"></div>
<div id="sujet">
<div id="sujettitre"></div>
<div id="sondage"></div>
<div id="sujetcontenu"></div>
</div>
<style>
form {
border: 2px solid black;
padding: 10px;
text-align: center;
font-size: 14px;
font-weight: bold;
margin: 10px;
}
#page-body form input {
display: block;
margin: 10px auto;
width:250px;
}
#pagination {
text-align: center;
border: 1px solid black;
padding: 10px;
margin: 10px;
}
#sujet {
border: 1px solid black;
padding: 10px;
margin: 10px;
overflow: auto;
max-height: 500px;
}
div#sujettitre, div#sujettitre * {
text-align: center;
font-size: 18px;
margin-bottom: 25px;
text-decoration: underline;
}
</style>
J'ai testé sur différents sujets de mon forum test et d'autres forums à gauche à droite, dont par exemple ceux-ci, qui ne sont pas trop personnalisés :
EDIT :
- J'avais également pensé à la possibilité d'avoir un bouton pour pouvoir, à la fin du chargement, copier tout le contenu du sujet d'un coup, ou au moins tout sélectionner ; mais pareil c'est du bonus auquel je n'ai même pas encore réfléchi ! xP
MlleAlys- Membre actif
- Messages : 5967
Inscrit(e) le : 12/09/2012
Re: Enregistrer ou imprimer toutes les pages d'un sujet
Le code est plutôt pas mal, pas de gros problème (même si en effet, j'ai eu envie de tout réécrire ).
Le seul défaut que je vois, c'est que chaque load redemande à charger une page. La récupération du titre charge une page, la récupération du sondage charge une page, la récupération des sujets/contenus charge une page... tout ça alors qu'au final, en chargeant la page une fois et en piochant dedans, on s'épargne quelques chargements.
1) Alors, j'ai gardé la logique des inputs pour rentrer les infos qu'on veut, j'en ai retiré une (le nombre de messages par pages) et j'en ai ajouté une (le code d'un message dans lequel on pourra trouver le pseudo et le contenu).
2) Pour pouvoir utiliser le jquery, il suffirait de rajouter la ligne suivante avant les scripts qui utilisent du jquery :
3) A la place des load, on va utiliser un fetch. Ça permet de récupérer le texte d'une page, qu'on convertit ensuite en Object HTML.
4) Puisqu'on passe maintenant par des posts plutôt que des pseudos ou des messages, on boucle sur les posts, et on récupère les pseudos puis les messages. Comme ça, on aura toujours le bon ordre :
5) A voir, il faudrait rajouter un peu de code, vérifier qu'est-ce qui s'affiche dans toutes les versions. Effectivement, pour l'instant, je pense que le script va planter.
Ça pourra être une amélioration, c'est pas grave.
6) Je fais ça un peu plus simplement, en regardant l'avant dernier lien numéroté dans la zone pagination. Avant dernier, parce que le dernier, c'est la flèche pour aller à la page suivante, mais moi, je cherche à savoir le nombre de pages :
7) Pareil, j'ai repris le code. J'utilise juste posts.length pour avoir le nombre de posts par page, c'est pour ça que je n'ai pas besoin d'input avec cette information.
8 et 9) J'ai décidé de charger les pages les unes à la suite des autres, et de reprendre le principe de la récupération des posts, des pseudos et des messages. Je suis obligé d'écrire le fetch un peu différemment pour que le JavaScript ne fasse pas les chargements de toutes les pages en parallèle (ce qu'il ferait si on ne lui disait rien), avec un await. On part peut-être dans du "un peu plus compliqué à comprendre et à refaire", mais ce que ça veut dire, c'est qu'il va attendre la fin du chargement de la page 2 avant de commencer celui de la page 3, et ainsi de suite.
Conclusion :
Et voilà, tout charge en même temps et tout s'affiche dans le bon ordre, si je n'ai pas oublié des cas ni fait trop de bêtises...
Désolé par contre, pour le point mystère, je n'arrive pas trop à me rendre compte...
Voilà le code final, une page HTML à éditer en "Modification en mode avancé" pour plus de propreté !
Le seul défaut que je vois, c'est que chaque load redemande à charger une page. La récupération du titre charge une page, la récupération du sondage charge une page, la récupération des sujets/contenus charge une page... tout ça alors qu'au final, en chargeant la page une fois et en piochant dedans, on s'épargne quelques chargements.
1) Alors, j'ai gardé la logique des inputs pour rentrer les infos qu'on veut, j'en ai retiré une (le nombre de messages par pages) et j'en ai ajouté une (le code d'un message dans lequel on pourra trouver le pseudo et le contenu).
2) Pour pouvoir utiliser le jquery, il suffirait de rajouter la ligne suivante avant les scripts qui utilisent du jquery :
- Code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
3) A la place des load, on va utiliser un fetch. Ça permet de récupérer le texte d'une page, qu'on convertit ensuite en Object HTML.
- Code:
// Chargement de la première page
const response = await fetch(lien);
const html = await response.text();
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
4) Puisqu'on passe maintenant par des posts plutôt que des pseudos ou des messages, on boucle sur les posts, et on récupère les pseudos puis les messages. Comme ça, on aura toujours le bon ordre :
- Code:
const posts = doc.querySelectorAll(selectpost);
posts.forEach(function(post) {
const pseudo = post.querySelector(selectpseudo);
const contenu = post.querySelector(selectmsg);
document.getElementById('sujetcontenu').appendChild(pseudo);
document.getElementById('sujetcontenu').appendChild(contenu);
});
5) A voir, il faudrait rajouter un peu de code, vérifier qu'est-ce qui s'affiche dans toutes les versions. Effectivement, pour l'instant, je pense que le script va planter.
Ça pourra être une amélioration, c'est pas grave.
6) Je fais ça un peu plus simplement, en regardant l'avant dernier lien numéroté dans la zone pagination. Avant dernier, parce que le dernier, c'est la flèche pour aller à la page suivante, mais moi, je cherche à savoir le nombre de pages :
- Code:
// Récupération du nombre de pages du sujet
let nbPages = 1;
const pagination = doc.querySelector(selectpag + ' a:nth-last-child(2)');
if (pagination){
nbPages = pagination.innerText;
}
7) Pareil, j'ai repris le code. J'utilise juste posts.length pour avoir le nombre de posts par page, c'est pour ça que je n'ai pas besoin d'input avec cette information.
8 et 9) J'ai décidé de charger les pages les unes à la suite des autres, et de reprendre le principe de la récupération des posts, des pseudos et des messages. Je suis obligé d'écrire le fetch un peu différemment pour que le JavaScript ne fasse pas les chargements de toutes les pages en parallèle (ce qu'il ferait si on ne lui disait rien), avec un await. On part peut-être dans du "un peu plus compliqué à comprendre et à refaire", mais ce que ça veut dire, c'est qu'il va attendre la fin du chargement de la page 2 avant de commencer celui de la page 3, et ainsi de suite.
- Code:
// Chargement d'une nouvelle page
await fetch(lienPage).then(function (response) {
return response.text();
}).then(function (htmlPage) {
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parserPage = new DOMParser();
const docPage = parserPage.parseFromString(htmlPage, 'text/html');
// Récupération des pseudos et messages
docPage.querySelectorAll(selectpost).forEach(function(postPage) {
const pseudoPage = postPage.querySelector(selectpseudo);
const contenuPage = postPage.querySelector(selectmsg);
document.getElementById('sujetcontenu').appendChild(pseudoPage);
document.getElementById('sujetcontenu').appendChild(contenuPage);
});
});
Conclusion :
Et voilà, tout charge en même temps et tout s'affiche dans le bon ordre, si je n'ai pas oublié des cas ni fait trop de bêtises...
Désolé par contre, pour le point mystère, je n'arrive pas trop à me rendre compte...
Voilà le code final, une page HTML à éditer en "Modification en mode avancé" pour plus de propreté !
- Code:
<!DOCTYPE html>
<html lang="fr" xml:lang="fr">
<head>
<meta charset="UTF-8" />
<title>Mon récupérateur de texte</title>
<style>
form {
border: 2px solid black;
padding: 10px;
text-align: center;
font-size: 14px;
font-weight: bold;
margin: 10px;
}
#page-body form input {
display: block;
margin: 10px auto;
width:250px;
}
#pagination {
text-align: center;
border: 1px solid black;
padding: 10px;
margin: 10px;
}
#sujet {
border: 1px solid black;
padding: 10px;
margin: 10px;
overflow: auto;
max-height: 500px;
}
div#sujettitre, div#sujettitre * {
text-align: center;
font-size: 18px;
margin-bottom: 25px;
text-decoration: underline;
}
.postbody {
margin-bottom: 10px;
}
</style>
</head>
<body>
<form>
<input type="url" placeholder="lien du sujet" value="" id="liensujet" name="liensujet" />
<input type="text" placeholder="sélecteur pagination" value="td.pagination span.gensmall" id="selectpag" />
<input type="text" placeholder="sélecteur titre du rp" value=".catHead h1" id="selecttitre" />
<input type="text" placeholder="sélecteur post" value="tr.post" id="selectpost" />
<input type="text" placeholder="sélecteur pseudo" value=".name" id="selectpseudo" />
<input type="text" placeholder="sélecteur message" value=".postbody" id="selectmsg" />
<button type="button" onclick="charger();">Charger le sujet !</button>
</form>
<div id="pagination"></div>
<div id="sujet">
<div id="sujettitre"></div>
<div id="sondage"></div>
<div id="sujetcontenu"></div>
</div>
<script>
/**
* Chargement de la première page
*/
async function charger() {
// Lien
const lien = document.getElementById("liensujet").value;
const selectpag = document.getElementById("selectpag").value;
const selecttitre = document.getElementById("selecttitre").value;
const selectpost = document.getElementById("selectpost").value;
const selectpseudo = document.getElementById("selectpseudo").value;
const selectmsg = document.getElementById("selectmsg").value;
// Chargement de la première page
const response = await fetch(lien);
const html = await response.text();
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
// Récupération du titre du sujet
document.getElementById('sujettitre').replaceChildren();
const titre = doc.querySelector(selecttitre);
document.getElementById('sujettitre').appendChild(titre);
// Récupération du sondage du sujet
document.getElementById('sondage').replaceChildren();
const sondage = doc.querySelector('table.poll-result');
if (sondage){
document.getElementById('sondage').appendChild(sondage);
}
// Récupération des pseudos et messages
document.getElementById('sujetcontenu').replaceChildren();
const posts = doc.querySelectorAll(selectpost);
posts.forEach(function(post) {
console.log(post);
const pseudo = post.querySelector(selectpseudo);
const contenu = post.querySelector(selectmsg);
document.getElementById('sujetcontenu').appendChild(pseudo);
document.getElementById('sujetcontenu').appendChild(contenu);
});
// Récupération du nombre de pages du sujet
let nbPages = 1;
const pagination = doc.querySelector(selectpag + ' a:nth-last-child(2)');
if (pagination){
nbPages = pagination.innerText;
}
// Récupération du contenu des autres pages
for (let i = 1; i < nbPages; i++){
let lienPage = lien.split('-');
lienPage[0] = lienPage[0] + "p" + (posts.length * i);
lienPage = lienPage.join('-');
// Chargement d'une nouvelle page
await fetch(lienPage).then(function (response) {
return response.text();
}).then(function (htmlPage) {
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parserPage = new DOMParser();
const docPage = parserPage.parseFromString(htmlPage, 'text/html');
// Récupération des pseudos et messages
docPage.querySelectorAll(selectpost).forEach(function(postPage) {
const pseudoPage = postPage.querySelector(selectpseudo);
const contenuPage = postPage.querySelector(selectmsg);
document.getElementById('sujetcontenu').appendChild(pseudoPage);
document.getElementById('sujetcontenu').appendChild(contenuPage);
});
});
}
}
</script>
</body>
</html>
Re: Enregistrer ou imprimer toutes les pages d'un sujet
Déjà avec de html et du css ça me fait cet effet là, alors avec du javascript j'imagine encore plus !(même si en effet, j'ai eu envie de tout réécrire Razz)
Oh la la faut que je la garde quelque part celle là, merci !Pour pouvoir utiliser le jquery, il suffirait de rajouter la ligne suivante avant les scripts qui utilisent du jquery :
J'avais également pensé à ça, mais les pubs qui sont affichées parfois en fin de page comme un message (avec même un .postbody), et qui du coup sont aussi importées avec mon code d'essai, m'ont fait peur... C'est pour ça que j'ai contourné le problème avec le input : Pourquoi ici n'est-ce pas un souci ? Ne devraient-ils pas être comptabilisés également, et fausser le nombre de messages sur la page ?J'utilise juste posts.length pour avoir le nombre de posts par page
Oh, ça c'est une difficulté que je rencontre souvent avec le javascript !! Il va falloir que je creuse ça ! **pour que le JavaScript ne fasse pas les chargements de toutes les pages en parallèle (ce qu'il ferait si on ne lui disait rien), avec un await
Alors, déjà tout le reste, je comprends les grandes lignes, mais dans les détails je ne comprends pas tout, et je serais bien incapable de refaire ! Je viens de découvrir (ou redécouvrir pour certaines ?) des choses comme "const", "let", "querySelectorAll".... J'ai du boulot !"un peu plus compliqué à comprendre et à refaire"
(Ah bon, parce qu'il existe un autre mode ? )à éditer en "Modification en mode avancé"
Merci beaucoup pour ton aide ! ça semble bien fonctionner, et je crois que jamais je n'aurais réussi à obtenir un résultat aussi efficace par moi même !
- si je veux, pour des envies de mise en forme, insérer chaque pseudo et messages dans des balises spécifiques ou leur appliquer une class chacun (et du coup avoir un css qui ne dépendrait pas de la personnalisation du forum d'origine du sujet), est-ce faisable facilement ? Où est-ce que je peux l'insérer dans le code ? J'ai essayé à quelques endroits mais chaque fois ça a tout cassé
EDIT : ou alors modifier le sélecteur du css en fonction de celui indiqué dans les input ?
- sur mon forum test, aucun problème, mais lorsque j'essaye avec la deuxième adresse proposée dans mon message précédent, il y a un souci d'affichage des caractères avec accents ?
J'ai prérempli les input avec le sujet en question ici : https://mllealys2.forumactif.org/h17-charger-contenu-sujet-entier
Merci encore pour ton aide !
EDIT :
J'ai une nouvelle question !
Quand on fait "imprimer" la page, en tout cas avec chrome, on peut avec en option des en-tête et le pied de page : Il contiennent sur ce navigateur la date, l'adresse du site, le titre de la page web, le numéro de page de l'impression...
Sont-ils définis par le navigateur ? Peut-on les définir dans la page elle même ?
MlleAlys- Membre actif
- Messages : 5967
Inscrit(e) le : 12/09/2012
Re: Enregistrer ou imprimer toutes les pages d'un sujet
Effectivement, je n'avais pas pensé au contenu sponsorisé...
Si on regarde, c'est toujours le .post--0, donc pour ne pas le sélectionner, on peut juste modifier le sélecteur post :
Pour tout ce qui est pseudo et message, on peut ajouter des nouvelles class si on veut, oui, on procède comme ceci en JavaScript natif, et on le place comme ceci :
Alors, pour les caractères spéciaux, ça vient du fait que notre page est encodée en utf-8 alors que la page à charger est encodée en windows-1252. Là comme ça, je ne sais pas pourquoi, sachant que je teste avec un forum en phpbb2 et qu'il est bien en utf-8 (sûrement une question de date de création du forum, tout est en utf-8 partout maintenant). Du coup, il va falloir modifier des choses et en rajouter d'autres :
- on rajoute un input avec l'encodage de la page à charger (c'est un peu pénible, parce qu'il faut chercher l'encodage de la page en question, ce sera windows-1252 pour l'exemple de ce lien)
- on modifie le code des fetch pour rajouter un Decoder, qui va s'occuper de convertir le format indiqué vers utf-8
J'ai intercalé un const buffer = await response.arrayBuffer(); et les lignes du decoder.
Ça fait pas mal de modifications, donc voilà ce que donne le script final :
Pour les entêtes et numéro de pages, oui, c'est le navigateur qui les rajoute. Il doit y avoir un bouton pour les afficher ou non d'ailleurs. Quant à afficher autre chose, à priori oui, c'est possible, j'ai trouvé ceci qui explique comment faire par exemple : https://prograide.com/pregunta/77663/en-tete-et-pied-de-page-dimpression-html
Si on regarde, c'est toujours le .post--0, donc pour ne pas le sélectionner, on peut juste modifier le sélecteur post :
- Code:
<input type="text" placeholder="sélecteur post" value="tr.post:not(.post--0)" id="selectpost" />
Pour tout ce qui est pseudo et message, on peut ajouter des nouvelles class si on veut, oui, on procède comme ceci en JavaScript natif, et on le place comme ceci :
- Code:
let pseudo = post.querySelector(selectpseudo);
let contenu = post.querySelector(selectmsg);
pseudo.classList.add('maNouvelleClassPseudo');
contenu.classList.add('maNouvelleClassContenu');
document.getElementById('sujetcontenu').appendChild(pseudo);
document.getElementById('sujetcontenu').appendChild(contenu);
Alors, pour les caractères spéciaux, ça vient du fait que notre page est encodée en utf-8 alors que la page à charger est encodée en windows-1252. Là comme ça, je ne sais pas pourquoi, sachant que je teste avec un forum en phpbb2 et qu'il est bien en utf-8 (sûrement une question de date de création du forum, tout est en utf-8 partout maintenant). Du coup, il va falloir modifier des choses et en rajouter d'autres :
- on rajoute un input avec l'encodage de la page à charger (c'est un peu pénible, parce qu'il faut chercher l'encodage de la page en question, ce sera windows-1252 pour l'exemple de ce lien)
- on modifie le code des fetch pour rajouter un Decoder, qui va s'occuper de convertir le format indiqué vers utf-8
- Code:
// Chargement de la première page
const response = await fetch(lien);
const buffer = await response.arrayBuffer();
// On convertit le format vers utf-8
const decoder = new TextDecoder(selectencodage);
const html = decoder.decode(buffer);
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
J'ai intercalé un const buffer = await response.arrayBuffer(); et les lignes du decoder.
Ça fait pas mal de modifications, donc voilà ce que donne le script final :
- Code:
<!DOCTYPE html>
<html lang="fr" xml:lang="fr">
<head>
<meta charset="UTF-8" />
<title>Mon récupérateur de texte</title>
<style>
form {
border: 2px solid black;
padding: 10px;
text-align: center;
font-size: 14px;
font-weight: bold;
margin: 10px;
}
#page-body form input {
display: block;
margin: 10px auto;
width:250px;
}
#pagination {
text-align: center;
border: 1px solid black;
padding: 10px;
margin: 10px;
}
#sujet {
border: 1px solid black;
padding: 10px;
margin: 10px;
overflow: auto;
max-height: 500px;
}
div#sujettitre, div#sujettitre * {
text-align: center;
font-size: 18px;
margin-bottom: 25px;
text-decoration: underline;
}
.postbody {
margin-bottom: 10px;
}
</style>
</head>
<body>
<form>
<input type="url" placeholder="lien du sujet" value="" id="liensujet" name="liensujet" />
<input type="text" placeholder="sélecteur encodage" value="utf-8" id="selectencodage" />
<input type="text" placeholder="sélecteur pagination" value="td.pagination span.gensmall" id="selectpag" />
<input type="text" placeholder="sélecteur titre du rp" value=".catHead h1" id="selecttitre" />
<input type="text" placeholder="sélecteur post" value="tr.post:not(.post--0)" id="selectpost" />
<input type="text" placeholder="sélecteur pseudo" value=".name" id="selectpseudo" />
<input type="text" placeholder="sélecteur message" value=".postbody" id="selectmsg" />
<button type="button" onclick="charger();">Charger le sujet !</button>
</form>
<div id="pagination"></div>
<div id="sujet">
<div id="sujettitre"></div>
<div id="sondage"></div>
<div id="sujetcontenu"></div>
</div>
<script>
/**
* Chargement de la première page
*/
async function charger() {
// Lien
const lien = document.getElementById("liensujet").value;
const selectencodage = document.getElementById("selectencodage").value;
const selectpag = document.getElementById("selectpag").value;
const selecttitre = document.getElementById("selecttitre").value;
const selectpost = document.getElementById("selectpost").value;
const selectpseudo = document.getElementById("selectpseudo").value;
const selectmsg = document.getElementById("selectmsg").value;
// Chargement de la première page
const response = await fetch(lien);
const buffer = await response.arrayBuffer();
// On convertit le format vers utf-8
const decoder = new TextDecoder(selectencodage);
const html = decoder.decode(buffer);
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
// Récupération du titre du sujet
document.getElementById('sujettitre').replaceChildren();
const titre = doc.querySelector(selecttitre);
document.getElementById('sujettitre').appendChild(titre);
// Récupération du sondage du sujet
document.getElementById('sondage').replaceChildren();
const sondage = doc.querySelector('table.poll-result');
if (sondage){
document.getElementById('sondage').appendChild(sondage);
}
// Récupération des pseudos et messages
document.getElementById('sujetcontenu').replaceChildren();
const posts = doc.querySelectorAll(selectpost);
posts.forEach(function(post) {
const pseudo = post.querySelector(selectpseudo);
const contenu = post.querySelector(selectmsg);
pseudo.classList.add('maNouvelleClassPseudo');
contenu.classList.add('maNouvelleClassContenu');
document.getElementById('sujetcontenu').appendChild(pseudo);
document.getElementById('sujetcontenu').appendChild(contenu);
});
// Récupération du nombre de pages du sujet
let nbPages = 1;
const pagination = doc.querySelector(selectpag + ' a:nth-last-child(2)');
if (pagination){
nbPages = pagination.innerText;
}
// Récupération du contenu des autres pages
for (let i = 1; i < nbPages; i++){
let lienPage = lien.split('-');
lienPage[0] = lienPage[0] + "p" + (posts.length * i);
lienPage = lienPage.join('-');
// Chargement d'une nouvelle page
await fetch(lienPage).then(function (response) {
return response.arrayBuffer();
}).then(function (bufferPage) {
// On convertit le format vers utf-8
const decoderPage = new TextDecoder(selectencodage);
const htmlPage = decoder.decode(bufferPage);
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parserPage = new DOMParser();
const docPage = parserPage.parseFromString(htmlPage, 'text/html');
// Récupération des pseudos et messages
docPage.querySelectorAll(selectpost).forEach(function(postPage) {
const pseudoPage = postPage.querySelector(selectpseudo);
const contenuPage = postPage.querySelector(selectmsg);
pseudoPage.classList.add('maNouvelleClassPseudo');
contenuPage.classList.add('maNouvelleClassContenu');
document.getElementById('sujetcontenu').appendChild(pseudoPage);
document.getElementById('sujetcontenu').appendChild(contenuPage);
});
});
}
}
</script>
</body>
</html>
Pour les entêtes et numéro de pages, oui, c'est le navigateur qui les rajoute. Il doit y avoir un bouton pour les afficher ou non d'ailleurs. Quant à afficher autre chose, à priori oui, c'est possible, j'ai trouvé ceci qui explique comment faire par exemple : https://prograide.com/pregunta/77663/en-tete-et-pied-de-page-dimpression-html
Re: Enregistrer ou imprimer toutes les pages d'un sujet
ça fonctionne superbement bien !! Merci Toryudo !!
Pour ce qui est des en-têtes et footers, j'avais effectivement vu cette page, je creuserai ça un jour pour savoir s'il est possible d'afficher également le numéro de page (ce que j'ai testé pour l'instant n'a pas fonctionné).
Donc pour l'instant je le passe dans la liste des "bonus possibles un jour peut-être" !
Merci encore pour tout ! Je passe le sujet en résolu !
Mon code actuel avec un peu de bidouillage css (pas sûre que ce soit très propre cela dit ^^") pour ceux que cela intéresserait (les champs sont préremplis avec les sélecteurs par défaut pour phpbb2) :
Pour ce qui est des en-têtes et footers, j'avais effectivement vu cette page, je creuserai ça un jour pour savoir s'il est possible d'afficher également le numéro de page (ce que j'ai testé pour l'instant n'a pas fonctionné).
Donc pour l'instant je le passe dans la liste des "bonus possibles un jour peut-être" !
Merci encore pour tout ! Je passe le sujet en résolu !
Mon code actuel avec un peu de bidouillage css (pas sûre que ce soit très propre cela dit ^^") pour ceux que cela intéresserait (les champs sont préremplis avec les sélecteurs par défaut pour phpbb2) :
- Code:
<!DOCTYPE html>
<html lang="fr" xml:lang="fr">
<head>
<meta charset="UTF-8" />
<title>Mon récupérateur de sujet</title>
<style>
body {
margin: 1%;
}
form {
border: 2px solid black;
padding: 1rem 1%;
margin: 1rem 0;
position: sticky;
background: white;
top: 0;
}
#sujet {
border: 1px solid black;
padding: 1%;
}
#sujettitre, #sujettitre * {
text-align: center;
font-size: 2rem;
margin: 0;
text-decoration: underline;
}
h1#sujettitre {
margin: 1rem 1rem 3rem;
}
.poll-result {
margin-bottom: 2rem;
}
.pseudo, .pseudo * {
font-weight: bold;
text-decoration: underline;
}
.contenu {
margin: 1rem 0 2rem 3%;
}
.signature_div {
display: none;
}
.cont_code {
font-family: monospace;
}
.spoiler_content.hidden {
content-visibility: visible;
}
.spoiler_title {
font-weight: bold;
}
.codebox dd {
border-left: 1pt solid black;
padding-left: 0.5rem;
}
@media print {
form {
display: none;
}
#sujet {
border: 0;
max-height: unset;
}
}
</style>
</head>
<body>
<form>
<input type="url" placeholder="lien du sujet" value="" id="liensujet" name="liensujet" />
<select id="selectencodage"> <option value="utf-8">utf-8</option> <option value="windows-1252">windows-1252</option> </select>
<input type="text" placeholder="sélecteur pagination" value=".pagination span" id="selectpag" />
<input type="text" placeholder="sélecteur titre du rp" value="h1.cattitle" id="selecttitre" />
<input type="text" placeholder="sélecteur post" value="tr.post:not(.post--0)" id="selectpost" />
<input type="text" placeholder="sélecteur pseudo" value=".name" id="selectpseudo" />
<input type="text" placeholder="sélecteur message" value=".postbody" id="selectmsg" />
<button type="button" onclick="charger();">Charger le sujet !</button>
</form>
<div id="sujet">
<h1 id="sujettitre"></h1>
<div id="sondage"></div>
<div id="sujetcontenu"></div>
</div>
<script>
/**
* Chargement de la première page
*/
async function charger() {
// Lien
const lien = document.getElementById("liensujet").value;
const selectencodage = document.getElementById("selectencodage").value;
const selectpag = document.getElementById("selectpag").value;
const selecttitre = document.getElementById("selecttitre").value;
const selectpost = document.getElementById("selectpost").value;
const selectpseudo = document.getElementById("selectpseudo").value;
const selectmsg = document.getElementById("selectmsg").value;
// Chargement de la première page
const response = await fetch(lien);
const buffer = await response.arrayBuffer();
// On convertit le format vers utf-8
const decoder = new TextDecoder(selectencodage);
const html = decoder.decode(buffer);
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
// Récupération du titre du sujet
document.getElementById('sujettitre').replaceChildren();
const titre = doc.querySelector(selecttitre);
document.getElementById('sujettitre').appendChild(titre);
// Récupération du sondage du sujet
document.getElementById('sondage').replaceChildren();
const sondage = doc.querySelector('table.poll-result');
if (sondage){
document.getElementById('sondage').appendChild(sondage);
}
// Récupération des pseudos et messages
document.getElementById('sujetcontenu').replaceChildren();
const posts = doc.querySelectorAll(selectpost);
posts.forEach(function(post) {
const pseudo = post.querySelector(selectpseudo);
const contenu = post.querySelector(selectmsg);
pseudo.classList.add('pseudo');
contenu.classList.add('contenu');
document.getElementById('sujetcontenu').appendChild(pseudo);
document.getElementById('sujetcontenu').appendChild(contenu);
});
// Récupération du nombre de pages du sujet
let nbPages = 1;
const pagination = doc.querySelector(selectpag + ' a:nth-last-child(2)');
if (pagination){
nbPages = pagination.innerText;
}
// Récupération du contenu des autres pages
for (let i = 1; i < nbPages; i++){
let lienPage = lien.split('-');
lienPage[0] = lienPage[0] + "p" + (posts.length * i);
lienPage = lienPage.join('-');
// Chargement d une nouvelle page
await fetch(lienPage).then(function (response) {
return response.arrayBuffer();
}).then(function (bufferPage) {
// On convertit le format vers utf-8
const decoderPage = new TextDecoder(selectencodage);
const htmlPage = decoder.decode(bufferPage);
// On convertit le texte HTML reçu en Objet pour pouvoir le traiter
const parserPage = new DOMParser();
const docPage = parserPage.parseFromString(htmlPage, 'text/html');
// Récupération des pseudos et messages
docPage.querySelectorAll(selectpost).forEach(function(postPage) {
const pseudoPage = postPage.querySelector(selectpseudo);
const contenuPage = postPage.querySelector(selectmsg);
pseudoPage.classList.add('pseudo');
contenuPage.classList.add('contenu');
document.getElementById('sujetcontenu').appendChild(pseudoPage);
document.getElementById('sujetcontenu').appendChild(contenuPage);
});
});
}
}
</script>
</body>
</html>
MlleAlys- Membre actif
- Messages : 5967
Inscrit(e) le : 12/09/2012
Sujets similaires
» Modifier Enregistrer et Réinitialiser sur toutes les pages,
» Code js qui s'exécute sur un sujet précis et toutes ses pages
» [Sujet] Pouvoir imprimer un sujet/topic en .pdf dans son intégralité.
» Réactualisation de toutes les pages du forum toutes les 5 secondes
» pouvoir imprimer des sujet du forum par l' imprimante
» Code js qui s'exécute sur un sujet précis et toutes ses pages
» [Sujet] Pouvoir imprimer un sujet/topic en .pdf dans son intégralité.
» Réactualisation de toutes les pages du forum toutes les 5 secondes
» pouvoir imprimer des sujet du forum par l' imprimante
Forum gratuit : Le forum des forums actifs :: Entraide & Support... :: Problème divers :: Archives des problèmes divers
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum