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

0 Members and 1 Guest are viewing this topic.

Offline Bhudh

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

Offline Red Khan

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

Offline Bhudh

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

Offline Red Khan

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

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

Offline Bhudh

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

Offline Bhudh

  • Posts: 51671
  • 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.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

 

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 Напишите ответ строчными буквами:
«Сто одёжек, все без застёжек» — что это?: