Youtube comment use selenium - xpath

import subprocess
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
subprocess.Popen(r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\chrometemp"') # 디버거 크롬 구동
option = Options()
option.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Chrome('chromedriver', options = option)
url = 'https://www.youtube.com/watch?v=_XulUbBra5M'
driver.get(url)
driver.maximize_window() # 크롬 창 크기 최대화
driver.implicitly_wait(3) # 페이지 로드까지 3초간 기다림
heihgt = driver.execute_script(
"return document.documentElement.scrollHeight"
)
# 기존 위치
stand_height = 0
while True:
# 현재 높이
current_height = driver.execute_script(
"return document.documentElement.scrollHeight"
)
driver.execute_script(
f"window.scrollTo(0, {stand_height});" #스크롤 내리기
)
time.sleep(1)
# 스크롤 내린 페이지의 높이
new_page_height = driver.execute_script(
"return document.documentElement.scrollHeight"
)
stand_height = heihgt
heihgt = new_page_height
time.sleep(1)
driver.find_element(By.XPATH, "//*[#id='contenteditable-root']")
#driver.close()
I'm making a program that uses crawling to comment comments, but when I find the location of comments with xpath, I get the following error: I don't know why.
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id='contenteditable-root']"}
(Session info: chrome=96.0.4664.110)
Python does not support driver.find_element_by_xpath , it supports driver.find(By.XPATH,) . Does this cause an error? please tell me why

The input element to insert a new comment is not initially loaded on the page.
To make this element loaded you need to scroll the page down.
Also, to make the actual input comment element to be interactable you first need to click another element.
This should work:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
url = 'https://www.youtube.com/watch?v=_XulUbBra5M'
driver.get(url)
wait = WebDriverWait(driver, 20)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button.ytp-play-button")))
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
wait.until(EC.visibility_of_element_located((By.XPATH, "//*[#id='simplebox-placeholder']"))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, "//*[#id='contenteditable-root']"))).send_keys(your_comment_text)

Related

How to copy to clipboard from browser using python 3.10.4 and Ubuntu 22.04?

I have the following code that is automating a process in the browser.
At the line pt.click(clicks=3) I can get the text selected in the input box (Chrome). At the line pc.copy() I should copy this text and send it to the variable self.message to be processed. This step is not working.
There are a lot of documents and tutorials on how to do that on Windows and Mac, not in Ubuntu, specially in Ubuntu 22.04.
I am using OS Ubuntu 22.04 and Python 3.10.4.
What am I missing?
from turtle import right
import cv2 as cv
from time import sleep
# Waiting time
print('Waiting 2s')
sleep(2)
import pyautogui as pt
import paperclip as pc
from tkinter import ttk
....
def nav_message(self):
try:
clipPicCenter = pt.locateCenterOnScreen('./clip_pic.png', confidence=0.7)
# print('LocateCenter clip_pic', clipPicCenter)
pt.moveTo(clipPicCenter[0]+48, clipPicCenter[1]-60, duration=self.speed)
pt.click(clicks=3)
sleep(.9)
self.message = pc.copy() //Out PUT - Pyperclip do not have the method copy()
print(self.message)
# pt.click(button='right', clicks=1)
# pos = pt.position()
# pt.moveTo(pos[0]+20, pos[1]-300, duration=self.speed)
# txt = pt.click()
# print(txt)
# self.nav_input_box()
# pt.write(txt)
# txt = pt.hotkey("ctrl", "c") # copy the text (simulating key strokes)
# pt.click(button=right)
except Exception as e:
print ('Exception (nav_green_dot): ', e)
you can use this to copy something to your clipboard
import pyperclip
s1 = "Hello world"
pyperclip.copy(s1)
s2 = pyperclip.paste()
print(s2)
Line 9 you import paperclip as pc. You need to import pyperclip as pc (Note that it starts with py and not pa). The 2 are spelled similar, but your code imports the paperclip library for Django instead of the pyperclip library for managing the clipboard. Heres a codeblock with your fixed imports:
from turtle import right
import cv2 as cv
from time import sleep
# Waiting time
print('Waiting 2s')
sleep(2)
import pyautogui as pt
# this used to be "paperclip"
# "pyperclip" is what you need to import
import pyperclip as pc
from tkinter import ttk

how to read image from wand.image.Image without saving it to drive

