UserJS: Allegro Seller Info - strona aukcji

tech • 752 słowa • 4 minuty czytania

Moje ostatnie zabawy ze skryptem UserJS do poprawiania Allegro tak mi się spodobały, że postanowiłem poświecić jeszcze jeden wieczór i dodać obsługę także strony z aukcją. Bo wydaje mi się, że informacja o lokalizacji sprzedającego w nagłówku aukcji będzie wygodniejsza, niż szukanie jej w treści ogłoszenia lub w “Opcjach dostawy”. A że często obserwuję różne aukcje, to zdecydowanie poprawi mi to komfort użytkowania serwisu. Szczególnie, gdy uda mi się osiągnąć coś podobnego do tego przedstawionego na poniższym zrzucie.

Na początek oczywiście sprawdziłem, czy nie ma tutaj też jakiś fajnych obiektów globalnych zaszytych w kontekście danej strony. Okazało się, że kilka takich zmiennych z nazwami zaczynającymi się od __ zawiera całkiem sporo informacji nie tylko o aukcji.

Niestety w żadnym nie znalazłem przystępnej informacji o lokalizacji sprzedającego powiązanej z daną aukcją, oprócz “danych” w obsłudze karty “Dostawa i płatność”. Ale istnienie jednej z tych zmiennych w globalnej przestrzeni może być (jak wcześniej) dobrym określeniem czy znajdujemy się na stronie z opisem aukcji, czy może innej części serwisu.

Dane o lokalizacji chyba najprościej wyekstrahować wprost ze wspomnianej już karty prezentującej informacje o dostawie. Co ciekawe wystawiający może tam wpisać cokolwiek, ale zawsze info to będzie poprzedzone ciągiem “Lokalizacja:” co ułatwia całą zabawę w poszukiwania.

var node = document.getElementsByName('delivery')[0].nextElementSibling;

var loc;
for (var p of node.getElementsByTagName('p')) {
	if (p.innerText.startsWith('Lokalizacja:')) {
		var i = p.innerText.lastIndexOf(', Polska');
		loc = i != -1 ? p.innerText.substr(0, i) : p.innerText;
		break;
	}
}

if (!loc) return;

Formatowanie i budowa tej karty bywa różna, więc standardowo najlepiej zrobić to po chamsku, czyli tutaj akurat polecieć po paragrafach i sprawdzić zawartość tekstową innerText. I przy okazji można pominąć wzmiankę o Polsce, jeśli to lokalizacja krajowa ;)

Gorzej z szukaniem miejsca na wstrzykniecie kodu. Ten layout jest jakiś dziwny, a’la tablicowy na kontenerach. I z tego co już zauważyłem, to na różnych aukcjach i w różnych konfiguracjach występuje różna ilość wierszy i prezentowanych danych. Nie da się tak łatwo znaleźć elementu, bazując choćby nawet na liczeniu poszczególnych dzieci i potomków.

node = document.querySelector('div[itemprop="offers"]');
node = [...node.children].filter(n => {
	return n.computedStyleMap().get('border-top-width').value == 1;
})[0].previousElementSibling;

Ale jest inny prosty sposób. W końcu chcę to dodać nad danymi oddzielonymi od reszty poziomową linią, która de facto jest obramowaniem górnym kolejnego wiersza. Wystarczy znaleźć pierwszy element z ustawionym obramowaniem i dobrać się do jego poprzednika!

Teraz mogę już wstrzyknąć swoje bebechy do DOM-a. Tylko przez ten layout trzeba się trochę nagimnastykować, aby dodane elementy nie rozjechały strony i spójnie się z nią komponowały…

// gdy wiersz jest pelny, dodajemy nowy
if (node.childElementCount > 1) {
	node.insertAdjacentHTML('afterend', `<div class="${node.className}"></div>`);
	node = node.nextElementSibling;
}

// gdy wiersz pusty dodajemy pusty kontener jako pierwsza komorka
if (node.childElementCount == 0) {
	node.insertAdjacentHTML('beforeend', `<div></div>`);
}

// a jako druga komorka leci nasza wstawka
node.insertAdjacentHTML('beforeend', `<div class="${cssName}">${loc}</div>`);

Na koniec wypada jeszcze wspomnieć o dodaniu potrzebnych styli CSS, bo nie ma sensu polegać na tych zmieniających się nazwach klas na poszczególnych stronach aukcji.

const cssName = 'm8dkm36f';
document.body.insertAdjacentHTML('beforeend', `
	<style type="text/css">
		div.${cssName} {
			font-size: 13px;
			color: #767676;
			margin-bottom: 8px;
			line-height: 21px;
		}
	</style>
`);

Szybkie testy na różnych aukcjach potwierdzają prawidłowe działanie. Poszło szybko i gładko w porównaniu do moich poprzednich ekscesów, gdzie zmagałem się z listą aukcji.

Kilka godzin później…

No jednak, nie jest tak fajnie. Natrafiłem na dziwny problem objawiający się tylko przy otwarciu strony w nowej zakładce w tle. Mimo tego, że skrypt się wykona, bo widzę jego wpisy w logu konsoli, to jednak na stronie próżno szukać wstawionych elementów. To dopiero jest WTF!

Active resource loading counts reached a per-frame limit while the tab was in background. Network requests will be delayed until a previous loading finishes, or the tab is brought to the foreground. See http://www.chromestatus.com/feature/5527160148197376 for more details

Powyższy wpis w logach konsoli strony wygląda na jakiś feature w Chromie optymalizujący działanie aplikacji przez zarządzanie (limitowanie) zasobów dla stron działających w tle - Background Tab Resource Load Throttling. Po wyłączenie tego mechanizmu problem znika, ale to niekoniecznie musi oznaczać błąd w przeglądarce.

Równie dobrze może skrypty na stronie z aukcją są zbyt zasobożerne przy działaniu w tle, albo jakieś inne dziwne zachowanie występujące w połączeniu Chrome + Allegro… Temu się przyjrzę bliżej zapewne dopiero po urlopie, a tymczasem małe obejście problemu:

// Workaround/Hack na problemy z Background Tab Resource Load Throttling 
document.addEventListener('visibilitychange', function () {
	if (!document.hidden && document.getElementsByClassName(cssName).length == 0)
		UpdateOffer();
});

Jeśli przy “wyjściu” zakładki z tła w DOM-ie strony nie można znaleźć moich wcześniej dodanych elementów to ponownie wstrzykuję kontener z lokalizacją użytkownika. Działa to dobrze i rozwiązuje problem. Ciekawe czy tak już zostanie ;)

Komentarze (0)

Dodaj komentarz

/dozwolony markdown/

/nie zostanie opublikowany/