使用scrapy进行12306车票查询

概述

通过12306的查询API进行查询某日火车票, 结果保存在csv文件中.

详细

代码下载:http://www.demodashi.com/demo/12623.html

一、环境搭建

1. 安装配置python3.6

示例网站使用的是python 3.6.1

下载地址:https://www.python.org/downloads/release/python-361/

根据自己的系统选择相应的版本

2. 安装Twisted

Windows:

进入http://www.lfd.uci.edu/~gohlk...下载对应twisted

转到下载目录, 命令行执行:pip install Twisted-17.9.0-cp36-cp36m-win_amd64.whl

3. 安装Scrapy

mac或linux:

pip install Scrapy

windows:

pip install pywin32

pip install Scrapy

二、项目结构以及程序实现

上图是使用scrapy startproject spider12306 命令生成的基本模板, 之后使用scrapy genspider search 12307.cn 生成了一个基本爬虫,在此基础上进行自己需要的爬虫改写.

思路:

找到网页接口——进行查询后通过chrome找到查询地址是这样的:

通过这个地址可以看出,查询是通过向https://kyfw.12306.cn/otn/leftTicket发送GET请求来执行查询的。参数一共有4个:

leftTicketDTO.train_date: 日期

leftTicketDTO.from_station: 出发站

leftTicketDTO.to_station: 到达站

purpos_codes:车票类型 ADULT 成人票

现在有一个问题,出发站和到达站用的是缩写,查询返回的结果用的也是缩写,所以我们需要知道英文缩写对应的车站,之后我就找到了这个东西:

有一个名为:station_name 的js文件,其中就记录所有的中文站名以及其缩写。

通过正则等方法将其保存为两个json文件(本人用的是笨办法),键值对分别是:

站点名: 缩写 以及 缩写: 站点名 方便我们将来查询

之后就可以编写爬虫了

1. 根据顺序来我们先设置起始站点为查询站点缩写的js文件

class SearchSpider(scrapy.Spider):

    name = ‘search‘
    allowed_domains = [‘12306.cn‘]
    # 出发时间 日期如果小于今天  会报错的
    train_data = ‘2018-03-22‘
    # 出发站
    from_station = ‘郑州‘
    # 到
    to_station = ‘杭州‘

    start_urls = [‘https://kyfw.12306.cn/otn/resources/js‘
                  ‘/framework/station_name.js?station_version=1.9048‘]

2. 解析并保存结果为json文件

if not os.path.exists(‘stations.json‘):
    text = response.body.decode(‘utf-8‘)
    content = re.match(‘.+?(@.+)‘, text)
    if content:
        # 获取所有车站信息
        text = content.group(1)
        # 进行清洗后写入json文件
        l = text.split(‘|‘)
        a, b = 1, 2
        stations = {}
        search = {}
        while b < len(l):
            stations[l[a]] = l[b]
            search[l[b]] = l[a]
            a += 5
            b += 5
        stations = json.dumps(stations, ensure_ascii=False)
        with open(‘stations.json‘, ‘w‘, encoding=‘utf-8‘) as f:
            f.write(stations)
        search = json.dumps(search, ensure_ascii=False)
        with open(‘search.json‘, ‘w‘, encoding=‘utf-8‘) as f:
            f.write(search)
    else:
        (response.body.decode())

3. 根据需要查询的内容向查询地址发出get请求并接受查询结果

with open(‘stations.json‘, ‘rb‘) as f:
    station = json.load(f)
query_url = ‘https://kyfw.12306.cn/otn/leftTicket/queryZ?‘             ‘leftTicketDTO.train_date={}&‘             ‘leftTicketDTO.from_station={}&‘             ‘leftTicketDTO.to_station={}&‘             ‘purpose_codes=ADULT‘.format(
                self.train_data, station[self.from_station],
                station[self.to_station])
yield scrapy.Request(query_url, callback=self.query_parse)

4. 解析查询结果并保存为csv文件(可使用excel打开)

通过观察发现,返回的结果都是用‘|‘隔开的,貌似只能用下标来定位, 所以采用了下面的方法,如果有更好的方法请联系我,谢谢!

def query_parse(self, response):
    """解析查询结果"""
    text = response.body.decode(‘utf-8‘)
    message_fields = [‘车次‘, ‘始发站‘, ‘终点站‘, ‘出发站‘, ‘到达站‘, ‘出发时间‘, ‘到达时间‘,
                      ‘历时‘, ‘特等座‘, ‘一等座‘, ‘二等座‘, ‘软卧‘, ‘硬卧‘, ‘硬座‘, ‘无座‘]
    writer = csv.writer(open(‘ans.csv‘, ‘w‘))
    writer.writerow(message_fields)
    infos = json.loads(text)[‘data‘][‘result‘]
    with open(‘search.json‘, ‘rb‘) as f:
        search = json.load(f)
    for info in infos:
        info = info.split(‘|‘)[3:]
        if info[8] == ‘N‘:
            continue
        row = [info[0], search[info[1]], search[info[2]], search[info[3]],
               search[info[4]], info[5], info[6], info[7], info[29],
               info[28], info[27], info[20], info[25], info[26], info[23]]
        writer.writerow(row)
    pass

