** Ce que je voulais faire ** Je veux prendre une capture d'écran d'une page Web sur heroku et la recadrer avec un élément HTML.
problème Lors de l'exécution de PhantomJS avec du sélénium, il n'existe aucune méthode pour obtenir l'emplacement de la position de l'élément.
Solution
Exécutez Javascript avec la fonction ʻexecute_script fournie dans la classe
selenium.webdriver.PhantomJS`.
** Bibliothèque Python **
screenshot_crop.py
from PIL import Image
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get("https://www.yahoo.co.jp") # (1)
driver.save_screenshot("screenshot.png ") # (2)
element_type = "Id" # (3)
element_name = "topicsboxbd" # (4)
before_script = """
var element = document.getElementBy""" + element_type + "('" + element_name + """');
var rect = element.getBoundingClientRect();
""" # (5)
left = driver.execute_script(before_script + "return rect.left;") # (6)
top = driver.execute_script(before_script + "return rect.top;") # (6)
right = driver.execute_script(before_script + "return rect.width;") + left # (7)
bottom = driver.execute_script(before_script + "return rect.height;") + top # (7)
im = Image.open("screenshot.png ") # (8)
im = im.crop((left, top, right, bottom)) # (9)
im.save("screenshot_crop.png ") # (10)
im.close()
(1) - Spécifiez l'URL pour prendre la capture d'écran.
(2) -Enregistrer une capture d'écran de la page entière.
(3) --Spécifiez le nom de l'attribut d'élément (Id, Classe, etc.) dans ʻelement_type. Tout peut être saisi dans le cercle Javascript getElementBy 〇〇. Par conséquent, la chaîne de caractères à attribuer doit commencer par une lettre supérieure. (4) --Spécifiez la valeur d'attribut (partie principale telle que id = "main") de l'attribut spécifié dans (3) de l'élément dans ʻelement_name
.
(5) - Partie commune du code JS à exécuter
(6) (7) --Le code Javascript est exécuté par la fonction driver.execute_script
pour obtenir les coordonnées en haut à gauche et en bas à droite de l'élément.
(8) -Ouvrez la capture d'écran enregistrée dans (1).
(9) -Cadrer la capture d'écran originale en utilisant les coordonnées obtenues en (6) et (7).
(10) --Enregistrez la capture d'écran recadrée.
screenshot.png Capture d'écran de la page entière
screenshot_crop.png Capture d'écran de screenshot.png recadrée avec l'élément ʻid = "topicsboxbd" ʻelement
Lorsque je mets PhantomJS sur heroku et que je prends une capture d'écran, le japonais n'est pas affiché tel quel dans l'image enregistrée.
En créant un répertoire .font
dans le répertoire racine et en insérant un fichier ttf (otf) prenant en charge le japonais, le japonais sera affiché.
Utilisation de phantomjs avec Heroku | Program Memo
exphantom.py
from PIL import Image
from selenium import webdriver
class ScreenShot:
def __init__(self, file_name_: str = "screenshot.png "):
"""
:type file_name_: str
"""
self._filename = file_name_
self._driver = webdriver.PhantomJS()
self._driver.set_window_size(1024, 768)
self._crop_margin = 0
def screen_shot(self, url_: str) -> bool:
"""
Take a screenshot of the specified url.
:return: Success is True, Fail is False
:param url_: the webpage to save screenshot
"""
try:
self._driver.get(url_)
self._driver.save_screenshot(self._filename)
except Exception as e:
print(e)
return False
return True
def screen_shot_crop(self, url_: str, search_element_name: str, search_element_type: str = "Id") -> bool:
"""
Take a screenshot of the specified class of the specified url destination.
:return: Success is True, Fail is False
:param url_: the webpage to save screenshot
:param search_element_name: search to element name
:param search_element_type: search to element type
"""
self.screen_shot(url_)
before_script = """
var element = document.getElementBy""" + search_element_type + "('" + search_element_name + """');
var rect = element.getBoundingClientRect();
"""
try:
left = self._driver.execute_script(before_script + "return rect.left;") - self._crop_margin
top = self._driver.execute_script(before_script + "return rect.top;")
right = self._driver.execute_script(before_script + "return rect.width;") + left + self._crop_margin
bottom = self._driver.execute_script(before_script + "return rect.height;") + top + self._crop_margin
except Exception as e:
print(e)
return False
im = Image.open(self._filename)
im = im.crop((left, top, right, bottom))
im.save(self._filename)
im.close()
return True
def set_file_name(self, filename_: str):
self._filename = filename_
def set_window_size(self, width_: int, height_: int):
self._driver.set_window_size(width=width_, height=height_)
def get_window_size(self) -> object:
return self._driver.get_window_size()
def set_crop_margin(self, crop_margin_: int):
self._crop_margin = crop_margin_
def ger_crop_margin(self) -> object:
return self._crop_margin
def __del__(self):
self._driver.close()
if __name__ == "__main__":
#Spécifiez l'URL pour prendre une capture d'écran
screen_url = "https://www.yahoo.co.jp"
#Spécifiez les attributs de l'élément à recadrer
element_type = "Id"
#Spécifiez le nom de l'élément à recadrer
element_name = "topicsboxbd"
#Spécifiez le nom du fichier de destination d'enregistrement lors de la création d'une instance
ss = ScreenShot("screenshot.png ")
# screen_Enregistrer la capture d'écran de l'URL
ss.screen_shot(screen_url)
#Changer le nom du fichier de destination d'enregistrement
ss.set_file_name("screenshot_crop.png ")
# screen_élément url_élément de type attribut_Enregistrer une capture d'écran de l'élément nommé name
ss.screen_shot_crop(screen_url, element_name, element_type)
#Supprimer l'instance
del ss
** Exemple d'utilisation réelle ** [Non officiel] Miyadai Support Division Notice BOT
python selenium phantomJS element.location returns wrong location - Stack Overflow
Recommended Posts