Author Topic: поиск утерянных тем  (Read 56944 times)

0 Members and 1 Guest are viewing this topic.

Offline Bhudh

  • Posts: 52602
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
« Reply #300on: August 9, 2018, 21:40 »
У меня так и осталось на этой странице.  :donno:
Операции с DOM (Document Object Model), к которой относятся операции с перерисовкой страницы в результате — самые жутко тормозящие во всей инфрасфере JavaScript.
Ваши 45 тысяч сообщений могли вставляться несколько минут, и забитость памяти тоже наверняка была связана именно с этим.
А потом, видимо, действительно кончилась отпущенная конкретно браузеру квота памяти. :donno:
Кстати, в «Просмотре сообщений» видны только посты из разделов, к которым выкачивающий имеет доступ.
Так что посты из «Политики» я, к примеру, выкачать не могу.
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Red Khan

  • Global Moderator
  • *
  • Posts: 43726
  • Gender: Male
« Reply #301on: August 9, 2018, 23:50 »
Потом могу попробовать ещё только с этой открытой страницей.
Перезагрузил комп, открыл только эту страницу, оставил, когда уходил с работы. Сейчас вот по удалёнке подключился в консоле:
Code: [Select]
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://googleads.g.doubleclick.net/pagead/id. (Reason: CORS request did not succeed).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://googleads.g.doubleclick.net/pagead/id. (Reason: CORS request did not succeed).
Loading failed for the <script> with source “https://static.doubleclick.net/instream/ad_status.js”. HsF-flvBhoo:1
uncaught exception: out of memory

« Reply #302on: August 9, 2018, 23:51 »
Кстати, в «Просмотре сообщений» видны только посты из разделов, к которым выкачивающий имеет доступ.
Так что посты из «Политики» я, к примеру, выкачать не могу.
Да, это я знаю. Я, как модератор, вижу даже удалённые сообщения из "Мыла".

Offline Bhudh

  • Posts: 52602
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
« Reply #303on: August 10, 2018, 01:57 »
Code: [Select]
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://googleads.g.doubleclick.net/pagead/id. (Reason: CORS request did not succeed).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://googleads.g.doubleclick.net/pagead/id. (Reason: CORS request did not succeed).
Loading failed for the <script> with source “https://static.doubleclick.net/instream/ad_status.js”. HsF-flvBhoo:1
uncaught exception: out of memory
О-о, вот это проблема. Вместе с кодом постов при парсинге исполняется и всё окружающее, включая вызовы гугл-аналитики и прочих скриптов.
Можно попробовать просто вставить xhr.withCredentials = true; перед xhr.open, но не уверен, что поможет.

У меня-то вся эта аналитика и метрика жыстоко порезана прямо в hosts, поэтому такой проблемы не испытывал.
Offtop
Но у Валентина Н пару раз вылезала просьба зарегиться на каком-то имидж-хостинге, видимо, он случайно размещал ссылки на приватные изображения.
Впрочем, это так и так бы вылезло.
Придётся обрезать полученную страницу до приемлемого размера, включающего минимальное окружение постов, а потом парсить.
Получилось удивительно легко:
Code: [Select]
let lastUnparsedLink = document.querySelectorAll('.pagesection a')[document.querySelectorAll('.pagesection a').length-1];;
let postsSelector = '#main_admsection .topic';
let xhr = new XMLHttpRequest();
let parser = new DOMParser();
let postsFragment = document.createDocumentFragment();
let getLastUnparsedLink = doc => doc.querySelector('.pagesection strong').previousElementSibling;
let indexator = document.querySelector('.pagesection span').firstChild;
function addPosts(){
if(this.readyState == 4 && this.status == 200){
let answer = this.responseText;
let postsCodeBegin = answer.indexOf('<div id="content_section">');
let postsCodeEnd = answer.indexOf('<div id="footer_section">');
let postsCode = answer.slice(postsCodeBegin, postsCodeEnd);
let doc = parser.parseFromString(postsCode, 'text/html');
Array.from(doc.querySelectorAll(postsSelector)).reverse().forEach(
el => {
el.style.display = 'none';
postsFragment.insertBefore( el, postsFragment.firstChild );});
lastUnparsedLink = getLastUnparsedLink( doc );
if( !lastUnparsedLink ){
lastUnparsedLink = {
href: doc.URL.replace(/\d+$/, '0'),
textContent: '1'}}
setTimeout( _ => {
xhr.open('GET', lastUnparsedLink.href);
xhr.send();
indexator.textContent = lastUnparsedLink.textContent+' ';
if( !('firstChild' in lastUnparsedLink) ){
xhr.onreadystatechange = null;
postsCodeBegin = xhr.response.indexOf('<div id="content_section">');
postsCodeEnd = xhr.response.indexOf('<div id="footer_section">');
postsCode = xhr.response.slice(postsCodeBegin, postsCodeEnd);
doc = parser.parseFromString(postsCode, 'text/html');
let topics = document.querySelectorAll(postsSelector);
topics.forEach( el => el.textContent = '' );
Array.from(postsFragment.children).reverse().forEach( (el, index) => {
el.querySelector('.counter').textContent = index+1;
el.style.display = 'block';
});
topics[0].parentNode.insertBefore( postsFragment, null );
}}, 200);}}
xhr.onreadystatechange = addPosts;
xhr.withCredentials = true;
xhr.open('GET', lastUnparsedLink.href);
xhr.send();

