How to convert a web html to pdf with pyqt5 - html

last year i converted html to pdf with pyqt4 succesfully.. but with pyqt5 i lost 2 days and i´m frustrated..
This is my code:
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebKitWidgets import QWebView
from PyQt5.QtPrintSupport import QPrinter
from PyQt5.QtCore import QUrl
app = QApplication(sys.argv)
web = QWebView()
web.load(QUrl("https://www.google.com"))
printer = QPrinter()
printer.setPageSize(QPrinter.A4)
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName("out.pdf")
def convertIt():
web.print_(printer)
print ('Pdf generado')
QApplication.exit()
QObject.connect(web, SIGNAL("loadFinished(bool)"), convertIt)
app.exec_()
And i have one "QOject no have attribute "connect"... i know is something about the signals, that changed from pyqt4 to pyqt5, but i have no idea to code it.. thanks in advance.

This should be web.loadFinished.connect(convertIt) as per the PyQt docs about signals/slots.

Related

How do I upload javascript and html to qwebengine?

I want to upload my javascript and html code to qwebengine so that it will read the code and load it in the browser. Is this possible? I think there is some way to do this as I have been reading about it on the internet but I'm unsure of how to do so. My code for the browser is:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtWebEngineWidgets import *
class MyWebBrowser(QMainWindow):
def __init__(self,):
super(MyWebBrowser, self).__init__()
self.window=QWidget()
self.window.setWindowTitle("Brave")
self.layout=QVBoxLayout()
self.horizontal = QHBoxLayout()
self.url_bar = QTextEdit()
self.url_bar.setMaximumHeight(30)
self.go_btn=QPushButton("Go")
self.go_btn.setMinimumHeight(30)
self.back_btn = QPushButton("<")
self.back_btn.setMinimumHeight(30)
self.forward_btn = QPushButton(">")
self.forward_btn.setMinimumHeight(30)
self.horizontal.addWidget(self.url_bar)
self.horizontal.addWidget(self.go_btn)
self.horizontal.addWidget(self.back_btn)
self.horizontal.addWidget(self.forward_btn)
self.browser=QWebEngineView()
self.go_btn.clicked.connect(lambda: self.navigate(self.url_bar.toPlainText()))
self.back_btn.clicked.connect(self.browser.back)
self.forward_btn.clicked.connect(self.browser.forward)
self.layout.addLayout(self.horizontal)
self.layout.addWidget(self.browser)
self.browser.setUrl(QUrl("http://www.google.com"))
self.window.setLayout(self.layout)
self.window.show()
def navigate(self,url):
if not url.startswith("http"):
url = "http://" + url
self.url_bar.setText(url)
# redirect to your website
if "google.com" in url:
url = "http://stackoverflow.com"
self.browser.setUrl(QUrl(url))
app=QApplication([])
window=MyWebBrowser()
app.exec_()
If I create an html/javascript file called somefile, how will I upload that code to the browser?

Selenium fails to locate element even though it's loaded and not in an iframe

I'm trying to locate an element in a form, but for some reason Selenium keeps throwing an error saying it can't be found. Here is the simple code that I'm using. Can anyone decipher why this isn't working? It looks like a basic HTML form.
driver = uc.Chrome()
driver.get('https://www.stumblechat.com/register')
username = driver.find_element(By.ID, 'user')
There are 2 problems here:
You have to wait for element appearance. The best approach is to use WebDriverWait expected_conditions explicit waits.
That element has different locator. You probably looking for element located by this CSS Selector: input[name='username'].
If so, your code can be like following:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("start-maximized")
webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, service=webdriver_service)
wait = WebDriverWait(driver, 10)
url = "https://stumblechat.com/register"
driver.get(url)
username = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='username']")))

Python Selenium Popup

