1
|
|
|
import abc |
|
|
|
|
2
|
|
|
from typing import TypeVar |
3
|
|
|
|
4
|
|
|
from typeddfs import TypedDfs |
|
|
|
|
5
|
|
|
|
6
|
|
|
from mandos.model.settings import QUERY_EXECUTORS |
7
|
|
|
|
8
|
|
|
from mandos.model.scrape import Scraper, By |
9
|
|
|
from mandos.model.apis.chembl_api import ChemblApi |
10
|
|
|
from mandos.model.hits import AbstractHit |
11
|
|
|
from mandos.model.searches import Search |
12
|
|
|
|
13
|
|
|
H = TypeVar("H", bound=AbstractHit, covariant=True) |
|
|
|
|
14
|
|
|
|
15
|
|
|
|
16
|
|
|
class _ScraperSingleton: |
17
|
|
|
x = None |
18
|
|
|
|
19
|
|
|
@classmethod |
20
|
|
|
def get(cls): |
|
|
|
|
21
|
|
|
if cls.x is None: |
22
|
|
|
cls.x = Scraper.create(QUERY_EXECUTORS.chembl) |
23
|
|
|
return cls.x |
24
|
|
|
|
25
|
|
|
|
26
|
|
|
ChemblTable = TypedDfs.typed("ChemblTable").build() |
27
|
|
|
|
28
|
|
|
|
29
|
|
|
class ChemblScrapeSearch(Search[H], metaclass=abc.ABCMeta): |
|
|
|
|
30
|
|
|
"""""" |
31
|
|
|
|
32
|
|
|
@classmethod |
33
|
|
|
def _page_name(cls) -> str: |
34
|
|
|
raise NotImplementedError() |
35
|
|
|
|
36
|
|
|
def _scrape(self, chembl_id: int) -> ChemblTable: |
37
|
|
|
# e.g. target_predictions |
38
|
|
|
url = f"https://www.ebi.ac.uk/chembl/embed/#compound_report_card/{chembl_id}/{self._page_name}" |
|
|
|
|
39
|
|
|
scraper = _ScraperSingleton.get() |
40
|
|
|
scraper.go(url) |
41
|
|
|
rows = [] |
42
|
|
|
i = 2 |
43
|
|
|
while True: |
44
|
|
|
table = scraper.find_element("table", By.TAG_NAME) |
45
|
|
|
for tr in table.find_elements("tr"): |
|
|
|
|
46
|
|
|
rows += [td.text for td in tr.find_elements("td")] |
47
|
|
|
# noinspection PyBroadException |
48
|
|
|
try: |
49
|
|
|
scraper.find_elements(str(i), By.LINK_TEXT) |
50
|
|
|
except Exception: |
|
|
|
|
51
|
|
|
break |
52
|
|
|
i += 1 |
53
|
|
|
header = rows[0] |
54
|
|
|
rows = rows[1:] |
55
|
|
|
return ChemblTable(rows, columns=header) |
56
|
|
|
|
57
|
|
|
|
58
|
|
|
class ChemblSearch(Search[H], metaclass=abc.ABCMeta): |
|
|
|
|
59
|
|
|
def __init__(self, key: str, api: ChemblApi): |
60
|
|
|
""" |
61
|
|
|
Constructor. |
62
|
|
|
|
63
|
|
|
Args: |
64
|
|
|
api: |
65
|
|
|
""" |
66
|
|
|
super().__init__(key) |
67
|
|
|
self.api = api |
68
|
|
|
|
69
|
|
|
|
70
|
|
|
__all__ = ["ChemblSearch", "ChemblScrapeSearch", "ChemblTable"] |
71
|
|
|
|