I am using Selenium to clear old text in a text area before input new text in a web browser. This is my code:
MY_UDP_SESSION = 32768
elem = driver.find_element_by_id("udp-session-quota").clear()
time.sleep(1)
elem.send_keys(MY_UDP_SESSION)
but I see this error:
'NoneType' object has no attribute 'send_keys'
clear()
clear() clears the text if it's a text entry element and is defined as:
def clear(self):
"""Clears the text if it's a text entry element."""
self._execute(Command.CLEAR_ELEMENT)
As clear() doesn't returns anything hence as per your line of code:
elem = driver.find_element_by_id("udp-session-quota").clear()
elem is assigned as null i.e. NoneType. Moving forward when you try to invoke send_keys() on elem:
elem.send_keys(MY_UDP_SESSION)
You see the error.
Solution
Once the WebElement is returned then you can invoke clear() and send_keys() as follows:
MY_UDP_SESSION = "32768"
elem = driver.find_element_by_id("udp-session-quota")
elem.clear()
elem.send_keys(MY_UDP_SESSION)
Related
I'm trying to run spyder to extract real estate advertisements informaiton.
My code:
import scrapy
from ..items import RealestateItem
class AddSpider (scrapy.Spider):
name = 'Add'
start_urls = ['https://www.exampleurl.com/2-bedroom-apartment-downtown-4154251/']
def parse(self, response):
items = RealestateItem()
whole_page = response.css('body')
for item in whole_page:
Title = response.css(".obj-header-text::text").extract()
items['Title'] = Title
yield items
After running in console:
scrapy crawl Add -o Data.csv
In .csv file I get
['\n 2-bedroom-apartment ']
Tried adding strip method to function:
Title = response.css(".obj-header-text::text").extract().strip()
But scrapy returns:
Title = response.css(".obj-header-text::text").extract().strip()
AttributeError: 'list' object has no attribute 'strip'
Is there are some easy way to make scrapy return into .csv file just:
2-bedroom-apartment
AttributeError: 'list' object has no attribute 'strip'
You get this error because .extract() returns a list, and .strip() is a method of string.
If that selector always returns ONE item, you could replace it with .get() [or extract_first()] instead of .extract(), this will return a string of the first item, instead of a list. Read more here.
If you need it to return a list, you can loop through the list, calling strip in each item like:
title = response.css(".obj-header-text::text").extract()
title = [item.strip() for item in title]
You can also use an XPath selector, instead of a CSS selector, that way you can use normalize-space to strip whitespace.
title = response.xpath('normalize-space(.//*[#class="obj-header-text"]/text())').extract()
This XPath may need some adjustment, as you didn't post the source I couldn't check it
In the code mentioned I am trying to get value of "text" which is inside the function . Outside of a function with one variable "A" but here I am not getting anything.Can anyone help me on this issue please
Also when I am writing print statement inside the function it is printing the value
enter code here
from tkinter import *
window = Tk()
window.geometry('500x500')
def callback(self):
text = No_of_chances.get()
return text
No_of_chances = Entry(window)
No_of_chances.place(x=50, y=300)
No_of_chances.bind('<Return>', callback)
A=text
print(A)
window.mainloop()
The text variable is not defined when you try to do A=text this is because the function callback() is only called when the enter button is pressed. Therefore text does not exist when you try to assign it to A
The callback function works perfectly fine, it gets the current string within the Number_of_chances Entry you have, and returns it.
That being said your question is very unclear, since you provide no context to what you want to do with the text you get from the Entry when you press enter, if you provide some context I or someone else might be able to help fix your problem better.
Here is a solution so then A will contain the value you want.
from tkinter import *
window = Tk()
window.geometry('500x500')
text = ""
def callback(event):
text = No_of_chances.get()
print(text)
return text
No_of_chances = Entry(window)
No_of_chances.place(x=50, y=300)
No_of_chances.bind('<Return>', callback)
A=text
print(A)
window.mainloop()
I am made this simple whatsapp bot using python and selenium.
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://web.whatsapp.com/')
target = "Someone"
msg = "Something"
input('Press Enter after scanning QR Code...')
TargetXML = driver.find_element_by_xpath('//span[#title = "
{}"]'.format(target))
TargetXML.click()
MsgBox = driver.find_elements_by_class_name('_1Plpp')
MsgBox[0].send_keys(msg)
SendButton = driver.find_elements_by_class_name('_35EW6')
SendButton[0].click()
At first run, I had MsgBox.send_keys(msg) and SendButton.click() instead of what you see in the script which gave an error AttributeError: 'list' object has no attribute 'send_keys' and AttributeError: 'list' object has no attribute 'click'.
I changed them to index 0 which solved the error and the script worked perfectly fine but I couldn't really understand why it worked with the element in 0th index so I tried to print the element and got the output as <selenium.webdriver.remote.webelement.WebElement (session="bd86fe53729956ba1fc3b16cf841a1a8", element="0.5125252686493715-2")> I am still not convinced with it and have that question in mind. Any help would be appreciated! Thank you!
The method 'find_elements_by_class_name' returns a list of elements that satisfy the class name in the parameter. This list consists of WebElement when you select the 0th element, you get the object of WebElement, over which you can apply the methods send_keys() and click().
For more information on Selenium and WebElement object refer to this documentation.
I am having some issues wrapping my head around something I encountered in python recently.
So, basically, I want to allow for a user to load several json files, all listed in a python list. These files contain parameters used to create buttons with, namely, the color the button should have, the text that should be displayed in it and the command that it needs to execute once clicked.
def createTags(self):
for items in self.LoadedInstallProfiles:
with open(items, "r") as jsonfiles:
self.loadeddata = json.load(jsonfiles)
self.tag = Button(self.tagmenu, text=self.loadeddata.get("profilename"), background=
self.loadeddata.get("profilecolor"), command=print(self.loadeddata.get("profilename")))
self.tag.pack(side="top",fill="x")
The problem is: the buttons show up with their individual color and text, but all seem to print out the same profilename when clicked, which is that in the last json file in the list.
I common way is to store the created button widgets in a list. I have modified your method. See below.
def createTags(self):
# First create the widget and append to list variable
self.tags = [] #List to store button widgets
for items in self.LoadedInstallProfiles:
with open(items, "r") as jsonfiles:
loadeddata = json.load(jsonfiles)
text = loadeddata.get("profilename")
bg = loadeddata.get("profilecolor")
tag = Button( self.tagmenu, text=text, background=bg, command=print(text) )
self.tag.append( tag )
# Then display the widgets
for tag in self.tags:
tag.pack(side="top",fill="x")
I imagine the problem with command=print(self.loadeddata.get("profilename")) is similar to the problem with lambda statements (that said I am surprised your buttons work at all They should print once at init and then never work after that because you are calling print at button creation instead of saving a reference to print).
Due to the nature of how lambda works here in a loop like this you end up only printing the last value in the loop for all commands. Instead you need to use a lambda statement and also define the value in the lambda for each loop to accurately record the correct data for the print statement.\
I created 3 test files for this:
test.json:
{"profilename":"test", "profilecolor": "green"}
test2.json:
{"profilename":"test2", "profilecolor": "blue"}
test3.json:
{"profilename":"test3", "profilecolor": "orange"}
Example code:
import tkinter as tk
import json
class Window(tk.Tk):
def __init__(self):
super().__init__()
self.btn_list = []
for file in ['test.json', 'test2.json', 'test3.json']:
with open(file, 'r') as f:
self.btn_list.append(json.load(f))
self.create_tags()
def create_tags(self):
for item in self.btn_list:
tk.Button(self, text=item.get("profilename"), background=item.get("profilecolor"),
command=lambda x=item.get("profilename"): print(x)).pack(side="top", fill="x")
if __name__ == '__main__':
Window().mainloop()
Results:
i am new to Python + tkinter
I am trying to enter values into a text widget using FOR loop
The problem is, text widget not showing anything during For loop execution. When for loop finishes, it shows all values.
How can I show inserted values during for loop.
See last line of code
for item in liList:
listDict = {}
# get a tag href
listATag = item.find_all("a", attrs={"class": "product-image"})[0]
listATagHref = listATag['href']
listDict["purchaseLink"] = listATagHref
imgPageRequest = requests.get(listATagHref)
imgPageData = imgPageRequest.text
imgPageSoup = BeautifulSoup(imgPageData, 'lxml')
try:
productImgDiv = imgPageSoup.find_all('div', attrs={"class": "product-image"})[0]
imgATag = productImgDiv.find_all('a')[0]['href']
largeThumbFileName = (imgATag.split('/')[-1])
tempImgNameList.append(largeThumbFileName)
print(listATagHref)
textBox.insert(END,listATagHref+'\n')
etc...
You need to call update on the widget you are adding new data to, for it to refresh and show the new values after each iteration. This is as the Tk mainloop will normally catch the new information on your widget and update it, but when you are in a loop such as this, it cannot check until after the loop is finished.
If root is what you define to be Tk(), then you can call root.update(), or on the actual widget itself. This would go at the end of your for loop.
aside from updating the window, or the text widget you can change the first argument of your textbox from END to INSERT.
import tkinter as tk
# inside the try block change the first argument to INSERT
textBox.insert(tk.INSERT,listATagHref+'\n')