# Setup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchAttributeException, NoAlertPresentException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://am1.badoo.com/sv/mobile/")
driver.maximize_window()
username = "*************"
password = "*************"
print(driver.title)
time.sleep(5)
search = driver.find_element_by_xpath('//*[#id="header"]/div/div[2]/div/div[2]/a')
search = driver.find_element_by_partial_link_text('Logga in')
search.send_keys(Keys.RETURN)
time.sleep(5)
print("Login in")
search = driver.find_element_by_name('email')
search.send_keys(username)
search = driver.find_element_by_name('password')
search.send_keys(password)
time.sleep(2)
search = driver.find_element_by_xpath('//*[#id="page"]/div[1]/div[3]/section/div/div/div[1]/form/div[5]/div/div[1]/button').click()
time.sleep(5)
# klickar på like knappen
search = driver.find_element_by_xpath('//*[#id="mm_cc"]/div[1]/section/div/div[2]/div/div[2]/div[1]/div[1]').click()
time.sleep(1)
#popup
#Switch the control to the Alert window
search = driver.switch_to.alert
#Retrieve the message on the Alert window
message=search.text
print ("Alert shows following message: "+ message )
time.sleep(2)
# Or Dismiss the Alert using
search.dismiss()
Hey my question is that I cant understand how to handle a popup. Trying to make a automation for badoo the dating application. And when you like the first person a popup appers. But I cant find or firgure out how to connect that popup so I can click decline/ accept.
Can any one help me out?
Thanks in advance :)
Screen of popup:
Can't figure out how to copy html code, but this is screens of it:
If the popup has the same text and format every single time, you can use pyautogui(python library) to detect the popup and move the mouse to the position of "Nej" and click it.

Using Python 3.7 and Selenium, I can't figure out how to troubleshoot my code for out of Viewport elements

