how to scroll a page inside a qwebview? - python

I guess this should be a simple task: change a QWebView's content (it always contains several pages of stuff) then scroll the page back in the previous position:
y = self.webView.page().mainFrame().scrollPosition().y()
self.webView.setHtml(looong_html_text)
if y != 0:
self.webView.scroll(0, y)
self.webView.page().mainFrame().scroll(0, y)
self.webView.page().mainFrame().setScrollPosition(QPoint(0, y))
print(self.webView.page().mainFrame().scrollPosition().y())
But the 3 commands inside the if are completely useless: the page scrolls back to top.
What's wrong?

This is a bit of a guess:
setScrollPosition will not let you scroll beyond the end of the page.
Since you are scrolling before the page is displayed, the page's effective height is 0 at the time. You could verify this by checking self.webView.page().mainFrame().contentSize()
Maybe you should do the scrolling when contentSizeChanged is triggered.

use this code
ui->webView->page()->mainFrame()->scroll(ui->webView->page()->mainFrame()->contentsSize().width(), ui->webView->page()->mainFrame()->contentsSize().height());

Related

Python Selenium unintentional click problem

I am trying to get followers with python selenium. But sometimes python clicks by itself.
I want to make an error-free program. I try to I've tried "try catch" constructs but it didn't work. Here is my code:
def getFollowers(self):
try:
self.browser.get(f"https://www.instagram.com/{self.username}")
time.sleep(2)
followers=self.browser.find_element_by_xpath("//*[#id='react-root']/section/main/div/header/section/ul/li[2]/a").click()
time.sleep(2)
dialog=self.browser.find_element_by_xpath("/html/body/div[5]/div/div/div[2]")
followerCount=len(dialog.find_elements_by_tag_name("li"))
print(f"first count:{followerCount}")
action=webdriver.ActionChains(self.browser)
//*******************************************Probly my problem is here****************************************
while True:
dialog.click()
action.key_down(Keys.SPACE).key_up(Keys.SPACE).perform()
time.sleep(3)
newCount=len(dialog.find_elements_by_tag_name("li"))
if followerCount!=newCount or newCount==24:
print(f"New count:{newCount}")
time.sleep(3)
followerCount=newCount
else:
break
//**********************************************************************************************************
followers=dialog.find_elements_by_tag_name("li")
followersList=[]
for user in followers:
link=user.find_element_by_css_selector("a").get_attribute("href")
# print(link)
followersList.append(link)
with open("followers.txt","w",encoding="UTF-8") as file:
for item in followersList:
file.write(item+"\n")
time.sleep(5)
except:
pass
I also have def getfollowing and it works flawlessly. If you want I can show it too. But they are almost same.
EDIT: #RohanShah solved my problem. At the bottom of the page you can see the solution.
Edit: I am new here thats why sometimes my questions could be meanless.But please dont decrease my points. Stackoverflow not gonna accept my questions anymore. Please increase my points.
I've had this exact same problem while scrolling the popups. What happens is your dialog.click(), while attempting to focus your key down on the popup, occasionally clicks a user and loads their profile. Your script then crashes as the popup is no longer on the screen.
After a lot of research into solving this problem, I noticed it only happens with usernames that are long. Regardless, I implemented a simple hack to get around this problem.
First we get the url of what the standard scroll looks like. When opening and scrolling the popup, this is the url we are on.
https://www.instagram.com/some_username/followers/
2.Now I have created a function to hold the code for opening the popup. This will be very useful so trap the necessary code into a function. (I don't have the classnames or xpath's on me so please customize the function for yourself)
def openPopup():
self.browser.get(f"https://www.instagram.com/{self.username}")
global popup # we will need to access this variable outside of the function
popup = driver.find_element_by_class_name('popupClass') #you don't have to use class_name
popup.click()
Now we have to tell our while loop to not scan when Selenium accidentally clicks on a user. We will use our URL from step 1. Please make sure the following if-statement is inserted at the TOP of your loop so if there is a break, it will handle it first before trying to access the popup.
while True:
check_url = self.browser.current_url #returns string with current_url
if check_url != 'https://www.instagram.com/some_username/followers/':
#if this code is executed, this means there has been an accidental click
openPopup() #this will bring back to the page and reopen popup
#the rest of your code
popup.click() # variable from our function
action.key_down(Keys.SPACE).key_up(Keys.SPACE).perform()
time.sleep(3)
newCount=len(dialog.find_elements_by_tag_name("li"))
if followerCount!=newCount or newCount==24:
print(f"New count:{newCount}")
time.sleep(3)
followerCount=newCount
else:
break
check_url = self.browser.current_url #we must recheck the current_url every time the loop runs to see if there has been a misclick
Now, whenever your loop detects the URL is no longer one of the popup, it will automatically call openPopup() which will get you back to the page and back in the popup, and your loop will continue as if nothing happened.