详细代码在例子包中, 仅供参考.....

运行

进入spider12306文件夹,在装有scrapy的虚拟环境或真实环境中运行

scrapy crawl search

即可, 然后可在运行目录找到 ans.csv 文件 打开后类似上图

代码下载:http://www.demodashi.com/demo/12623.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

原文地址:https://www.cnblogs.com/demodashi/p/9452868.html

时间: 2024-11-05 23:20:35

使用scrapy进行12306车票查询的相关文章

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

一.摘要 突发奇想想读取12306的车票信息,最开始想用requests,但是突然又想试试selenium的无界面浏览器.有部分正则没调好,写好就懒得调了. 套用我师傅的话就是:我凭本事写的bug,凭什么要改! 二.方案思路 url = https://kyfw.12306.cn/otn/leftTicket/init 1.模拟用户是怎么查车票信息.然后通过selenium去操作浏览器. 2.最后输出字典. 三.源码 #-*- coding:utf-8 -*- #__anthor__:"Klay

聚合数据iOS SDK 12306火车票查询订票演示示例

1,将聚合数据SDK(JuheApis.framework)添加到你的程序中来,SDK依赖的包包括: 2,在聚合SDK Framework的JHSDKAPIPath.h文件中找到快递查询接口宏,以及字典参数 /* 12306火车票查询订票 *//**@brief 2306火车票查询订票--1.车次查询@param lname string 必填 车次名称,如:G4@param ldtype string 非必填 返回数据的格式,xml或json,默认json*/#define kJHAPIS_L

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

今天写一下12306火车票查询的爬虫,新手一个,代码方面可能不是那么整洁,望海涵... 一. 这个火车票爬虫感觉还是有点难度的,一些小细节需要考虑. 二. 还是先讲一下思路:  获得火车票查询URL----->单击'单程'------->点击出发输入框,输入城市,选取站点------>目的地输入同上一步------>点击出发日期那个框,选取出发日期.------>点击"查询"按钮------>前面几步用selenuim实现------>创建几个

使用Python和Splinter实现12306火车票查询与抢票

有一段时间没有使用Python了,前几天经朋友提起一篇关于用Python实现抢火车票的文章,百度了实现抢火车票的技术细节,网上却有不少资料,也不是新鲜的东西.在了解了一些技术手段,阅读了一些大神的博文后,也尝试实现了一下,代码写得粗糙,纯当娱乐,本文在Windows系统下完成.需要提到的是,抢票过程中的验证码部分只能手动完成. 首先,我需要的工具和组件有: Chrome浏览器 浏览器驱动ChromeDriver Python 3.5 Web应用测试工具Splinter Chrome浏览器可自行下

12306火车票查询工具

使用Python实现的火车票查询工具: Usage: ticket.py [-gdtzk] <from> <to> <date> Options: -h,--help 帮助信息 -a 所有 -g 高铁 -d 动车 -t 特快 -z 直达 -k 快速 Demo: ticket.py shenzhen beijing 20161001 -g 1 #!/usr/bin/env python 2 #coding:utf-8 3 import urllib2,re,json 4

聚合数据Android SDK 12306火车票查询订票演示示例 编辑

1.聚合SDK是聚合数据平台,为移动开发者提供的免费数据接口.使用前请先到聚合平台(http://www.juhe.cn/)注册,申请相关数据. 2.下载聚合数据SDK,将开发包里的juhe_sdk_v_1_1.jar拷贝到libs根目录下,将libJuheSDK_v_1_0.so拷贝到libs\armeabi目录下,如图: 3. 根据接口说明文档找到以下方法: Java代码   /** * 获取车次 * * @param name *            车次 * @param jsonCa

12306账号安全查询

分享一个可查自己的12306个人信息及密码是否遭到泄露的小工具,另外无论12306个人信息和密码是否遭到泄露,都请尽快修改自己的密码!避免因多处使用相同帐号密码带来连带损失! 查询地址: http://www.phpthinking.com/12306/search_user.htm 声明:该漏洞非本人发现,非本人传播,我只是下载了网友提供的数据库,并且删掉隐私信息,只保留了邮箱到服务器上提供查询是否泄露的服务.

练习js——自动化实现12306火车票查询

# !/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2019/12/1 09:03 # @Author : "小多肉" # @Email : [email protected] # @File : task1127.py # @Software: PyCharm import time from datetime import datetime, timedelta from selenium import webdriv

阿里云确认向12306提供了技术协助,负责承接12306网站75%的余票查询流量

公开数据显示,今年春运火车票售卖的最高峰日出现在2014年12月19日.12306网站访问量(PV值)达到破纪录的297亿次,平均每秒PV超过30万次.当天共发售火车票956.4万张,其中互联网发售563.9万张,占比59%,均创历年春运新高.阿里云计算日前予以确认,确实向12306提供了技术协助,负责承接12306网站75%的余票查询流量.至于合作的具体细节,阿里云方面称将适时对外公布. 12306网站曾被认为是“全球最忙碌的网站”,在应对高并发访问处理方面备受网民诟病.经此一役,阿里云计算将