取り急ぎ。
寝る直前にやったらいかんなぁ…。昨晩のは、大ポカ。「うまくいってる」の解と違うのを引っ張ってきてしまってた。
取り急ぎという意味で:
1 # -*- coding: utf-8 -*-
2 import time
3 from contextlib import contextmanager
4
5 from selenium import webdriver
6 from selenium.webdriver.common.by import By
7
8
9 class _MyScraper:
10 def __init__(self):
11 self._driver_inst = None
12
13 @property
14 def _driver(self):
15 if self._driver_inst is None:
16 import sys
17 from selenium.webdriver.chrome.options import Options
18
19 opts = Options()
20 if sys.platform == "win32":
21 opts.add_argument("--disable-gpu")
22 else:
23 # linux only
24 opts.add_argument("--no-sandbox")
25 # for on docker
26 opts.add_argument("--disable-dev-shm-usage")
27 opts.add_argument("--disable-extensions")
28 opts.add_argument("--headless")
29 # opts.add_argument('--log-level=3')
30 opts.add_experimental_option("excludeSwitches", ["enable-logging"])
31 self._driver_inst = webdriver.Chrome(options=opts)
32 return self._driver_inst
33
34 @contextmanager
35 def _wait0(self, sleep_time=0.2, **kwargs):
36 oldid = self._driver.find_element(By.TAG_NAME, 'html').id
37 yield
38 while oldid == self._driver.find_element(By.TAG_NAME, 'html').id:
39 time.sleep(sleep_time)
40
41 @contextmanager
42 def _wait1(self, sleep_time=0.2, **kwargs):
43 def _pagehash():
44 dom = self._driver.find_element(
45 By.TAG_NAME, 'html').get_attribute('innerHTML')
46 return hash(dom.encode('utf-8'))
47 yield
48 ph0, ph1 = "empty", ""
49 while ph0 != ph1:
50 ph0 = _pagehash()
51 time.sleep(sleep_time)
52 ph1 = _pagehash()
53
54 def opentree(self, pkg):
55 with self._wait1():
56 self._driver.get(
57 f"https://maven.google.com/web/index.html?q={pkg}")
58 # print(self._driver.page_source)
59 for node in self._driver.find_elements(By.CLASS_NAME, "indexItem"):
60 if node.text == pkg:
61 with self._wait1():
62 node.click()
63 break
64 print(self._driver.page_source)
65
66
67 s = _MyScraper()
68 s.opentree("exoplayer")
これの「wait1」は昨晩の言い回しでいう「試してみてる範囲内ではうまくいってる」やつで、昨晩のに対応する「wait0」は、これはうまくいかない。
で、昨晩のでいうところの「readyState との関係」なのだけれど、これは、wait1 については愚問。wait1 のアプローチは wait0 と逆で、「変化が落ち着くのを待つ」ということをしてるだけなので、コードから全てわかる。これが不完全たりうる状況はすぐにわかるでしょ、そして「大抵うまくいく」理由もわかるはず。
取り急ぎでざっくり書いてしまったので、あとで改めて整理して書く…かもしれないし、書かないかもしれない。まぁ気分が乗れば、ね。
2023-04-06追記:
本題とは関係ないんだけれど、「for on docker」というコメントを付けて --disable-dev-shm-usage
しているのが気持ち悪くて、解決したかった。これは dbus デーモンが docker ではデフォルトでは動作してないために必要なオプションだった。
ビルドステップにて必要なオペレーション:
1 # ...
2 RUN apt-get install -yqq dbus
3 RUN dbus-uuidgen > /var/lib/dbus/machine-id
4 RUN mkdir -p /var/run/dbus
5 # ...
で、エントリポイントでは例えば:
1 #! /bin/sh
2 # ...
3 dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address
4 # ...
こうしておけば --disable-dev-shm-usage
しなくても docker で google-chrome は動作するようになる。