scala爬取指定地点的所有列车班次
需求介绍:
爬取指定地点的所有全国相关的列车班次详情。将结果写进mysql。
步骤及所遇到的问题:
1.寻取全国站点静态信息 https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9002 一个静态的js文件
2.借助web工具,本人谷歌浏览器F12在12306相关页面找取所需要的接口
3.寻找规律,注意去重写进mysql
直接上代码,看注释:
object TrainSchedulesMain {
def main(args: Array[String]): Unit = {
// val dateStr = "2019-01-07"
if (args == null || args.length < 2) {
System.err.println("args is null or missing")
System.exit(1)
}
val dateStrList = args(0).trim
val station = args(1).trim
assert(StringUtils.isNotBlank(dateStrList), "dateStrList is null or empty")
assert(StringUtils.isNotBlank(station), "station is null or empty")
// 打印参数
println(args.mkString(" "))
//获取全国所有的站点信息
val allStationsMap = analysisAllStations()
/*
* 1.深圳
* 2.深圳西
* 3.深圳东
* 4.深圳坪山
* 5.深圳北
* 6.福田
*/
// val fromStations = collection.mutable.ListBuffer("深圳", "深圳西", "深圳东", "深圳坪山", "深圳北", "福田")
var dateStr = "";
//出发站集合
val fromStations = collection.mutable.ListBuffer(station.trim)
dateStrList.split(",").foreach(date => {
dateStr = date
fromStations.foreach(r => {
var n = 0
//出发站
val fromStationRequest = allStationsMap.get(r).get
allStationsMap.foreach(d => {
val toStationRequest = d._2 //train code
//根据出发站和到达站请求12306
excuteAnaly(fromStationRequest, toStationRequest)
println(dateStr)
println("进度:" + r)
n += 1
println(n)
})
})
})
def excuteAnaly(fromStationRequest: String, toStationRequest: String) = {
val url1 =
s"""https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=${dateStr}&leftTicketDTO.from_station=${fromStationRequest}&leftTicketDTO.to_station=${toStationRequest}&purpose_codes=ADULT"""
.stripMargin
println("url1: " + url1)
//获取所查询的 出发站-》到达站 的所有班次列车信息
val responseStr = HttpRequest.sendGet(url1)
println("url1Res: " + responseStr)
if (StringUtils.isNotBlank(responseStr) && JSONUtil.isJson(responseStr)) {
val allStationModel = JSONUtil.toJavaBean(responseStr, new AllStationTimes().getClass)
//表示初始站为深圳 目的地为 toStationRequest 是有值
if (allStationModel != null && allStationModel.getHttpstatus == 200 && allStationModel.getData.getResult != null && allStationModel.getData.getResult.size() > 0) {
val resList = allStationModel.getData.getResult
for (item <- 0 until resList.size()) {
val str = resList.get(item)
val indexNumStart = str.indexOf("预订")
if (indexNumStart > -1) {
val arrs = str.substring(indexNumStart).split("\\|")
val trainNo = arrs(1)
val trainCode = arrs(2)
val startStation = arrs(3)
val endStation = arrs(4)
val fromStation = arrs(5)
val toStation = arrs(6)
// 并且目的地站必须是终点站才会当做一条 班次 写入msyql[否则是过站,导致重复写入mysql.并且站点还不全]
if (toStation.trim.equals(endStation.trim)) {
val url2 =s"""https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=${trainNo}&from_station_telecode=${fromStation}&to_station_telecode=${toStation}&depart_date=${dateStr}"""
println("url2: " + url2)
//查询上一步所有班次的详细各个站点顺序信息
val res = HttpRequest.sendGet(url2)
println("url2Res: " + res)
if (StringUtils.isNotBlank(res) && JSONUtil.isJson(res)) {
val trainSchedulesModel = JSONUtil.toJavaBean(res, new TrainSchedules().getClass)
if (trainSchedulesModel != null && trainSchedulesModel.getData.getData.size() > 0) {
val data0 = trainSchedulesModel.getData.getData.get(0)
if (!MysqlHandleUtil(MysqlConnect.trainDB).isHasValue(
s"""select *
|
|from train_schedules
|where train_code='${data0.getStation_train_code}'
|and start_station_name='${data0.getStart_station_name}'
|and end_station_name='${data0.getEnd_station_name}'
|and start_time='${data0.getStart_time}'
|and dates='$dateStr'
|"""
.stripMargin)) {
val sql =
s"""insert into
|train_schedules(`train_code`,`start_station_name`,`end_station_name`,`start_time`,`arrive_time`,`dates`,`data`)
|values('${data0.getStation_train_code}','${data0.getStart_station_name}','${data0.getEnd_station_name}','${data0.getStart_time}','${trainSchedulesModel.getData.getData.get(trainSchedulesModel.getData.getData.size() - 1).getArrive_time}','${dateStr}','${JSONUtil.toJsonString(trainSchedulesModel.getData.getData)}')"""
.stripMargin
MysqlHandleUtil(MysqlConnect.trainDB).insertData(sql)
}
}
}
}
}
}
}
}
}
}
/**
* 解析全国所有站点(中文名字,编码)
*
* @author XXXX
* @date 17:08
* @param []
* @return scala.collection.mutable.HashMap<java.lang.String,java.lang.String>
*/
def analysisAllStations(): collection.mutable.HashMap[String, String] = {
val hashMap = new mutable.HashMap[String, String]()
val url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9002"
val response = HttpRequest.sendGet(url)
assert(StringUtils.isNotBlank(response), "response is null or empty")
val arrs = response.split("@")
val len = arrs.length
for (item <- 1 until len) {
val ars = arrs(item).split("\\|")
hashMap.put(ars(1), ars(2))
}
hashMap
}
}
效果:

