I want to make a little software with python and I have to get to YouTube with Requests-Python, but everytime I have to accept the Cookie-License. So I started with Selenium, but i cant find the button ID and the name or the value,...
The Source Code:
<button class="VfPpkd-LgbsSe VfPpkd-LgbsSe-OWXEXe-k8QpJ VfPpkd-LgbsSe-OWXEXe-dgl2Hf nCP5yc AjY5Oe DuMIQc IIdkle" jscontroller="soHxf" jsaction="click:cOuCgd; mousedown:UX7yZ; mouseup:lbsD7e; mouseenter:tfO1Yc; mouseleave:JywGue; touchstart:p6p2H; touchmove:FwuNnf; touchend:yfqBxc; touchcancel:JMtRjd; focus:AHmuwe; blur:O22p3e; contextmenu:mg9Pef;" jsname="higCR" aria-label=""><div class="VfPpkd-Jh9lGc"></div><span jsname="V67aGc" class="VfPpkd-vQzf8d" aria-hidden="true"></span><div class="VfPpkd-RLmnJb"></div></button>
Selenium has many options additionally to id.
For example, try to use css locator
locator = driver.find_element_by_css_selector(".VfPpkd-LgbsSe.VfPpkd-LgbsSe-OWXEXe-k8QpJ.VfPpkd-LgbsSe-OWXEXe-dgl2Hf.nCP5yc.AjY5Oe.DuMIQc.IIdkle")
Remove classes that do not make this locator unique to make the locator shorter.
Related
I am trying to automate something on Facebook using Python selenium. I want to click the post button shown in the second image. When I click the inspect in chrome on this post button, it takes me to the highlighted 'class' element shown in the third image. To click this button, I have tried the following:
#browser.find_element_by_class_name("oajrlxb2 s1i5eluu qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 pq6dq46d p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x cxgpxx05 d1544ag0 sj5x9vvc tw6a2znq oqcyycmt esuyzwwr f1sip0of lzcic4wl l9j0dhe7 abiwlrkh p8dawk7l ehryuci6 bp9cbjyn beltcj47 p86d2i9g aot14ch1 kzx2olss rt8b4zig n8ej3o3l agehan2d sk4xxmp2 lrazzd5p gigivrx4 sf5mxxl7 g0qnabr5 lrwzeq9o iqfcb0g7 lsqurvkf id6903cd jq4qci2q m5l1wtfr taijpn5t sn7ne77z oqhjfihn bwm1u5wc").click()
Following is the error I am getting:
One thing that I noticed is that the div tag contains the text Post, so instead of complicating things with the class name, you can simply click on the element by identifying the text it contains. You can do it like this:
browser.find_element_by_xpath("//div[contains(text(), 'Post')]")
I want to login to the following website:
https://www.investing.com/equities/oil---gas-dev-historical-data
Here is what I have tried so far:
from selenium import webdriver
profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.manager.showWhenStarting", False)
profile.set_preference("browser.download.dir", './ogdc.csv')
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/x-gzip")
driver = webdriver.Firefox(firefox_profile=profile)
driver.get('https://www.investing.com/equities/oil---gas-dev-historical-data')
driver.find_element_by_class_name("login bold")
driver.find_element_by_id('Email').send_keys('myemail')
driver.find_element_by_id('Password').send_keys('mypass')
driver.find_element_by_partial_link_text("Download Data").click()
But I get following Exception:
NoSuchElementException
How can I login to the above website?
You need click Sign in first to bring up the login popup, try the following code:
driver.get('https://www.investing.com/equities/oil---gas-dev-historical-data')
driver.find_element_by_css_selector("a[class*='login']").click()
driver.find_element_by_id('loginFormUser_email').send_keys('myemail')
driver.find_element_by_id('loginForm_password').send_keys('mypass')
driver.find_element_by_xpath("//div[#id='loginEmailSigning']//following-sibling::a[#class='newButton orange']").click()
From what I can tell, you need to click the Sign In button („login bold”) in order to open the popup. That one is not part of the initial DOM load and need some time to show up. So basically, wait for #Email and #Password to get visible.
You should be able to use an explicit wait for this.
I am not interested in using any API nor am I interested in any other library other than request-promie and cheerio. I am trying to get the name of a yt channel when I enter a link to the yt channel page. The text is inside a unique tag and is formatted like this: <yt-formatted-string id="text" class="style-scope ytd-channel-name">NAME OF CHANNEL</yt-formatted-string> I have tried the following
$('yt-formatted-string', html).text()
$('.ytd-channel-name', html).text()
$('div > yt-formatted-string', html).text()
and some other combinations but it seems as if the cheerio library is unable to recognize custom crafted tags such as "yt-formatted-string" as well as their attributes! Any suggestions on how to get past this?
Could you please try the below fragment? It works for me,
const $ = cheerio.load(`<yt-formatted-string id="text" class="style-scope ytd-channel-name">NAME OF CHANNEL</yt-formatted-string>`);
const a = $('yt-formatted-string').text(); //NAME OF CHANNEL
I want to get the current url when I am running Selenium.
I looked at this stackoverflow page: How do I get current URL in Selenium Webdriver 2 Python?
and tried the things posted but it's not working. I am attaching my code below:
from selenium import webdriver
#launch firefox
driver = webdriver.Firefox()
url1='https://poshmark.com/search?'
# search in a window a window
driver.get(url1)
xpath='//input[#id="user-search-box"]'
searchBox=driver.find_element_by_xpath(xpath)
brand="freepeople"
style="top"
searchBox.send_keys(' '.join([brand,"sequin",style]))
from selenium.webdriver.common.keys import Keys
#EQUIValent of hitting enter key
searchBox.send_keys(Keys.ENTER)
print(driver.current_url)
my code prints https://poshmark.com/search? but it should print: https://poshmark.com/search?query=freepeople+sequin+top&type=listings&department=Women because that is what selenium goes to.
The issue is that there is no lag between your searchBox.send_keys(Keys.ENTER) and print(driver.current_url).
There should be some time lag, so that the statement can pick the url change. If your code fires before url has actually changed, it gives you old url only.
The workaround would be to add time.sleep(1) to wait for 1 second. A hard coded sleep is not a good option though. You should do one of the following
Keep polling url and wait for the change to happen or the url
Wait for a object that you know would appear when the new page comes
Instead of using Keys.Enter simulate the operation using a .click() on search button if it is available
Usually when you use click method in selenium it takes cared of the page changes, so you don't see such issues. Here you press a key using selenium, which doesn't do any kind of waiting for page load. That is why you see the issue in the first place
I had the same issue and I came up with solution that uses default explicit wait (see how explicit wait works in documentation).
Here is my solution
class UrlHasChanged:
def __init__(self, old_url):
self.old_url = old_url
def __call__(self, driver):
return driver.current_url != self.old_url:
#contextmanager
def url_change(driver):
current_url = driver.current_url
yield
WebDriverWait(driver, 10).until(UrlHasChanged(current_url))
Explanation:
At first, I created my own wait condition (see here) that takes old_url as a parameter (url from before action was made) and checks whether old url is the same like current_url after some action. It returns false when both urls are the same and true otherwise.
Then, I created context manager to wrap action that I wanted to make, and I saved url before action was made, and after that I used WebDriverWait with created before wait condition.
Thanks to that solution I can now reuse this function with any action that changes url to wait for the change like that:
with url_change(driver):
login_panel.login_user(normal_user['username'], new_password)
assert driver.current_url == dashboard.url
It is safe because WebDriverWait(driver, 10).until(UrlHasChanged(current_url)) waits until current url will change and after 10 seconds it will stop waiting by throwing an exception.
What do you think about this?
I fixed this problem by clicking on the button by using href. Then do driver.get(hreflink). Click() was not working for me!
In a Watir script, after I check checkboxes in a popup window, I'm trying to execute a javascript function to add objects selected to the parent window.
What works fine until now it is the check of the checkbox, but object is not added to the parent window and I get following error when I executed the watir script:
in `method_missing': execScript (WIN32OLERuntimeError)
This was my approach - please let me know what other method I can use
ie.checkbox(:id => "check_asm0option0").set
ie.document.parentWindow.execScript("window.triggerOriginalChange(asm0option0, add);","JavaScript")
tr class="tr_option" rel="asm0option0"
td class="td_check"
input id="check_asm0option0" type="checkbox" value="4dbb118ddca3244e2800003d" rel="asm0option0" name="ignore"
/td
td class="td_li"
li value="0" rel="asm0option0" test /li
/td
/tr
if using .set doesn't result in your code working the way you'd expect, then examine the source and then try using .fireEvent to fire the event that should trigger the script that needs to execute.
In this case I'd try
ie.checkbox(:id => "check_asm0option0").fireEvent('onChange')
that approach is generally a bit more organic and easier than trying to invoke the script manually