12306火车票查询爬虫(基于selenium)

Posted 嚯嚯嚯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了12306火车票查询爬虫(基于selenium)相关的知识,希望对你有一定的参考价值。

今天写一下12306火车票查询的爬虫,新手一个,代码方面可能不是那么整洁,望海涵。。。

一。

这个火车票爬虫感觉还是有点难度的,一些小细节需要考虑。

二。

还是先讲一下思路:  获得火车票查询URL----->单击‘单程’------->点击出发输入框,输入城市,选取站点------>目的地输入同上一步------>点击出发日期那个框,选取出发日期.------>点击“查询”按钮------>前面几步用selenuim实现------>创建几个列表,分别存储车次,出发站点,到达站点,出发时间,到达时间,行程耗时。------>创建打印信息函数------>封装函数------>运行程序。。。。。。

三。

先插入所有代码在进行逐步讲解。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
import datetime
from selenium.webdriver import ActionChains
from selenium import webdriver

#形参为出发城市,目的地,月份,日。
def train_tickets(scity,ecity,month,day):
    #打开浏览器
    browser = webdriver.Chrome()
    url = ‘https://kyfw.12306.cn/otn/leftTicket/init‘
    browser.get(url)
    #设置隐形等待
    browser.implicitly_wait(15)
    #选择单程
    browser.find_element_by_xpath(‘//label[@for="dc"]‘).click()
    time.sleep(1)
    #定位出发城市和目的地城市的输入框
    start_city = browser.find_element_by_xpath(‘//input[@id="fromStationText"]‘)
    end_city = browser.find_element_by_xpath(‘//input[@id="toStationText"]‘)
    #点击并写入城市。
    ActionChains(browser).click(start_city).send_keys(scity).perform()
    try:
        list_0 = browser.find_elements_by_xpath(‘//div[@id="panel_cities"]//div/span[1]‘)
        for vb in list_0:
            if vb.text == scity:
                time.sleep(3)
                vb.click()
    except:
        pass
    time.sleep(3)

    ActionChains(browser).click(end_city).send_keys(ecity).perform()
    try:
        list_01 = browser.find_elements_by_xpath(‘//div[@id="panel_cities"]//div/span[1]‘)
        for vb2 in list_01:
            if vb2.text == ecity:
                time.sleep(3)
                vb2.click()
    except:
        pass
    time.sleep(3)
    #选定日期
    if month == ‘当月‘:
        browser.find_element_by_xpath(‘//input[@readonly="readonly"]‘).click()
        time.sleep(2)
        qa = browser.find_elements_by_xpath(‘//div[@class="cal-cm"][1]//div[@class="cell"]‘)[int(day)-1]
        ActionChains(browser).click(qa).perform()
        time.sleep(3)
    elif month == ‘下月‘:
        browser.find_element_by_xpath(‘//input[@readonly="readonly"]‘).click()
        time.sleep(2)
        qb = browser.find_elements_by_xpath(‘//div[@class="cal-cm"][2]//div[@class="cell"]‘)[int(day)-1]
        ActionChains(browser).click(qb).perform()
        time.sleep(2)
        #点击查询
    browser.find_element_by_xpath(‘//a[@id="query_ticket"]‘).click()
    time.sleep(3)
    #车次,出发站,到达站点,出发时间,到达时间,耗时。
    che_ci = []
    start_c = []
    end_c = []
    start_t = []
    end_t = []
    time_2 = []
    #获取列车车次,并写入列表。
    che_ci_list = browser.find_elements_by_xpath(‘//tbody[@id="queryLeftTable"]//tr[@style="display:none;"]‘)
    for w in che_ci_list:
        aa = w.get_attribute(‘datatran‘)
        che_ci.append(aa)
    #获取出发站点。
    start_c_list = browser.find_elements_by_xpath(‘//strong[@class="start-s"]‘)
    for w2 in start_c_list:
        start_c.append(w2.text)
    #获取目的地站点
    end_c_list = browser.find_elements_by_xpath(‘//strong[@class="end-s"]‘)
    for w3 in end_c_list:
        end_c.append(w3.text)
    #获取出发时间
    start_t_list = browser.find_elements_by_xpath(‘//strong[@class="start-t"]‘)
    for w4 in start_t_list:
        start_t.append(w4.text)
    #获取到达时间
    end_t_list = browser.find_elements_by_xpath(‘//strong[@class="color999"]‘)
    for w5 in end_t_list:
        end_t.append(w5.text)
    #获取耗时
    time_2_list = browser.find_elements_by_xpath(‘//div[@class="ls"]‘)
    for w6 in time_2_list:
        time_2.append(w6.text)
    #关闭浏览器。
    time.sleep(3)
    browser.quit()
    #返回值
    return che_ci,start_c,end_c,start_t,end_t,time_2

#qaz = train_tickets(scity=‘北京‘,ecity=‘上海‘,month=‘当月‘,day=‘28‘)
#print(qaz)
#创建一个打印所有信息的函数。
def print_info(tuple):
    for aaa,bbb,ccc,ddd,eee,fff in zip(tuple[0],tuple[1],tuple[2],tuple[3],tuple[4],tuple[5]):
        print(‘车次: %s  出发站点:%s  到达站点:%s  出发时间:%s  到达时间:%s  总耗时:%s  ‘ % (aaa,bbb,ccc,ddd,eee,fff))
    return True
#把函数封装。
def search_train_tickets():
    time_1 = datetime.datetime.now()
    scity = input(‘请输入你的出发城市站点或城市:‘)
    ecity = input(‘请输入你的目的地城市站点或城市:‘)
    month = input(‘请输入出发月份(余票只能查询即日起30天的票,输入‘当月’或‘下月’):‘)
    day = input(‘请输入你几号出发:‘)
    num_1 = train_tickets(scity=scity,ecity=ecity,month=month,day=day)
    print_info(num_1)
    time_2 = datetime.datetime.now()
    cha = (time_2 - time_1).seconds
    print(‘\n\n此次运行耗时%s秒。‘ % cha)

#运行程序
search_train_tickets()

四。

1.导入模块

import time
import datetime
from selenium.webdriver import ActionChains
from selenium import webdriver

2.打开浏览器,打开网页。

def train_tickets(scity,ecity,month,day):
    #打开浏览器
    browser = webdriver.Chrome()
    url = ‘https://kyfw.12306.cn/otn/leftTicket/init‘
    browser.get(url)
 
    #设置隐形等待
    browser.implicitly_wait(15)

3.选择行程按钮,并点击。

#选择单程
    browser.find_element_by_xpath(‘//label[@for="dc"]‘).click()
    time.sleep(1)

  这里之所以要设置一个等待,是因为我在测试的时候发现,如果操作过快,在最后点击搜索的时候,会卡在搜索状态,一直显示正在搜索。。。。。。

4.定位输入框,写入并选择站点。

#定位出发城市和目的地城市的输入框
    start_city = browser.find_element_by_xpath(//input[@id="fromStationText"])
    end_city = browser.find_element_by_xpath(//input[@id="toStationText"])
    #点击并写入城市。
    ActionChains(browser).click(start_city).send_keys(scity).perform()
    try:
        list_0 = browser.find_elements_by_xpath(//div[@id="panel_cities"]//div/span[1])
        for vb in list_0:
            if vb.text == scity:
                time.sleep(3)
                vb.click()
    except:
        pass
    time.sleep(3)

    ActionChains(browser).click(end_city).send_keys(ecity).perform()
    try:
        list_01 = browser.find_elements_by_xpath(//div[@id="panel_cities"]//div/span[1])
        for vb2 in list_01:
            if vb2.text == ecity:
                time.sleep(3)
                vb2.click()
    except:
        pass
    time.sleep(3)

    前两行是用的xpath定位元素。


ActionChains(browser).click(start_city).send_keys(scity).perform()
ActionChains(browser).click(end_city).send_keys(ecity).perform()
这两句是用来对输入框输入文本的语句。


异常包着的是用来选中与出发站点一致的链接,如:我想从北京北站出发,在输入后,会出现很多个站点,所以用次来选中想要出发的站点,并单击。
之所以弄异常处理,是因为我在测试的时候发现明明匹配单击都正确,但是执行后会显示错误,如果你看了本文章,知道出错在哪,希望您能告诉我,谢谢。当然,如果我明白错在哪后也会第一时间修改文章的。

5.选择日期
 1 #选定日期
 2     if month == 当月:
 3         browser.find_element_by_xpath(//input[@readonly="readonly"]).click()
 4         time.sleep(2)
 5         qa = browser.find_elements_by_xpath(//div[@class="cal-cm"][1]//div[@class="cell"])[int(day)-1]
 6         ActionChains(browser).click(qa).perform()
 7         time.sleep(3)
 8     elif month == 下月:
 9         browser.find_element_by_xpath(//input[@readonly="readonly"]).click()
10         time.sleep(2)
11         qb = browser.find_elements_by_xpath(//div[@class="cal-cm"][2]//div[@class="cell"])[int(day)-1]
12         ActionChains(browser).click(qb).perform()
13         time.sleep(2)
14         #点击查询

由于火车票只能查询当日起30天的火车票,所以询问‘’当月‘’与“下月”,通过审查元素可以看见,日期分为两块,每块代表的是一个月,所以匹配一个月的,然后将日期转化为索引,获取出发日的那个元素并点击它。

 

6。点击搜索

1 browser.find_element_by_xpath(//a[@id="query_ticket"]).click()
2     time.sleep(3)

 

7.创建需要存储信息的列表,匹配后返回列表。

 1 #车次,出发站,到达站点,出发时间,到达时间,耗时。
 2     che_ci = []
 3     start_c = []
 4     end_c = []
 5     start_t = []
 6     end_t = []
 7     time_2 = []
 8     #获取列车车次,并写入列表。
 9     che_ci_list = browser.find_elements_by_xpath(//tbody[@id="queryLeftTable"]//tr[@style="display:none;"])
10     for w in che_ci_list:
11         aa = w.get_attribute(datatran)
12         che_ci.append(aa)
13     #获取出发站点。
14     start_c_list = browser.find_elements_by_xpath(//strong[@class="start-s"])
15     for w2 in start_c_list:
16         start_c.append(w2.text)
17     #获取目的地站点
18     end_c_list = browser.find_elements_by_xpath(//strong[@class="end-s"])
19     for w3 in end_c_list:
20         end_c.append(w3.text)
21     #获取出发时间
22     start_t_list = browser.find_elements_by_xpath(//strong[@class="start-t"])
23     for w4 in start_t_list:
24         start_t.append(w4.text)
25     #获取到达时间
26     end_t_list = browser.find_elements_by_xpath(//strong[@class="color999"])
27     for w5 in end_t_list:
28         end_t.append(w5.text)
29     #获取耗时
30     time_2_list = browser.find_elements_by_xpath(//div[@class="ls"])
31     for w6 in time_2_list:
32         time_2.append(w6.text)
33     #关闭浏览器。
34     time.sleep(3)
35     browser.quit()
36     #返回值
37     return che_ci,start_c,end_c,start_t,end_t,time_2

代码中对每一步操作进行了解释,所以在这里就不赘述了。

 

8.创建是打印信息的函数

1 def print_info(tuple):
2     for aaa,bbb,ccc,ddd,eee,fff in zip(tuple[0],tuple[1],tuple[2],tuple[3],tuple[4],tuple[5]):
3         print(车次: %s  出发站点:%s  到达站点:%s  出发时间:%s  到达时间:%s  总耗时:%s   % (aaa,bbb,ccc,ddd,eee,fff))
4     return True

 

9.封装函数

 1 #把函数封装。
 2 def search_train_tickets():
 3     time_1 = datetime.datetime.now()
 4     scity = input(请输入你的出发城市:)
 5     ecity = input(请输入你的目的地城市:)
 6     month = input(请输入出发月份(余票只能查询即日起30天的票,输入‘当月’或‘下月’):)
 7     day = input(请输入你几号出发:)
 8     num_1 = train_tickets(scity=scity,ecity=ecity,month=month,day=day)
 9     print_info(num_1)
10     time_2 = datetime.datetime.now()
11     cha = (time_2 - time_1).seconds
12     print(\n\n此次运行耗时%s秒。 % cha)
time_1 = datetime.datetime.now()
time_2 = datetime.datetime.now()
这两句用来获取程序运行开始的时间和运行结束的时间。


10。运行程序
#运行程序
search_train_tickets()

  

好了,到此就结束了,感谢大家的阅读。

 

 

 

---------------by sniper-huohuo ---------------------

---------------   知耻而后勇     ----------------------

 

以上是关于12306火车票查询爬虫(基于selenium)的主要内容,如果未能解决你的问题,请参考以下文章

Python3爬虫12306爬虫

使用python+selenium对12306车票数据读取

网络爬虫之12306-验证码验证

Python:基于Python爬虫技术的抢票程序及其实现

12306抢票爬虫实战

仿12306查询火车票功能