Частоту запросов можно изменить выставлением значения переменной requestIntervalMs (здесь 200 миллисекунд). Вдруг хостер что-то нехорошее скажет, можно тогда сделать интервал побольше и скорость выкачивания, соответственно, поменьше.
Рекомендую сначала потестить на юзерах с небольшим числом сообщений — менее 100 страниц в профиле..
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

« Reply #304on: August 10, 2018, 02:25 »
Чуть-чуть недочистил код.
Апдейт:
Code: [Select]
let lastUnparsedLink = document.querySelectorAll('.pagesection a')[document.querySelectorAll('.pagesection a').length-1];;
let postsSelector = '#main_admsection .topic';
let xhr = new XMLHttpRequest();
let parser = new DOMParser();
let postsFragment = document.createDocumentFragment();
let getLastUnparsedLink = doc => doc.querySelector('.pagesection strong').previousElementSibling;
let indexator = document.querySelector('.pagesection span').firstChild;
function addPosts(){
if(this.readyState == 4 && this.status == 200){
let answer = this.responseText;
let postsCodeBegin = answer.indexOf('<div id="content_section">');
let postsCodeEnd = answer.indexOf('<div id="footer_section">');
let postsCode = answer.slice(postsCodeBegin, postsCodeEnd);
let doc = parser.parseFromString(postsCode, 'text/html');
Array.from(doc.querySelectorAll(postsSelector)).reverse().forEach(
el => {
el.style.display = 'none';
postsFragment.insertBefore( el, postsFragment.firstChild );});
lastUnparsedLink = getLastUnparsedLink( doc );
if( !lastUnparsedLink ){
lastUnparsedLink = {
href: doc.URL.replace(/\d+$/, '0'),
textContent: '1'}}
setTimeout( _ => {
xhr.open('GET', lastUnparsedLink.href);
xhr.send();
indexator.textContent = lastUnparsedLink.textContent+' ';
if( !('firstChild' in lastUnparsedLink) ){
xhr.onreadystatechange = null;
console.timeEnd('Request all posts');
let topics = document.querySelectorAll(postsSelector);
topics.forEach( el => el.textContent = '' );
Array.from(postsFragment.children).reverse().forEach( (el, index) => {
el.querySelector('.counter').textContent = index+1;
el.style.display = 'block';
});
topics[0].parentNode.insertBefore( postsFragment, null );
}}, 200);}}
xhr.onreadystatechange = addPosts;
xhr.withCredentials = true;
xhr.open('GET', lastUnparsedLink.href);
console.time('Request all posts');
xhr.send();

Можно даже не открывать консоль, а просто написать в адресной строке javascript: и после этого вставить код и нажать Enter.
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Валентин Н

  • Posts: 32954
  • Gender: Male
« Reply #305on: August 10, 2018, 23:38 »
Но у Валентина Н пару раз вылезала просьба зарегиться на каком-то имидж-хостинге, видимо, он случайно размещал ссылки на приватные изображения.
Впрочем, это так и так бы вылезло.
:what:
Нижниь ıндэкс в ҷıсʌах — степень тıсяҷı.
Препинания авторские!

