python编程实现12306的一个小爬虫实例

作者:sentimental_dog 时间:2021-09-23 10:58:14 

本文思路主要来源于实验楼的教程,但是一些具体的一些细节是我自己发现的,比如哪里获得站点对应的3位英文编号,怎么获得这个查询的url

本文用到的库主要有requests(获取url的内容),prettytable(让文本输出美观),argparse(命令行参数解析)

关于这些库怎么使用,可以参见我之前的博文

1、首先打开12306余票查询的界面

https://kyfw.12306.cn/otn/lcxxcx/init

我们想要的信息当然就是在输入了始发站、终点站和日期之后各车次的时间和车票余量,那么我们尝试在始发站使用检查元素,观察一下它是怎么上传始发站的信息的,那么我们不妨随便输入出发地、目的地和信息,使用抓包工具来看看它是怎么发包的(使用浏览器也可以,因为我们只需要查看包的内容,不需要更改包)

2、

python编程实现12306的一个小爬虫实例

在chrome的network中我们可以查看到我们点击之后浏览器发送的所有包(关于http包的知识不熟悉的同学,可以看看《图解http》这本书)

python编程实现12306的一个小爬虫实例

点击查询之后我们马上就会注意到以query开头的这个包,显然这就是一个查询指令,我们看看这个包的url

'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2016-10-04&from_station=BJP&to_station=XKS'

然后我们看看它的response

python编程实现12306的一个小爬虫实例

仔细观察就能发现它其实是一串json格式的字符串(要非常有经验。。。。)

3、经过以上这些过程,我们大致就能知道我们需要做的是什么了,我们只需要更改url中的data,fromstaion,tostaion后面的内容,然后用requests获得response,然后解析这一串json字符就行了。

但是我们会发现,日期还好说,对于fromstation和tostaion的代码,我们该怎么办呢?

4、有两种可能,一中可能是这些文件在服务器上,每回改变站点网页都会从服务器请求这个站点的代码,还有一种可能是这个已经下载到本地了,如何判断呢?我们不妨改变一下始发站,然后用抓包软件(或者浏览器)观察我们的浏览器是否向12306发送了包

python编程实现12306的一个小爬虫实例

把北京改成了上海,但是我们发现浏览器并没有发送包

这样我们基本可以肯定这个车站编号信息是存在本地了(已经从服务器下载下来)

5、我们这时候,就需要分析html来发现这个编号信息到底储存在了那里

我们试着检查一下出发地附近的html标签,在‘热门'上面点击检查,我们很容易发现这个标签上面带了一个onclick方法

python编程实现12306的一个小爬虫实例

我们发现这个onclick方法指向了一个js文件,并且名字是‘Stationfor12306',基本我们可以确定这个js文件就是我们需要的站点信息文件了。

6、我们尝试在这个html(12306余票查询界面)里面搜一下stationfor,我们马上就能发现,它就在<head>标签的<script>元素里,并且指向了一个url

python编程实现12306的一个小爬虫实例

进入这个url看看,我们马上就发现站点信息已经被我们找到啦(注意这是一个相对URL,绝对url需要在前面补上https://kyfw.12306.cn/)

python编程实现12306的一个小爬虫实例

关于怎么获取三位数的车站代码,用正则,字符串查询都是可以的啦,由于这里是固定的3位车站代码,我就用简单的字符串查询来提取这个代码了。

7、剩下的工作,基本就是代码实现了,关于具体怎么实现,我把我的代码贴在下面了。


#coding=utf-8
import requests
import argparse
import datetime
import re
from prettytable import PrettyTable
now = datetime.datetime.now()

tomorrow = now+datetime.timedelta(days=1)  
tomorrow = tomorrow.strftime('%Y-%m-%d')
print tomorrow

argument = argparse.ArgumentParser()
argument.add_argument('--fromcity','-f',default='hangzhoudong')
argument.add_argument('--tocity','-t',default='xiamen')
argument.add_argument('--date','-d',default=tomorrow)
# argument.add_argument('-d',action='store_true')
args =argument.parse_args()

from_station = args.fromcity
to_station = args.tocity
Date = args.date

stationlist_url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js'
r = requests.get(stationlist_url, verify=False)
stationlist = r.content

ToStation = ''
FromStation = ''

placea = stationlist.find(from_station)
placeb = stationlist.find(to_station)

for i in range(-4,-1):
 FromStation += stationlist[placea+i]
for i in range(-4,-1):
 ToStation += stationlist[placeb+i]

query_url='https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate='+Date+'&from_station='+FromStation+'&to_station='+ToStation
r = requests.get(query_url,verify=False)

with open('json.txt','w') as fp:
  fp.write(str(r.json()))

if 'datas' in r.json()["data"]:
 rj = r.json()["data"]["datas"]
 pt = PrettyTable()

header = '车次 车站 到站时间 时长 一等座 二等座 软卧 硬卧 硬座 无座'.split()
 pt._set_field_names(header)

for x in rj:
   ptrow = []
   ptrow.append(x["station_train_code"])
   ptrow.append('\n'.join([x["from_station_name"],x["to_station_name"]]))
   ptrow.append('\n'.join([x["start_time"], x["arrive_time"]]))
   ptrow.append(x["lishi"].replace(':','h')+'m')
   ptrow.append(x['zy_num'])
   ptrow.append(x['ze_num'])
   ptrow.append(x['rw_num'])
   ptrow.append(x['yw_num'])
   ptrow.append(x['yz_num'])
   ptrow.append(x['wz_num'])
   pt.add_row(ptrow)
 print pt
else :
 print '这两个站点没有直达列车'

来源:http://blog.csdn.net/sentimental_dog/article/details/52673935

标签:python,爬虫,12306
0
投稿

猜你喜欢

  • Python requests的SSL证书验证方式

    2021-10-06 09:21:51
  • Go语言调用Shell与可执行文件的实现

    2024-02-06 17:03:44
  • 跟老齐学Python之for循环语句

    2021-12-22 04:52:50
  • 在Python的Django框架中实现Hacker News的一些功能

    2023-11-24 19:27:46
  • Bootstrap每天必学之响应式导航、轮播图

    2023-08-15 03:29:45
  • Go语言中int、float、string类型之间相互的转换

    2024-02-03 04:32:55
  • python 中 .py文件 转 .pyd文件的操作

    2022-02-17 09:59:38
  • Python Pandas高级教程之时间处理

    2021-08-12 14:04:49
  • golang 输出重定向:fmt Log,子进程Log,第三方库logrus的详解

    2024-04-27 15:40:14
  • 举例讲解Python程序与系统shell交互的方式

    2021-10-29 14:43:17
  • CSS文字排版终极指南

    2010-01-19 10:30:00
  • 在oracle 数据库中查看一个sql语句的执行时间和SP2-0027错误

    2009-10-09 13:04:00
  • Python中的赋值、浅拷贝、深拷贝介绍

    2023-09-29 06:01:54
  • 详解Python中的数据清洗工具flashtext

    2021-10-05 01:59:47
  • Python 二分查找之bisect库的使用详解

    2023-10-03 01:24:29
  • Django分页功能的实现代码详解

    2022-09-27 01:12:08
  • python 实现logging动态变更输出日志文件名

    2023-10-26 06:40:27
  • Python接口自动化之浅析requests模块post请求

    2022-12-10 21:10:05
  • Django {{ MEDIA_URL }}无法显示图片的解决方式

    2023-06-20 07:42:22
  • Git的撤销、修改和回退命令

    2022-12-05 14:10:12
  • asp之家 网络编程 m.aspxhome.com