what changes should i do in this code so i don't have to save image to disk in step [A] then again read it from disk in step [B]. as showing in code. can anyone help me this with changes in the code or some tips?
import io
import os
import six
from google.cloud import vision
from google.cloud import translate
from google.cloud.vision import types
import json
from wand.image import Image
client = vision.ImageAnnotatorClient()
sample_pdf = Image(filename='CMB72_CMB0720160.pdf[0]', resolution=500)
blank = Image(filename='Untitled.png')
all_ = sample_pdf.clone()
polling_ = sample_pdf.clone()
voters = sample_pdf.clone()
all_.crop(3000,2800,3800,3860)
polling_.crop(870,4330,2900,4500)
voters.crop(1300,4980,2000,5250)
blank.composite(all_,left=0,top=0)
blank.composite(voters,left=0,top=1100)
blank.composite(polling_,left=0,top=1420)
blank.save('CMB72_CMB0720122.jpg')---------------[A]
file_name = 'CMB72_CMB0720122.jpg'-------------|
with io.open(file_name,'rb') as image_file:----|>[B]
content = image_file.read()---------------|
image = types.Image(content= content)
image_context = vision.types.ImageContext(
language_hints=['hi'])
response = client.document_text_detection(image=image)
texts = response.text_annotations
file = open('jin.txt','w+',encoding='utf-8')
file.write(texts[0].description)
file.close()
Use the wand.image.Image.make_blob method.
content = blank.make_blob('JPEG')

flask server running in virtual box is not accessible from the windows host