Offline Red Khan

  • Global Moderator
  • *
  • Posts: 43726
  • Gender: Male
« Reply #306on: August 14, 2018, 19:27 »
Что-то я всё-таки не так делаю. Беру пользователя с 283 постами, счётчик заканчивается, в консоле появляется:
Code: [Select]
undefined
Request all posts: 4456ms
и всё, ничего не меняется. В Chromium также.

Беру пользователя с четыремя постами получаю
Code: [Select]
Error: lastUnparsedLink is undefinedХотя подозреваю это потому что там одна страница.

Заодно выяснил что кнопка "Выделить" в теге code не работает в FF, но работает в Chromium

« Reply #307on: August 14, 2018, 19:28 »
Можно даже не открывать консоль, а просто написать в адресной строке javascript: и после этого вставить код и нажать Enter.
В поисковик лезет. :) Это, видимо, у Вас тоже отключено.

Offline Bhudh

  • Posts: 52602
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
« Reply #308on: August 14, 2018, 19:49 »
Можно даже не открывать консоль, а просто написать в адресной строке javascript: и после этого вставить код и нажать Enter.
В поисковик лезет. :) Это, видимо, у Вас тоже отключено.
Э, нет, это не у меня, это у Вас протокол javascript: гадкими разрабами отключён! :negozhe:

Что-то я всё-таки не так делаю. Беру пользователя с 283 постами, счётчик заканчивается, в консоле появляется:
Code: [Select]
undefined
Request all posts: 4456ms
и всё, ничего не меняется. В Chromium также.
Странно. У меня FF ESR 52.7.4.
До запуска скрипта:


После запуска счёт инвертируется, все посты вставляются на страницу:


В консоли точно никаких ошибок не показывает?

Попробуйте такой вариант кода:
Code: [Select]
let lastUnparsedLink = document.querySelectorAll('.pagesection a')[document.querySelectorAll('.pagesection a').length-1];;
let postsSelector = '#main_admsection .topic';
let xhr = new XMLHttpRequest();
let parser = new DOMParser();
let postsFragment = document.createDocumentFragment();
let getLastUnparsedLink = doc => doc.querySelector('.pagesection strong').previousElementSibling;
let indexator = document.querySelector('.pagesection span').firstChild;
function addPosts(){
if(this.readyState == 4 && this.status == 200){
let answer = this.responseText;
let postsCodeBegin = answer.indexOf('<div id="content_section">');
let postsCodeEnd = answer.indexOf('<div id="footer_section">');
let postsCode = answer.slice(postsCodeBegin, postsCodeEnd);
let doc = parser.parseFromString(postsCode, 'text/html');
Array.prototype.slice.call(doc.querySelectorAll(postsSelector)).reverse().forEach(
el => {
el.style.display = 'none';
postsFragment.insertBefore( el, postsFragment.firstChild );});
lastUnparsedLink = getLastUnparsedLink( doc );
if( !lastUnparsedLink ){
lastUnparsedLink = {
href: doc.URL.replace(/\d+$/, '0'),
textContent: '1'}}
setTimeout( _ => {
xhr.open('GET', lastUnparsedLink.href);
xhr.send();
indexator.textContent = lastUnparsedLink.textContent+' ';
if( !('firstChild' in lastUnparsedLink) ){
xhr.onreadystatechange = null;
console.timeEnd('Request all posts');
let topics = document.querySelectorAll(postsSelector);
let allText = '';
topics.forEach( el => el.textContent = '' );
Array.prototype.slice.call(postsFragment.children).reverse().forEach( (el, index) => {
el.querySelector('.counter').textContent = index+1;
el.style.display = 'block';
allText += el.textContent;
});
console.log( '[[ All posts: ]] ', allText );
topics[0].parentNode.insertBefore( postsFragment, null );
}}, 200);}}
xhr.onreadystatechange = addPosts;
xhr.withCredentials = true;
xhr.open('GET', lastUnparsedLink.href);
console.time('Request all posts');
xhr.send();

Должен вывести то, что попало в парсер.
Если будет пустота, значит, что-то не то с разрешениями браузера, надо явно разрешить CORS-запросы в настройках.
Браузерня сейчас малость двинутая по теме безопасности, как будто каждый второй открытым текстом номера банковских карт вместе с пин-кодом пересылает.
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