How to stop the automatic scroll-down when user scroll up?

I want to stop the automatic scroll down when user scroll up by mouse. I have made a function that scroll's down the webpage automatically after every 2 second but I want to stop that automatic scroll when user scroll up by mouse
My code:
from selenium import webdriver
import time
driver=webdriver.Chrome()
driver.get("https://YouTube.com")
driver. maximize_window()
a=input('press y if you want to scroll down')
if a=='y':
while(True) :
driver. execute_script("window.scrollBy(0, 150) ", "")
time.sleep(2)
else:
Print(" Ok")
One of the ways in which you can solve this is using the window.pageYOffset property.
From the Docs
The read-only Window property pageYOffset is an alias for scrollY; as such, it returns the number of pixels the document is currently scrolled along the vertical axis (that is, up or down) with a value of 0.0, indicating that the top edge of the Document is currently aligned with the top edge of the window's content area.
So what you will have to do is each time you scroll in the loop keep a count of the increase in y and for the condition of your loop, you should check that the pageYOffset == YScrolled. If it equals there's no user input, otherwise there is.
There is a good example here

Problem with simple count variable in Python

I made this short code for a school project using a Microbit computer, however, when I press the a button when the count is 1, the count jumps to 16 and I can't figure out why.
count = (1)
while True:
gesture = accelerometer.current_gesture()
display.show(count)
if button_a.is_pressed():
count *= (2)
if button_b.is_pressed():
count += (1)
if gesture == "shake":
count = (1)
any help would be greatly appreciated!
If count does not always increase by 16 on each click, you are likely dealing with button de-bouncing issue. Like others have suggested, you could use sleep(1) to check whether that is case or not, but for more practical solution you could do the following:
# detect click of button
if button.is_pressed():
count += 1
# do nothing while button remains clicked for the duration
while button.is_pressed():
pass
As other contributors commented, more than one button push is being detected for a single button push.
With Micropython, to avoid repeated button presses being detected for a single button press use the code:
if button_a.was_pressed():
instead of:
if button_a.is_pressed():

Vpython userspin does not work

I have a function call on button click which is used to display a number of cuboids. However i want the ability to rotate my frame on user mouse drag so as to get the desired viewing angle (as preferred by user)
However, i cant seem to rotate as well as zoom on my display window.
Edit: What i found was upon a right click drag it changes the viewing angle. However it does not get reflected. Weirdly enoughn it is reflected only after i maximize and then restore the screen. Is there some setting i can do to make it work seamlessly.
Also, the first display happens after i move the window from its initial position. Else its just blank upon launch!! Please advise
def testDraw():
global containers
myscene = display(title='Diagram')
#myscene.material = materials.wood
myscene.select()
myscene.exit=False
#myscene.userspin = True
myscene.userspin = 1
myscene.forward = (.1, -.3, -1)
mybox = [['','','','','','','',''] for x in range(len(containers))]
for x in range(len(containers)):
for y in range(len(containers[x])):
mybox[x]=box(pos=(float(containers[x][1])+float(containers[x][2])/2,float(containers[x][3])+float(containers[x][4])/2,float(containers[x][5])+float(containers[x][6])/2),width=float(containers[x][6]),height=float(containers[x][4]),length=float(containers[x][2]))
#,color='color.'+containers[x][7]
#mybox = box(pos=(2.5,1,5), length=10, height=2, width=5,color=color.blue)
#mybox2 = box(pos=(12.5,1,5), length=10, height=2, width=5,color=color.green)
#Name,length0,length1,height0,height1,width0,width1,color
containers=[['Container_1','`enter code here`0','2','0','7','0','2','blue'],
['Container_2','2','5','0','10','0','2','green'],
['Container_3','7','10','0','5','0','2','red']]
I don't understand what is meant by "it does not get reflected". What is "it"? Also, you haven't provided a runnable program, so it' difficult to know what the context is.
I'll advertise that a better place to pose VPython questions is in the VPython forum at
https://groups.google.com/forum/?fromgroups&hl=en#!forum/vpython-users