scala爬取指定地点的所有列车班次的更多相关文章
- Python3网络爬虫之requests动态爬虫:拉钩网
操作环境: Windows10.Python3.6.Pycharm.谷歌浏览器目标网址: https://www.lagou.com/jobs/list_Python/p-city_0?px=defa ...
- Scala进阶之路-I/O流操作之文件处理
Scala进阶之路-I/O流操作之文件处理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 说起Scala语言操作文件对象其实是很简单的,大部分代码和Java相同. 一.使用Scal ...
- requests抓取数据示例
1:获取豆瓣电影名称及评分 # 抓取豆瓣电影名称及评分 url="https://movie.douban.com/j/search_subjects" start=input(& ...
- 一个js爬虫
1. 第一个demo 2. configs详解——之成员 3. configs详解——之field 4. configs详解——之site, page和console 5. configs详解——之回 ...
- 爬虫--Scrapy框架课程介绍
Scrapy框架课程介绍: 框架的简介和基础使用 持久化存储 代理和cookie 日志等级和请求传参 CrawlSpider 基于redis的分布式爬虫 一scrapy框架的简介和基础使用 a) ...
- scrapy框架简介和基础使用
概念 为了爬取网站数据而编写的一款应用框架,出名,强大.所谓的框架其实就是一个集成了相应的功能且具有很强通用性的项目模板.(高性能的异步下载,解析,持久化……) 安装 linux mac os:pip ...
- 手把手教你使用Python生成图灵智能小伙伴,实现工作助手/闲聊功能
/1 前言/ 在家闲着,做个小项目,基于Python,实现一个语聊小机器人,分享给大家.项目整体比较简单,官方文档介绍的非常详细,可快速上手. /2 目标/ 将图灵机器人放到桌面,实现工作助手/陪聊功 ...
- 假如我来架构12306网站---文章来自csdn(Jackxin Xu IT技术专栏)
(一)概论 序言: 此文的撰写始于国庆期间,当中由于工作过于繁忙而不断终止撰写,最近在设计另一个电商平台时再次萌发了完善此文并且发布此文的想法,期望自己的绵薄之力能够给予各位同行一些火花,共同推进国 ...
- WKWebView实现网页静态资源优先从本地加载
前言:最近微信的小游戏跳一跳特别的火,顺便也让h5小游戏更加的火热.另外微信小程序,以及支付宝的小程序都是用H5写的.无论是小游戏还是小程序,这些都需要加载更多的资源文件,处理更多的业务.这些都对网页 ...
随机推荐
- IDEA创建maven项目时,maven太慢-archetypeCatalog=internal
创建项目时候加上archetypeCatalog=internal 参数, archetypeCatalog表示插件使用的archetype元数 据,不加这个参数时默认为remote,local,即中 ...
- SQL函数应用-DATEPART()
作用:DATEPART() 函数用于返回日期/时间的单独部分,比如年.月.日.小时.分钟等等. 语法格式:DATEPART(datepart,date) 参数说明: datepart 是指定应返回的日 ...
- 【Leetcode】【Easy】Isomorphic Strings
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...
- 一些实用的adb命令
一.前提: 1.打开手机调试模式,确保手机已正常连接电脑,可在电脑上通过adb devices命令查看,结果如下说明连接成功: List of devices attached90xxxxc9 dev ...
- Java学习---XML的读写操作
DOM4_Jwriter.java package com.ftl.xmlparse; import java.io.File; import java.io.FileNotFoundExceptio ...
- LNMP-day1-安装并配置
Nginx安装 #Nginx [root@localhost downloads]# pwd /root/downloads #安装依赖pcre [root@localhost downloads]# ...
- 中石油大学统考(大学英语B)押题笔记
二. 词汇与结构 1. I will.意为“我会的”,固定搭配. 2. get tired of 是词组“对…厌烦了”的意思. 3. — ________ is your girl friend li ...
- python异常处理及内置模块
异常处理 有时候我们在写程序的时候会出现错误或者异常,导致程序终止,如下这个例子: #!/usr/bin/env python a = 2/0 print(a) 结果提示如下错误: Traceback ...
- css3鼠标经过出现转圈菜单(仿)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- psql: FATAL: role “postgres” does not exist
I'm a postgres novice. I installed the postgres.app for mac. I was playing around with the psql comm ...