« Reply #309on: August 14, 2018, 19:51 »
Заодно выяснил что кнопка "Выделить" в теге code не работает в FF, но работает в Chromium
А она работает как раз через псевдо-протокол:
Code: [Select]
<a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation">[Выделить]</a>
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Red Khan

  • Global Moderator
  • *
  • Posts: 43726
  • Gender: Male
« Reply #310on: August 14, 2018, 21:41 »
После запуска счёт инвертируется, все посты вставляются на страницу:
А слона-то я и не заметил. :fp:
Извините, работает всё, завтра попробую свои посты на рабочем компе запустить. Какую лучше версию скрипта запустить, последнюю или предпоследнюю?

Offline Bhudh

  • Posts: 52602
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
« Reply #311on: August 14, 2018, 22:13 »
Предпоследнюю, последняя с выводом полного списка постов ещё и в консоль, оно Вам надо? :)
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Red Khan

  • Global Moderator
  • *
  • Posts: 43726
  • Gender: Male
« Reply #312on: August 14, 2018, 22:29 »
Помню кто-то из умельцев форума (Тайльнемер?) делал дамп всех сообщений пользователя в один текстовый файл. Где это было и как это сделать никто не помнит?
Тема обнаружилась, но программа, к сожалению, не работает, видимо рассчитана на старый движок форума.
Корпус своих сообщений

Сообщения программы прочитать не могу, вместо них крякозябры

Offline Bhudh

  • Posts: 52602
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
« Reply #313on: August 15, 2018, 00:01 »
Сравнил время:

Написать простенькую программу на каком-нибудь языке программирования.
Я могу попробовать.
Вот, пожалуйста.
4 часа 19 минут. (Включая компиляцию и …?)
Размер сырцов: 5,18 КБ (Program.cs; вся папка с сырцами, выданная IDE: 569 КБ).

Сейчас мне надо уходить, но после работы попробую
Firefox исправно выкачивает все посты
4 часа 39 минут. (Включая выезд на заказ, ~1,5 часа.)
Размер сырцов: 1,72 КБ.

JS рулит ;D.
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Red Khan

  • Global Moderator
  • *
  • Posts: 43726
  • Gender: Male
« Reply #314on: August 15, 2018, 23:25 »
Сработал у меня скрипт на мои сообщения (выжрал, правда, 16 гигов памяти и ещё почти весь 8 гиговый swap). Но тут встал вопрос - а как, собственно, это богатство сохранить? Пробовал сохранить, но сохраняет он обычную страничку (ту, которую изначально получил), пробовал сделать Print Preview - вывел в консоле "uncaught exception: out of memory" и обнулил все результаты (самое последнее сообщение стало опять под номером 1).

Offline Bhudh

  • Posts: 52602
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
« Reply #315on: August 15, 2018, 23:45 »
Банальный копипаст путём Ctrl+A на страничку тоже не сработает?
Ну или по кускам, если буфер операционки тоже скажет Ой!

Offtop
Можно, правда, применить последнюю версию скрипта, заменив console.log( '[[ All posts: ]] ', allText ); на alert( '[[ All posts: ]] ', allText );, но тут браузер точно может сказать Ой!, да и копипастить в любом случае придётся.
А с File API как-то не приходилось работать… И неизвестно, как там с доступом к файловой системе в настройках браузера.
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