I have tried running it from host='0.0.0.0' and it is still inaccessible. I can ping my windows machine ip 192.168.1.109 from my virtualmachine, but I can not ping my Ubuntu VirtualMachine ip from ifconfig 10.0.2.15 from my windows side. I am using virtualbox if that helps.
run.py
#!flask/bin/python
from app import app
app.run(host='0.0.0.0',port=5000, debug=True)
init.py
import os
from flask import Flask
from flask.json import JSONEncoder
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_mail import Mail
from flask_babel import Babel, lazy_gettext
from config import basedir, ADMINS, MAIL_SERVER, MAIL_PORT, MAIL_USERNAME, \
MAIL_PASSWORD
from .momentjs import momentjs
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
lm = LoginManager()
lm.init_app(app)
lm.login_view = 'login'
lm.login_message = lazy_gettext('Please log in to access this page.')
mail = Mail(app)
babel = Babel(app)
class CustomJSONEncoder(JSONEncoder):
"""This class adds support for lazy translation texts to Flask's
JSON encoder. This is necessary when flashing translated texts."""
def default(self, obj):
from speaklater import is_lazy_string
if is_lazy_string(obj):
try:
return unicode(obj) # python 2
except NameError:
return str(obj) # python 3
return super(CustomJSONEncoder, self).default(obj)
app.json_encoder = CustomJSONEncoder
if not app.debug and MAIL_SERVER != '':
import logging
from logging.handlers import SMTPHandler
credentials = None
if MAIL_USERNAME or MAIL_PASSWORD:
credentials = (MAIL_USERNAME, MAIL_PASSWORD)
mail_handler = SMTPHandler((MAIL_SERVER, MAIL_PORT),
'no-reply#' + MAIL_SERVER, ADMINS,
'microblog failure', credentials)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
if not app.debug and os.environ.get('HEROKU') is None:
import logging
from logging.handlers import RotatingFileHandler
file_handler = RotatingFileHandler('tmp/microblog.log', 'a',
1 * 1024 * 1024, 10)
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('microblog startup')
if os.environ.get('HEROKU') is not None:
import logging
stream_handler = logging.StreamHandler()
app.logger.addHandler(stream_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('microblog startup')
app.jinja_env.globals['momentjs'] = momentjs
from app import views, models
It worked for me when I changed this line in the main
app.run()
to
app.run(host='192.168.163.128', port=5000)

sendOSCMsg is not defined on Kivy (Windows Shell)

I tried another attempt with this
kivy 1.9.0
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
from kivy.uix.widget import Widget
from simpleOSC import initOSCClient, initOSCServer, closeOSC, \
setOSCHandler, sendOSCMsg
class OscShowcase(BoxLayout):
pass
def __init__(self, **kwargs):
super(OscShowcase, self).__init__(**kwargs)
#self.but_Osc = Button(text='Press to show Osc')
#self.but_Osc.bind(on_release=self.send_Osc)
#self.add_widget(self.but_Osc)
def send_Osc(self, *l):
pass
#sendOSCMsg('/chaine_en_dur/', [2.0])
def sendOSCMsg( address='/print', data=[] ) :
m = OSCMessage()
m.setAddress(address)
for d in data :
m.append(d)
basic_client.send(m)
class OscWidget(GridLayout):
def __init__(self, **kwargs):
super(OscWidget, self).__init__(**kwargs)
class TestOscApp(App):
def build(self):
return OscShowcase()
if __name__ == '__main__':
host = '127.0.0.1'
sport = 9000
rport = 9001
# osc
initOSCClient(host, sport)
initOSCServer(host, rport)
TestOscApp().run()
.kv file
<OscShowcase>:
BoxLayout:
OscWidget:
Button:
text: 'OSC'
pos: (700, 500)
# on_release : sendOSCMsg('')
# sendOSCMsg: '/chaine_en_dur/', [2.0]
# on_release : self.but_Osc.bind()
group: 'OscButton'
on_press: sendOSCMsg('2')
I still get an error "NameError: name 'sendOSCMsg is not defined" when I press the button. Is anybody can help me to understand why? I would like to send osc messages out to Max MSP
Kv Lang has some scopes, you can read more about it here
There are three keywords specific to Kv language:
app: always refers to the instance of your application.
root: refers to the base widget/template in the current rule
self: always refer to the current widget
You can run a method from TestOscApp with app.method_name() and from OscShowcase with root.method_name()
So, just update your kv to call sendOSCMsg from OscShowcase:
on_press: root.sendOSCMsg('2')

Python 3.2 script not working and/or importing tkinter when running from Linux desktop

I'm really puzzled by this, but the answer is probably quite simple and just can't see it:
I have a series of python modules that work fine from within the python interpreter, but nothing happens when running from a GUI situation. I've tried creating a .desktop file, adding shebangs, changing permissions to 777 and renaming to .pyw for all the modules. A single test module works fine on its own, so I know that it's not a typo error.
If I click the main module .pyw file and click 'Run' from the system dialogue nothing happens at all. Similarly the .py file (and the .desktop via menu)... nothing. Here is the start of my code:#
#!/usr/bin/python3
import tkinter as tk, imp, sys
root = tk.Tk()
msg = tk.messagebox
sdg = tk.simpledialog
import capitaliser_cfg as cfg, fileio as io
imp.reload(cfg) ; imp.reload(io)
### GO AND GET COUNTY LIST ####
# Nb: attach to config for simplicity
cfg.counties = io.getfilelist("counties.txt", "London")
if not type(cfg.counties)==list:
k = msg.showerror(cfg.version, cfg.counties)
root.destroy()
root.mainloop()
### GO AND GET DICTIONARY ####
cfg.tempdict = [[],[],[]]
cfg.spelldict = io.getdictionary("addressdict.txt","roda","Road")
if not type(cfg.spelldict)==dict:
k = msg.showerror(cfg.version, cfg.spelldict)
root.destroy()
root.mainloop()
import thinbutton as tb, labelradio as lr, fieldblock as fb, bigbutton as bb
import textblock as tx, padding as pd, widget_tools as wt
import capitaliser_mth as mth
import capitaliser_bnd as bnd
imp.reload(tb) ; imp.reload(lr) ; imp.reload(fb) ; imp.reload(bb)
imp.reload(tx) ; imp.reload(pd) ; imp.reload(wt) ;
imp.reload(mth)
imp.reload(bnd)
If I put k = msg.showerror("xxxx","yyyy") after the line sdg = tk.simpledialog, still nothing happens which leads me to believe that tkinter is not loading for some reason.
Any ideas anyone ?
For Python 2 try:
import tkMessageBox
import tkSimpleDialog
msg = tkMessageBox
sdg = tkSimpleDialog
or simpler:
import tkMessageBox as msg
import tkSimpleDialog as sdk
For Python 3 try:
from tkinter import messagebox
from tkinter import simpledialog
msg = messagebox
sdg = simpledialog
or simpler:
from tkinter import messagebox as msg
from tkinter import simpledialog as sdg

Resources