Background
Let’s study the Python + Selenium automated testing framework, and simply implement automated batch uploading and publishing of videos on Mac, and share them with students who need them (without doing too much exception handling).
Script implementation
First log in with your manual mobile phone number and save the cookie file of the Xigua Video website.
Then load the cookie content, use a script to upload videos in batches, and save them to drafts (it can also be automatically published for secondary editing, such as modifying the cover)
Finally, the draft video is published by traversing the video draft list. PS: If too many videos are uploaded or published on the same day, the video will be limited by Xigua Video.
Installation dependencies
# Install dependencies Save website cookies # Install chromedriver $ brew install chromedriver
Script content
#!/usr/bin/python # -*- coding: utf-8 -*- import time import json import os import shutil importsys from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver import ActionChains from pykeyboard import PyKeyboard from pymouse import PyMouse import pyperclip class XiGua: """ Mac Xigua Video automatically uploads videos and publishes drafts """ def __init__(self): """ Initialize, open the browser """ self.driver = webdriver.Chrome() def save_cookies(self, cookies_file_name): """ save cookies cookies_file_name: cookies file name """ # Reserve 20 seconds for manual login time.sleep(20) # After successful login, save the cookies file with open(cookies_file_name, 'w') as cookies_file: cookies_file.write(json.dumps(self.driver.get_cookies())) def load_cookies(self, cookies_file_name): """ Load cookies cookies_file_name: cookies file name """ # Load cookies file with open(cookies_file_name, 'r') as cookies_file: cookies_list = json.load(cookies_file) for cookies in cookies_list: if 'expiry' in cookie: del cookie['expiry'] self.driver.add_cookie(cookie) # After loading the cookie, refresh the page to take effect. self.driver.refresh() def is_exist_element_by_xpath(self, xpath): """ Determine whether the element exists """ flag = True try: self.driver.find_element_by_xpath(xpath) return flag except Exception as e: flag=False print("xpath: [%s] element does not exist, error: %s" % xpath, e) return flag def upload_video(self, video_file_path): """ Upload video video_file_path: upload video path """ #Open the upload video page self.driver.get("https://studio.ixigua.com/upload?from=post_article") # Click to upload self.driver.find_element_by_class_name("byte-upload-trigger-drag").click() time.sleep(5) # Select video file k = PyKeyboard() m = PyMouse() # Open k.press_keys(['Command', 'Shift', 'G']) x_dim, y_dim = m.screen_size() k.press_keys(['Shift']) m.click(x_dim // 2, y_dim // 2, 1) #Copy video file path pyperclip.copy(video_file_path) # Paste k.press_keys(['Command', 'V']) time.sleep(2) k.press_key('Return') time.sleep(2) k.press_key('Return') time.sleep(2) # Set reprint options self.driver.find_element_by_xpath( '//*[@id="js-video-list-content"]/div/div[2]/div[4]/div[2]/div/div/label[2]/span/span') .click() time.sleep(1) # Sync to Douyin # self.driver.find_element_by_class_name("byte-checkbox-mask").click() # Loop to determine whether the video upload is successful. If it is not successful, wait for 10 seconds and then determine again until it is successful. while 'Upload successful' not in self.driver.find_element_by_xpath( '//*[@id="js-video-list-content"]/div/div[1]/div[1]/div[2]/div[2]').text: print("Loop waiting for the video to be uploaded successfully, wait 10 seconds") time.sleep(10) # Set video cover self.driver.find_element_by_class_name("m-xigua-upload").click() print('Click-upload cover') time.sleep(5) try: reload = self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div[1]/div/div/div/div[2]') # Video cover parsing failure processing, loop refresh if reload != '': print('Video cover analysis failure processing, start cycle refresh') while XiGua.is_exist_element_by_xpath(self, '/html/body/div[3]/div/div[2]/div/div[1]/div/div/div/div[2]'): # Click to loop self.driver.find_element_by_xpath( '/html/body/div[3]/div/div[2]/div/div[1]/div/div/div/div[2]').click() print('After the refresh fails, wait 5 seconds and refresh again') time.sleep(5) # Select the first image img = self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div[1]/div/div/div[1]/img') img.click() except Exception as e: print('Cover parsing is normal, no need to refresh') pass # Next step cover_next_element = WebDriverWait(self.driver, 30).until( lambda x: x.find_element_by_xpath( '/html/body/div[3]/div/div[2]/div/div[2]/div') ) cover_next_element.click() print('Click-Cover Next') try: # Complete cropping cover_crop_element = WebDriverWait(self.driver, 30).until( lambda x: x.find_element_by_xpath( '//*[@id="tc-ie-base-content"]/div[2]/div[2]/div[2]/div/div[2]/div/div/div[2]' ) ) if cover_crop_element != '': cover_crop_element.click() print('Click-Cover completed cropping') else: print('Cover does not need to be cropped') except Exception as e: print('An exception occurred when cutting the cover: %s' % e) pass time.sleep(5) # Sure self.driver.find_element_by_xpath('//*[@id="tc-ie-base-content"]/div[2]/div[2]/div[3]/div[3]/button[2]' ).click() print('Click-Cover Confirm') time.sleep(1) # Confirm again self.driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/div/div[2]/button[2]').click() print('Click-confirm the cover again') time.sleep(5) # Save draft draft_element = WebDriverWait(self.driver, 30).until( lambda x: x.find_element_by_xpath('//*[@id="js-submit-draft-0"]/button') ) action = ActionChains(self.driver) print('Click-Save Draft') # Move the scroll bar to the bottom js = "window.scrollTo(0,document.body.scrollHeight)" self.driver.execute_script(js) # Move to Save Draft button click action.move_to_element(draft_element).click().perform() def close(self): """ Close browser """ self.driver.close() def batch_upload(self, videos_dir_path): """ Upload videos in batches videos_dir_path: upload video storage path """ files = os.listdir(videos_dir_path) # Sort the upload in descending order. When the draft is published, the video serial number is in order. files.sort(reverse=True) #Batch upload videos for file in files: if os.path.slitext(file)[1] == '.mp4': full_file_path = os.path.join(videos_dir_path, os.path.splitext(file)[0]) print("==Start uploading video: %s" % full_file_path) self.upload_video(full_file_path) src = os.path.join(videos_dir_path, file) dst = os.path.join(videos_dir_path, 'bak', file) # After publishing is completed, move to the backup directory shutil.move(src, dst) def videos_release(self): """ Draft video release """ self.driver.get("https://studio.ixigua.com/content") time.sleep(2) # Click on draft navigation draft_navigation_element = WebDriverWait(self.driver, 30).until( lambda x: x.find_element_by_xpath('//*[@id="app"]/div/section/div/div[1]/ul/li[3]') ) draft_navigation_element.click() print('Click-Draft Navigation') time.sleep(2) # Draft list draft_elements = self.driver.find_elements_by_class_name('content-card__title ') # If the draft list is empty, exit if len(draft_elements) == 0: print("Draft list is empty") XiGua.close(self) sys.exit() # Publish drafts in a loop, publishing the first one each time for i in range(1, 99999): # The draft list is empty, exit if draft_elements == '': print('Draft publishing completed, total: %s' % str(i)) XiGua.close(self) sys.exit() print('Current release quantity %s, release video: %s' % (str(i), draft_elements[0].text)) # Publish the first video of the draft draft_elements[0].click() time.sleep(3) # Publish now element2 = WebDriverWait(self.driver, 30).until( lambda x: x.find_element_by_xpath('//button[contains(text(), "Publish")]') ) element2.click() print('Click-Video Publish') # Determine whether publishing failed, such as the title is too long try: # Error handling if XiGua.is_exist_element_by_xpath(self, '/html/body/div[3]/div/div/div/span'): print('An error occurred in publishing, exit, please check for errors, such as the title is too long, etc.') sys.exit() except Exception as e: print('Draft publishing exception: %s' % e) pass # Handle low cover resolution prompts try: # Cover resolution is low cover_cancel_element = self.driver.find_element_by_xpath('//div[contains(text(), "Cancel")]') print('Cover resolution is low, cancel directly') # Error handling if cover_cancel_element != '': print('cancel cover resolution is low') cover_cancel_element.click() # Publish now cover_publish_element = WebDriverWait(self.driver, 30).until( lambda x: x.find_element_by_xpath('//button[contains(text(), "Publish")]') ) cover_publish_element.click() except Exception as e: print('An exception occurred due to low cover resolution: %s' % e) pass # Click on draft draft_publish_element = WebDriverWait(self.driver, 30).until( lambda x: x.find_element_by_xpath('//*[@id="app"]/div/section/div/div[1]/ul/li[3]') ) draft_publish_element.click() time.sleep(2) print('Reacquire draft list') draft_elements = self.driver.find_elements_by_class_name('content-card__title ') print(draft_elements) def xigua_videos_release(self, base_url, cookies_file_path): """ Xigua video release draft base_url: Xigua video website cookies_file_path: Xigua Video cookies file path """ self.driver.get(base_url) # Load cookies XiGua.load_cookies(self, cookies_file_path) #Draft release video XiGua.videos_release(self) # Close browser XiGua.close(self) def xigua_batch_upload(self, base_url, cookies_file_path, videos_dir_path): """ Xigua Video releases videos in batches base_url: Xigua video website cookies_file_path: Xigua Video cookies file path videos_dir_path: upload video storage path """ self.driver.get(base_url) XiGua.load_cookies(self, cookies_file_path) XiGua.batch_upload(self, videos_dir_path) XiGua.close(self) def xigua_save_cookies(self, base_url, cookies_file_path): """ Save website cookies base_url: website address cookies_file_path: website cookies file path """ self.driver.get(base_url) # Save cookies XiGua.save_cookies(self, cookies_file_path) XiGua.close(self) if __name__ == '__main__': xi_gua = XiGua() #西瓜视频 base_url = 'https://www.ixigua.com/' xigua_cookies = '/tmp/xigua_update_video/xigua_cookies.txt' videos_dir_path = '/tmp/rm' ## 1. Save cookie # xi_gua.xigua_save_cookies(base_url, 'xigua_cookies.txt') ## 2. Batch upload xi_gua.xigua_batch_upload(base_url, xigua_cookies, videos_dir_path) ## 3. Publish drafts in batches # xi_gua.xigua_videos_release(base_url, xigua_cookies)
Finally, I would like to thank everyone who read my article carefully. Reciprocity is always necessary. Although it is not a very valuable thing, if you can use it, you can take it directly:
This information should be the most comprehensive and complete preparation warehouse for [software testing] friends. This warehouse has also accompanied tens of thousands of test engineers through the most difficult journey. I hope it can also help you!
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Python entry skill treeWeb crawlerSelenium386405 people are learning the system