« Reply #316on: August 16, 2018, 00:21 »
Что-то я слишком пессимистичен. Вот этот код прекрасно работает. По окончании парсинга открывается окно (для этого надо разрешить всплывающие окна для ЛФ) и предлагается сохранить то, что накачалось.
Внутри HTML, так что можете назвать файл как угодно с расширением .html или .htm и смотреть посты в браузере или в Wordʼе. Без разметки, правда :green:.
Code: [Select]
let lastUnparsedLink = document.querySelectorAll('.pagesection a')[document.querySelectorAll('.pagesection a').length-1];;
let postsSelector = '#main_admsection .topic';
let xhr = new XMLHttpRequest();
let parser = new DOMParser();
let postsFragment = document.createDocumentFragment();
let getLastUnparsedLink = doc => doc.querySelector('.pagesection strong').previousElementSibling;
let indexator = document.querySelector('.pagesection span').firstChild;
function addPosts(){
if(this.readyState == 4 && this.status == 200){
let answer = this.responseText;
let postsCodeBegin = answer.indexOf('<div id="content_section">');
let postsCodeEnd = answer.indexOf('<div id="footer_section">');
let postsCode = answer.slice(postsCodeBegin, postsCodeEnd);
let doc = parser.parseFromString(postsCode, 'text/html');
Array.prototype.slice.call(doc.querySelectorAll(postsSelector)).reverse().forEach(
el => {
el.style.display = 'none';
postsFragment.insertBefore( el, postsFragment.firstChild );});
lastUnparsedLink = getLastUnparsedLink( doc );
if( !lastUnparsedLink ){
lastUnparsedLink = {
href: doc.URL.replace(/\d+$/, '0'),
textContent: '1'}}
setTimeout( _ => {
xhr.open('GET', lastUnparsedLink.href);
xhr.send();
indexator.textContent = lastUnparsedLink.textContent+' ';
if( !('firstChild' in lastUnparsedLink) ){
xhr.onreadystatechange = null;
console.timeEnd('Request all posts');
let topics = document.querySelectorAll(postsSelector);
let allText = '';
topics.forEach( el => el.textContent = '' );
Array.prototype.slice.call(postsFragment.children).reverse().forEach( (el, index) => {
el.querySelector('.counter').textContent = index+1;
el.style.display = 'block';
allText += el.outerHTML;
});
//console.log( '[[ All posts: ]] ', allText );
topics[0].parentNode.insertBefore( postsFragment, null );
location.href= URL.createObjectURL(new Blob([document.body.outerHTML], {type : 'application/octet-stream'}));
}}, 200);}}
xhr.onreadystatechange = addPosts;
xhr.withCredentials = true;
xhr.open('GET', lastUnparsedLink.href);
console.time('Request all posts');
xhr.send();
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Red Khan

  • Global Moderator
  • *
  • Posts: 43726
  • Gender: Male
« Reply #317on: September 5, 2018, 13:52 »
Вот этот код прекрасно работает.
Да, сработал и я даже нашёл нужное сообщение аж за июнь 2014-го год в "Языках и государствах".
Большое спасибо! ;up:

Offline Bhudh

  • Posts: 52602
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
« Reply #318on: September 5, 2018, 14:08 »
Вот и отлично, а то я уже забеспокоился :eat:.

Дело за малым: встроить этот функционал в форум, чтобы скачать все свои посты можно было одной кнопочкой (естественно, с выполнением всех действий по доставанию данных из базы на сервере).
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Online From_Odessa

  • Posts: 36529
  • Gender: Male
« Reply #319on: September 30, 2018, 13:28 »
Прошу прощения, а куда далась недавно созданная тема об анализе идей и терминологии Сергия? Была в "Просто общении".
Шансы есть всегда. Даже, когда их нет (с)
Многие думают, что футбол - это вопрос жизни и смерти. Ерунда. Футбол куда важнее (с) Б. Шенкли
Программирование - ещё один вид искусства (с) From_Odessa

Offline Python

  • Posts: 36331
  • Gender: Male
  • Aluarium agent
« Reply #320on: September 30, 2018, 22:13 »
Для поиска и голый HTML сгодится.
Сейчас сложнее всего работающий Downloadthemall найти.
Старые плагины не работают, новые не спешат появляться.
Под Linux'ом, конечно, можно обойтись командой wget.
Под Windows'ом не знаю, как такие вопросы решаются.
Есть портированный wget. Делал когда-то бота для ЛФ с его использователем.
Пролетареві ніколи вчити європейських мов, бодай би свою знати добре і на ній принести до своєї хати світло знання (Гнат Хоткевич)
ÆC CASALI NAXI PRASQURI: AHOV CÆRU, MERTVÆRI TÆ SLAVUTÆT!
Вони просили його: «Скажи: кетум», а він говорив: «сатем», і не міг вимовити правильно.
Хотелось бы также отметить, что "Питон" - это "мышиный язык" : "пи+тон". © АБР-2

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Note: this post will not display until it's been approved by a moderator.
Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
√49 Напишите ответ строчными буквами:
«Сто одёжек, все без застёжек» — что это?: