1. Introduction
The technology used in this article is only used for learning and research, and any other use should be at your own risk.
The python library used in 12306 automatic ticket checking is mainly splinter, and it also involves the city code of ticket checking. Please search for the specific city code on the Internet. The basic format is as follows:
Beijing North: VAP
Beijing East: BOP
Beijing: BJP
Beijing South: VPN
Beijing West: BXP
The implemented functions include:
(1) Automatically open the Google browser and enter the 12306 login page
(1) Manually enter the account number, password, departure, destination, time and other related information on the command line. The login verification picture needs to be manually selected.
(2) Automatically fill in the input, complete the query and page jump.
Features that can be optimized later:
(1) Read the account, password, departure, destination, time and other related information from the configuration file.
(2) Get the city code from the configuration file
(3) The login verification picture can be automatically selected using third-party identification
2. Getting to know Splinter for the first time
1 Introduction
Splinter is an open source web automation testing toolset developed in Python. It can help you automate browser behavior, such as browsing URLs and interacting with pages.
Splinter is an abstraction layer automation tool on top of existing browsers (such as Selenium, PhantomJS and zope.testbrowser ). It has a high-level API, which makes it easy to write automated tests for web applications.
For example, to fill out a form item with Splinter:
browser.fill('username', 'janedoe')
In Selenium, the equivalent code would be:
elem = browser.find_element.by_name('username')
elem.send_keys('janedoe')
2. Installation
Execute the following command on the command line: sudo pip install splinter
3. Get started quickly
(1) Import the Browser class
from splinter.browser import Browser
(2) Create an instance
Specify the driver as the chrome browser. If you do not specify the driver for the Browser, firefox will be used by default.
browser = Browser(driver_name='chrome',executable_path='xxx')
The executable_path is the local directory of the corresponding browser driver.
(3) Visit Baidu search page
Use the browser.visit method to visit any website:
browser.visit('http://baidu.com')
(4) Enter search keywords
After the page is loaded, you can fill in the fields in the input box. Let's search for the 2018 New Year's greetings for the new year:
browser.fill('wd', '2018年新年祝福')
(5) Click the search button
Splinter can be identified by the css, xpath, id, tag or name of the button. Baidu search button uses the following operations:
button = browser.find_by_xpath('//input[@type="submit"]').click()
(6) Matching results
Use is_text_present to see matching results:
if browser.is_text_present('Spring Festival'): print("Found") else: print("Not found")
(7) Close the browser
After finishing the test, we need to close the browser using browser.quit:
browser**.**quit()
The complete code is as follows:
# -*- coding: utf-8 -*- #Import the Browser class from splinter.browser import Browser #Create an instance and specify the driver as the chrome browser. If you do not specify a driver for the Browser, firefox will be used by default. browser = Browser(driver_name='chrome',executable_path='/Users/xxx/Downloads/chromedriver')
browser.visit('http://baidu.com')
browser.fill('wd', '2018 New Year's greetings')
button = browser.find_by_xpath('//input[@type="submit"]').click()if browser.is_text_present('春节'):
print("Found") else:
print("Not found")
browser.quit()
3. 12306 automatic ticket checking
1. Process analysis
(1) After executing the python script, the browser can be automatically opened to enter the 12306 login page. So you need to load the browser driver and open the login page.
(2) The command line prompts the user to enter the user name and password, and waits for the user to manually select the verification code in the browser to complete the login.
(3) The command line prompts the user to input the origin, destination and departure time.
(4) Query train information according to the input
2. Sample code
The code has detailed comments. According to the above process analysis, we simplify it into three steps.
The first step is to load the basic information, including browser, url, etc. The second step is to enter your personal information to log in. The third step is to enter the query criteria to query train information.
Complete project github address: https://github.com/longup/TicketsUtil
class TicketsUtil(object): def __init__(self): self.loadBasicInfo() def loadBasicInfo(self): # login url self.loginUrl = 'https://kyfw.12306.cn/otn/login/init' #url after successful login self.myUrl = 'https://kyfw.12306.cn/otn/index/initMy12306' #Remaining ticket query page self.ticketUrl = 'https://kyfw.12306.cn/otn/leftTicket/init' # Initialize the driver self.driver=Browser(driver_name='chrome',executable_path='/Users/xxx/Downloads/chromedriver') # Initialize browser window size self.driver.driver.set_window_size(1400, 1000) def login(self): print("Start login...") # Log in self.driver.visit(self.loginUrl) self.username = input("\nPlease enter the username and press Enter...") #legality judgment while True: if self.username == '': self.username = input("\nPlease enter the username and press Enter...") else: break self.password = input("\nPlease enter the password, enter and press Enter...") #legality judgment while True: if self.password == '': self.password = input("\nPlease enter the password, enter and press Enter...") else: break # Autofill username self.driver.fill("loginUserDTO.user_name", self.username) # autofill password self.driver.fill("userDTO.password", self.password) print(u"Wait for the verification code, enter it by yourself...") # The verification code needs to be entered by yourself, the program spins and waits until the verification code is passed, click to log in while True: if self.driver.url != self.myUrl: sleep(1) else: break print(u"Login successful...") def query(self): self.source = input("\nPlease enter the starting point (format: Beijing, BJP), enter and press Enter...") #legality judgment while True: if self.source == '': self.source = input("\nPlease enter the starting point (format: Beijing, BJP), enter and press Enter...") else: break self.destination = input("\nPlease enter the destination (format: Shenzhen, SZQ), enter and press Enter...") while True: if self.destination == '': self.destination = input("\nPlease enter the destination (format: Shenzhen, SZQ), enter and press Enter...") else: break self.date = input("\nPlease enter the departure date (format: 2018-02-14), enter and press Enter...") while True: if self.date == '': self.date = input("\nPlease enter the departure date, enter and press Enter...") else: break #Convert the input origin into "Wuhan, WHN", and then encode it self.source = self.source.encode('unicode_escape').decode("utf-8").replace("\\u", "%u").replace(",", "%2c") #Convert the input destination self.destination = self.destination.encode('unicode_escape').decode("utf-8").replace("\\u", "%u").replace(",", "%2c") # load starting point self.driver.cookies.add({"_jc_save_fromStation": self.source}) # load destination self.driver.cookies.add({"_jc_save_toStation": self.destination}) # Load departure date self.driver.cookies.add({"_jc_save_fromDate": self.date}) # With query conditions, reload the page self.driver.reload() # Query remaining votes self.driver.find_by_text(u"查询").click() sleep(0.1) # Query remaining votes self.driver.find_by_text(u"查询").click() print('The query succeeded') """Entry function""" def start(self): self.loadBasicInfo() # Log in, automatically fill in the username and password, spin and wait for the verification code, enter the verification code, click login, and visit the tick_url (remaining ticket query page) self.login() # Log in successfully, visit the remaining ticket query page self.driver.visit(self.ticketUrl) self.query() if __name__ == '__main__': print(u"============Automatic ticket checking is turned on===========") ticketsUtil = TicketsUtil() ticketsUtil.start()