I am trying to use various methods to troubleshoot my code to figure out why I can't use the "actions.move_to_element" method to move to an offscreen element, and click on it.
I am trying to get this line of code:
Off_Screen_Element = driver.find_element_by_class_name("c-btn-cta")
to act on this HTML element, which I must scroll to see. It is a button to accept the conditions of me booking a class time:
<button class="c-btn-cta c-btn-cta--chevron modal-class-action js-terms-agreement-cta" data-class-action="book-class" data-class-action-step="class-action-confirmation" data-workout-id="205911" data-club-id="229" aria-disabled="false" data-waitlistable="true">Confirm</button>
I get no syntax error, but when I use this line of code:
print(Off_Screen_Element.text)
it returns nothing. No exception or error. Just nothing. What am I doing wrong?
The key chunk of code I am using is this. Note, some is commented out for trouble-shooting I am trying to do. There is a large chunk of code of this script I am not posting, as it is working fine.
import datetime
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
#Using Firefox to access the Web
profile = webdriver.FirefoxProfile()
#options = webdriver.FirefoxOptions()
#profile.set_preference("dom.disable_beforeunload", True)
profile.set_preference("dom.webnotifications.enabled", False)
profile.update_preferences()
#profile.set_preference("dom.push.enabled", False)
driver = webdriver.Firefox(firefox_profile=profile)
driver.maximize_window()
driver.find_element_by_id("js-workout-booking-agreement-input").click()
Off_Screen_Element = driver.find_element_by_class_name("c-btn-cta")
#actions = ActionChains(driver)
#actions.move_to_element(Off_Screen_Element).click()
print(Off_Screen_Element.text)
Edit: This is the entire script:
import datetime
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
#Using Firefox to access the Web
profile = webdriver.FirefoxProfile()
#options = webdriver.FirefoxOptions()
#profile.set_preference("dom.disable_beforeunload", True)
profile.set_preference("dom.webnotifications.enabled", False)
profile.update_preferences()
#profile.set_preference("dom.push.enabled", False)
driver = webdriver.Firefox(firefox_profile=profile)
driver.maximize_window()
# Open the website
driver.get('https://www.goodlifefitness.com/book-workout.html#no-redirect')
time.sleep(8)
# click on the sign in tab to get Login Window
driver.find_element_by_class_name('c-header__login-text').click()
# finding the Login Window User ID Box and sending the Login ID
User_ID = driver.find_element_by_class_name('js-login-email')
User_ID.send_keys('yyyyyyy')
#Finding the Login Window Password Box and sending the Password
Password = driver.find_element_by_class_name('js-login-password')
Password.send_keys('xxxxxxx')
#Finding the Login Window Log-In Button and Clicking on it
driver.find_element_by_class_name('js-login-submit').click()
#Pause a few seconds until the My Account Button appears
time.sleep(5)
#Find the unordered list that contains the 4th day (data-index 3) and then click on the element that is the 4th day
driver.find_element_by_xpath("//ul/li[#data-index='3']").click()
time.sleep(5)
Day_of_Timeslot = driver.find_element_by_xpath('//div[#id="day-number-4"]')
Precise_Timeslot = Day_of_Timeslot.find_element_by_xpath(".//li[#data-index='2']")
Actual_Button = Precise_Timeslot.find_element_by_xpath(".//button[#data-class-action='book-class']").click()
driver.find_element_by_id("js-workout-booking-agreement-input").click()
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button[data-class-action='book-class']"))).click()
#Off_Screen_Element = driver.find_element_by_class_name("c-btn-cta")
#actions = ActionChains(driver)
#actions.move_to_element(Off_Screen_Element).click()```
It seems element is not visible on the page. Use WebDriverWait() and wait for element_to_be_clickable() and following css selector for the button
print(WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button[data-class-action='book-class']"))).text)
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button[data-class-action='book-class']"))).click()
You need to import below libraries
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

Get specific informaion from html code

The idea is to collect all soundcloud users' id's (not names) who posted tracks that first letter is e.g. "f" in the period in our case of "past year".
I used filters on soundcloud and got results in the next URL: https://soundcloud.com/search/sounds?q=f&filter.created_at=last_year&filter.genre_or_tag=hip-hop%20%26%20rap
I found the first user's id ("wavey-hefner") in the follow line of html code:
<a class="sound__coverArt" href="/wavey-hefner/foreign" draggable="true">
I want to get every user's id from the whole html.
My code is:
import requests
import re
from bs4 import BeautifulSoup
html = requests.get("https://soundcloud.com/search/sounds?q=f& filter.created_at=last_year&filter.genre_or_tag=hip-hop%20%26%20rap")
soup = BeautifulSoup(html.text, 'html.parser')
for id in soup.findAll("a", {"class" : "sound_coverArt"}):
print (id.get('href'))
It returns nothing :(
The page is rendered in JavaScript. You can use Selenium to render it, first install Selenium:
pip3 install selenium
Then get a driver e.g. https://sites.google.com/a/chromium.org/chromedriver/downloads (if you are on Windows or Mac you can get a headless version of Chrome - Canary if you like) put the driver in your path.
from bs4 import BeautifulSoup
from selenium import webdriver
import time
browser = webdriver.Chrome()
url = ('https://soundcloud.com/search/sounds?q=f& filter.created_at=last_year&filter.genre_or_tag=hip-hop%20%26%20rap')
browser.get(url)
time.sleep(5)
# To make it load more scroll to the bottom of the page (repeat if you want to)
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
html_source = browser.page_source
browser.quit()
soup = BeautifulSoup(html_source, 'html.parser')
for id in soup.findAll("a", {"class" : "sound__coverArt"}):
print (id.get('href'))
Outputs:
/tee-grizzley/from-the-d-to-the-a-feat-lil-yachty
/empire/fat-joe-remy-ma-all-the-way-up-ft-french-montana
/tee-grizzley/first-day-out
/21savage/feel-it
/pluggedsoundz/famous-dex-geek-1
/rodshootinbirds/fairytale-x-rod-da-god
/chancetherapper/finish-line-drown-feat-t-pain-kirk-franklin-eryn-allen-kane-noname
/alkermith/future-low-life-ft-the-weeknd-evol
/javon-woodbridge/fabolous-slim-thick
/hamburgerhelper/feed-the-streets-prod-dequexatron-1000
/rob-neal-139819089/french-montana-lockjaw-remix-ft-gucci-mane-kodak-black
/pluggedsoundz/famous-dex-energy
/ovosoundradiohits/future-ft-drake-used-to-this
/pluggedsoundz/famous
/a-boogie-wit-da-hoodie/fucking-kissing-feat-chris-brown
/wavey-hefner/foreign
/jalensantoy/foreplay
/yvng_swag/fall-in-luv
/rich-the-kid/intro-prod-by-lab-cook
/empire/fat-joe-remy-ma-money-showers-feat-ty-dolla-ign