Trouble when automating button click selenium

So I am trying to fill out a form on this site. Every time I try to click the submit button at the end, using what I believe is the correct id, it just gives me an error. Here is a code snippet:
from selenium import webdriver
thePassword = "asdf123"
print("Desired name: ")
name = raw_input()
print("Desired Last Name: ")
userLastName = raw_input()
browser = webdriver.Firefox()
browser.get('https://www.panerabread.com/en-us/mypanera/registration-page.html')
firstName = browser.find_element_by_id('join_first_name')
firstName.send_keys(name)
lastName = browser.find_element_by_id('join_last_name')
lastName.send_keys(userLastName)
emailElem = browser.find_element_by_id('join_email')
emailElem.send_keys("asdafasda" + "#gmail.com")
emailConfirm = browser.find_element_by_id("join_confirm_email")
emailConfirm.send_keys("asdafasda" + "#gmail.com")
password = browser.find_element_by_id("join_password")
password.send_keys("thePassword")
passwordConfirm = browser.find_element_by_id("join_confirm_password")
passwordConfirm.send_keys("thePassword")
phoneA = browser.find_element_by_id("phone_number_a")
phoneA.send_keys("231")
phoneB = browser.find_element_by_id("phone_number_b")
phoneB.send_keys("123")
phoneC = browser.find_element_by_id("phone_number_c")
phoneC.send_keys("2310")
tos = browser.find_element_by_id("join_i_agree")
tos.click()
browser.execute_script("$('#join_password').get(0).scrollIntoView();")
#browser.implicitly_wait(10)
# And then perform the click
browser.find_element_by_id("join_card_not_available").click()
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
print "Your email is: " + "asdafasda" + "#gmail.com"
print "Your password is: " + thePassword
My question is, how can I submit the form at the end of my script?
Edit: There is no error. The problem is that it doesn't click the button I want it to at all. I tried running the below code on a seperate file and it worked, however when you run it with this entire script it does not work.
This was a weird one... it took me a minute to figure out what was going on. The problem is that there are actually two elements that have that id on the page (which is a no-no according to the HTML standard... but alas it happens). One on the bottom of the page that you are looking at and another on the Sign In popup. If you click the Sign In button at the top of the page, you will see the (first) Sign In button on the popup. Because it is hidden, your code wouldn't click on it. Anyway... to the solution.
There are a few ways you can handle this, any of them valid. I would do this.
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
What this is doing is using a CSS selector to get all the elements with ID=join-now-primary. The CSS selector is #join-now-primary which means id (#) of join-now-primary. Because it uses .find_elements (plural), it will get both. We then use [1] to get the 2nd element (0-based index, so 1 is the 2nd) and then click on it.
EDIT
My guess is that it's a timing issue that is causing the code to work on its own but not in your script. Put a breakpoint on the first line and step through each line and make sure that it executes. Does it work? If I were to guess again... it's likely the line right before the Join Now click. That click has an animation that closes the credit card picture. I would wait for that section to become invisible using the code below
element = WebDriverWait(browser, 5).until(EC.invisibility_of_element_located(By.ID('panera-card-section')))
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
You didn't really ask a question but it's likely you need to look at the WebElement class's methods and properties.
Looks like the button might not be in the visible portion of the window based on your code.
WebElement Has a property call that scrolls until an element moves into view.
If an element is not visible by Selenium definition, it is not clickable.
Even though you use the guts of the page to drive it, selenium wants to pretend it is testing human like interaction and so provides an artificial constraint.
You can bypass that by executing JavaScript click() on the element.

Categories

Resources