Automatic timing transmission through selenium
Look at the overall code more. In fact, it's not much or difficult. It's just that I have a lot of code comments (my habit).
Sorry, the content of the article may be a little too much. In fact, I spend more time writing blog than writing code!
Let me be long winded. First use the trumpet to experiment, the lesson of tears! (I'm too confident)
I Programming idea and process
Enter QQ space.
# Prevent printing useless logs option = webdriver.ChromeOptions() option.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging']) # Use Google browser or you can also use Edge and Firefox driver = webdriver.Chrome(chrome_options=option) # Driver = webdriver is not used here Chrome (), because it will print a lot of useless logs #window maximizing driver.maximize_window() #Open QQ space website driver.get("https://i.qq.com")
2. Switch frames.
The window here is an iframe framework. If we want to locate the elements inside, we must first switch from the main framework to the iframe framework here
driver.switch_to.frame("login_frame") #When you enter the frame, you can directly switch between id and name attributes
3. Log in to QQ space.
First check whether the computer has logged in to QQ. If you log in, log in to QQ space directly; Otherwise, log in with account and password
If you choose an account and password to log in, don't forget to fill in your account and password in the code
After careful observation, you will find that if you log in to QQ on the computer, there will be another < a > tag, so you can judge whether you log in to QQ. If you log in, you can directly locate the a tag and click it to complete the automatic login; If not, locate the "account and password login" in turn, click -- > enter account in the "account box -- > enter password in the" password box -- > click the "login" option
try: #Determine whether a tag exists element=driver.find_element_by_xpath("//div[@class='qlogin_list']/a") #Or directly drive find_ element_ by_ xpath("//div[@class='qlogin_list']/a") ''' If it exists a Tag, continue to execute the following code and log in automatically Otherwise NoSuchElementException Exception, handle the exception directly, and log in with account and password NoSuchElementException: The element cannot be located, that is, the element does not exist, resulting in an exception ''' #Method 1: automatic login (only after QQ has been logged in on the computer) driver.find_element_by_xpath("//div[@class='qlogin_list']/a").click() # Or driver find_ element_ by_ class_ name("login"). click() except NoSuchElementException: # Method 2: enter the account and password to log in # Select account and password to log in driver.find_element_by_id("switcher_plogin").click() # Enter your qq account in the account box driver.find_element_by_id("u").send_keys("Your account number") # Enter the password in the password box driver.find_element_by_id("p").send_keys("Your password") # Click the login button driver.find_element_by_id("login_button").click() finally: print("Login successful") time.sleep(2) #Make sure you're logged in
4. Click to enter the talk page.
ps: Here's a reminder. Try the trumpet first, otherwise you will understand. Since then, I have used the trumpet for demonstration
Here, the < a > tag has no id and class attributes and cannot be located based on them, but link can be used_ Text to locate the text, or use xpath to locate layer by layer according to the path. First locate the < div > or < ul > tag on its outer layer, then locate < li > and finally < a >. The reason why < li > cannot be located directly is that Li and ul are integrated. The ul level is higher than Li, so it must be located to ul first
#Click the talk tab to talk about it driver.find_element_by_xpath("//div[@class='head-nav']/ul/li[5]/a").click() #This can be a driver find_ element_ by_ link_ Text ("talk") click() #This doesn't work, driver find_ element_ by_ xpath("//li[@class='menu_item_311']/a")
5. Write and talk
- Switch frames first. You can see that the area for writing and talking is located in the iframe framework.
''' there iframe No, id and name Property, but with class attribute So use it here class location iframe,Switch frames after positioning ''' frame1 = driver.find_element_by_css_selector("iframe.app_canvas_frame") #Switch frame driver.switch_to.frame(frame1) time.sleep(2) #Switching frames takes some time
- Locate and click the text box. We can think about it. When writing and talking, we first point to the content area and fill in the content when the cursor appears. The same is true here
''' Before filling in the talk content, you need to position the mouse in the talk text box. ''' #Positioning text box driver.find_element_by_xpath("//div[@class='textinput textarea c_tx3']").click() #You can also use driver find_ element_ by_ id("$1_substitutor_content"). click() time.sleep(2) #Fill in the content driver.find_element_by_id('$1_content_content').send_keys("hello everyone! This is a pass selenium Automatic timing transmission")
6. Regular release (slightly troublesome)
Timing here, not difficult, just troublesome. The whole article is a little too much. I can't say more. Just be concise.
#Select scheduled Publishing driver.find_element_by_xpath("//*[@class='sync-timing evt_click']").click() driver.find_element_by_link_text("Set publishing time").click()
Note that the pop-up window is in the main frame, not in the previous iframe frame, so go back to the main frame first
When we select the drop-down box, we find that we have entered the new iframe framework again
#Regular publishing needs to return to the main framework first driver.switch_to.default_content() time.sleep(1) #Then enter an iframe pop-up frame and select the time of regular release driver.switch_to.frame("popup_dialog_frame") #With id attribute, switch directly time.sleep(1)
#Select the number of days to publish driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='date']").click() #Option of the day [1] the first option is the day driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='date']/option[1]").click() #Select the hours to publish driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='hours']").click() #0~23 option[24] at 23:00, i.e. 23:00 driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='hours']/option[24]").click() #Select the minutes to publish driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='minutes']").click() #20 points 0-59 option[21], i.e. 20 points driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='minutes']/option[21]").click()
At this time, we should think of one thing. What if our fixed time has expired? My processing is to cancel the scheduled direct release when it expires
We can judge whether the timing has expired according to whether there is text content in the indicated position in the picture
judge_time=0 #Judge whether the timing is carried out. 0 is to be timed, and non-0 is not ''' If the timing does not expire, select OK; Otherwise, select Cancel timing. If the timing expires, there will be a text prompt at the specified location, Therefore, we only need to judge whether the text in this position is empty to judge whether it has expired. ''' if driver.find_element_by_xpath("//div[@class='tips tips_nobbor tips_highlight tips_icon icon_hint']").text == '': #Not expired, click OK driver.find_element_by_xpath("//a[@class='mod_btn mod_btn_sub']").click() else: #Expired, click Cancel driver.find_element_by_xpath("//a[@class='mod_btn mod_btn_nor']").click() #No timing judge_time=1
7. Make a statement (with key points)
Don't forget! Before we enter the timed pop-up window, we are also in an iframe frame
Therefore, to return to the previous iframe framework, we must first return to the main framework and then enter iframe
#Back to the main frame driver.switch_to.default_content() time.sleep(0.5) #The iframe here has no id and name attributes, so you need to locate the iframe first, and then switch after positioning frame = driver.find_element_by_css_selector("iframe.app_canvas_frame") driver.switch_to.frame(frame) time.sleep(1)
Here's the point!
#Click in the blank, otherwise you will not be able to locate the post (save) option later driver.find_element_by_xpath("//div[@class='bor mod-tab author_display']").click() time.sleep(0.5)
Here's a reminder. If we don't expire on time, the text content here will change from "publish" to "save", and others will remain unchanged. So don't use link_ Textpositioned
''' #Click the publish (save) option to publish. Here, because the text content is downloaded at irregular times, the text content after timing becomes saved, So it's not used here link_text Positioning. ''' driver.find_element_by_xpath("//a[@class='btn-post gb_bt evt_click']/span[@class='txt']").click()
If it is successfully released regularly, there will be a pop-up prompt
''' judge_time A value of 0 indicates that the timing is to be confirmed, and a pop-up window will pop up for final confirmation, If it is not 0, there will be no pop-up window and publish directly without considering other issues In fact, it doesn't matter if you don't confirm it, because it's already scheduled. ''' if judge_time == 0: #Back to the main frame driver.switch_to.default_content() #The delay here should be longer than 3s time.sleep(4) #The pop-up window here is div style, so there is no need to enter the iframe framework and other operations. #Therefore, the simplest positioning method is directly adopted here_ text. . driver.find_element_by_link_text("confirm").click() print("Published successfully")
II Complete code
import time from selenium import webdriver from selenium.common.exceptions import NoSuchElementException # Prevent printing useless logs option = webdriver.ChromeOptions() option.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging']) # Use Google browser or Edge, Firefox driver = webdriver.Chrome(chrome_options=option) # Driver = webdriver is not used here Chrome (), because it will print a lot of useless logs #window maximizing driver.maximize_window() #Open QQ space website driver.get("https://i.qq.com") #try is used here. If there is a problem in the process, execute finally directly and close the window after 3s try: driver.switch_to.frame("login_frame") #Enter frame frame try: #Determine whether a tag exists element=driver.find_element_by_xpath("//div[@class='qlogin_list']/a") #Or directly drive find_ element_ by_ xpath("//div[@class='qlogin_list']/a") ''' If it exists a Tag, continue to execute the following code and log in automatically Otherwise NoSuchElementException Exception, handle the exception directly, and log in with account and password NoSuchElementException: The element cannot be located, that is, the element does not exist, resulting in an exception ''' #Method 1: automatic login (only after QQ has been logged in on the computer) driver.find_element_by_xpath("//div[@class='qlogin_list']/a").click() # Or driver find_ element_ by_ class_ name("login"). click() except NoSuchElementException: # Method 2: enter the account and password to log in # Because the table is in the iframe, you need to enter the iframe #driver.switch_to.frame("login_frame") # Find the frame entry # Select account and password to log in driver.find_element_by_id("switcher_plogin").click() # Enter your qq account in the account box driver.find_element_by_id("u").send_keys("Your account number") # Enter the password in the password box driver.find_element_by_id("p").send_keys("Your password") # Click the login button driver.find_element_by_id("login_button").click() finally: print("Login successful") time.sleep(2) #After logging in, it is a new page, which is already the main frame. There is no need to switch back to the main frame #Click the talk tab to talk about it driver.find_element_by_xpath("//div[@class='head-nav']/ul/li[5]/a").click() #driver.find_element_by_link_text("talk") click() #driver.find_element_by_xpath("//li[@class='menu_item_311']/a") doesn't work time.sleep(1) ''' there iframe No, id and name Property, but with class attribute So use it here class location iframe,Switch frames after positioning ''' frame1 = driver.find_element_by_css_selector("iframe.app_canvas_frame") #Switch frame driver.switch_to.frame(frame1) time.sleep(2) ''' Before filling in the talk content, you need to position the mouse in the talk text box. ''' #Positioning text box #You can also use driver find_ element_ by_ id("$1_substitutor_content"). click() driver.find_element_by_xpath("//div[@class='textinput textarea c_tx3']").click() time.sleep(2) #Fill in the content driver.find_element_by_id('$1_content_content').send_keys("hello everyone! This is a pass selenium Automatic timing transmission") #Select scheduled Publishing driver.find_element_by_xpath("//*[@class='sync-timing evt_click']").click() driver.find_element_by_link_text("Set publishing time").click() #Regular publishing needs to return to the main framework first driver.switch_to.default_content() time.sleep(1) #Then enter an iframe pop-up frame and select the time of regular release driver.switch_to.frame("popup_dialog_frame") time.sleep(1) #Select the number of days to publish driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='date']").click() driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='date']/option[1]").click() # current day #Select the hours to publish driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='hours']").click() driver.find_element_by_xpath("//Div [@ class ='mod_cont '] / P [@ id ='datesel'] / select [@ id ='hours'] / option [24] "). Click() #23 #Select the minutes to publish driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='minutes']").click() driver.find_element_by_xpath("//div[@class='mod_cont']/p[@id='dateSel']/select[@id='minutes']/option[21]").click() #20 points judge_time=0 #Judge whether the timing is carried out. 0 is to be timed, and non-0 is not ''' If the timing does not expire, select OK; Otherwise, select Cancel timing. If the timing expires, there will be a text prompt at the specified location, Therefore, we only need to judge whether the text in this position is empty to judge whether it has expired. ''' if driver.find_element_by_xpath("//div[@class='tips tips_nobbor tips_highlight tips_icon icon_hint']").text == '': #Not expired, click OK driver.find_element_by_xpath("//a[@class='mod_btn mod_btn_sub']").click() else: #Expired, click Cancel driver.find_element_by_xpath("//a[@class='mod_btn mod_btn_nor']").click() #No timing judge_time=1 #Back to the main frame driver.switch_to.default_content() time.sleep(0.5) #The iframe here has no id and name attributes, so you need to locate the iframe first, and then switch after positioning frame = driver.find_element_by_css_selector("iframe.app_canvas_frame") driver.switch_to.frame(frame) time.sleep(1) #Click in the blank, otherwise you will not be able to locate the post (save) option later driver.find_element_by_xpath("//div[@class='bor mod-tab author_display']").click() time.sleep(0.5) ''' #Click the publish (save) option to publish. Here, because the text content is downloaded at irregular times, the text content after timing becomes saved, So it's not used here link_text Positioning. ''' driver.find_element_by_xpath("//a[@class='btn-post gb_bt evt_click']/span[@class='txt']").click() ''' judge_time A value of 0 indicates that the timing is to be confirmed, and a pop-up window will pop up for final confirmation, If it is not 0, there will be no pop-up window and publish directly without considering other issues In fact, it doesn't matter if you don't confirm it, because it's already scheduled. ''' if judge_time == 0: #Back to the main frame driver.switch_to.default_content() #The delay here should be longer than 3s time.sleep(4) #The pop-up window here is div style, so there is no need to enter the iframe framework and other operations. #Therefore, the simplest positioning method is directly adopted here_ text. . driver.find_element_by_link_text("confirm").click() print("Published successfully") finally: #If there is a problem, close the window after 3s and exit QQ space #After 3s, close QQ space time.sleep(3) driver.quit()
III Summary and suggestions
In fact, there are many defects in the code. You can improve it
For example: sleep(),You shouldn't have used this, sleep Is precisely timed, that is to say If someone nets faster, he can sleep The time can be shorter; If the Internet is slow, it will take a little longer. You can take a look at the display wait and implicit wait to try to change sleep.
Selenium seems to me to be very simple. I just learned a little and just played, so I don't need to delve into the code of selenium why I did this.
- If you use sleep, you must consider your own network factors (i.e. insufficient delay) and whether the failure is caused by the network.
- I suggest you think more about using xpath. When you fail to locate with id, class, etc., you might as well try xpath. Maybe you will be surprised.
If there are questions about the content of the article, you can leave a message. If there are questions, you can also leave a message. I'll try my best to answer them.